<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>어제도그랬어</title>
    <link>https://osy0907.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Mon, 17 Aug 2026 00:53:08 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>길순이</managingEditor>
    <item>
      <title>ktlint (kotlin lint) 적용</title>
      <link>https://osy0907.tistory.com/120</link>
      <description>&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;/li&gt;
&lt;li&gt;때에 따라 커스텀하게 디벨롭 시켜나갈 수 있습니다.&lt;/li&gt;
&lt;li&gt;비지니스 로직 이외의 것들에 대한 표준화가 되면 &lt;b&gt;유지보수 및 장애대응의 퍼포먼스&lt;/b&gt;를 가져갈 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div data-node-type=&quot;mediaSingle&quot; data-layout=&quot;center&quot; data-width=&quot;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1249&quot; data-origin-height=&quot;515&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bMqYku/btrx7yJ6oVe/pIlxyfavHkYKgKZg0ZuQU0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bMqYku/btrx7yJ6oVe/pIlxyfavHkYKgKZg0ZuQU0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bMqYku/btrx7yJ6oVe/pIlxyfavHkYKgKZg0ZuQU0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbMqYku%2Fbtrx7yJ6oVe%2FpIlxyfavHkYKgKZg0ZuQU0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1249&quot; height=&quot;515&quot; data-origin-width=&quot;1249&quot; data-origin-height=&quot;515&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;.editorconfig 설정&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;.editorconfig&lt;/span&gt;&amp;nbsp;파일을 기반으로 스타일 검사를 진행합니다. 자세한 내용은&amp;nbsp;&lt;a href=&quot;https://editorconfig.org/&quot;&gt;EditorConfig&lt;/a&gt;에 설명되어 있습니다.&amp;nbsp;&lt;span&gt;.editorconfig&lt;/span&gt;&amp;nbsp;파일이 없는 경우 기본룰 Ktlint 버전에 따라서&amp;nbsp;&lt;a href=&quot;https://github.com/pinterest/ktlint#standard-rules&quot;&gt;Standard rules&lt;/a&gt;를 기본적으로 따르지만 버전이 변경이 되면 Standard rules로 변경이 될 수 있기 때문에 root 디렉터리에&amp;nbsp;&lt;span&gt;.editorconfig&lt;/span&gt;파일을 설정하는 것을 권장합니다.&lt;/p&gt;
&lt;div data-node-type=&quot;mediaSingle&quot; data-layout=&quot;center&quot; data-width=&quot;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1257&quot; data-origin-height=&quot;957&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nxYyk/btrx8MHRMKY/LAeVCnQL2vVIvzsQtXraoK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nxYyk/btrx8MHRMKY/LAeVCnQL2vVIvzsQtXraoK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nxYyk/btrx8MHRMKY/LAeVCnQL2vVIvzsQtXraoK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnxYyk%2Fbtrx8MHRMKY%2FLAeVCnQL2vVIvzsQtXraoK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1257&quot; height=&quot;957&quot; data-origin-width=&quot;1257&quot; data-origin-height=&quot;957&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;h1&gt;사용 방법&lt;/h1&gt;
&lt;div data-node-type=&quot;mediaSingle&quot; data-layout=&quot;center&quot; data-width=&quot;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;778&quot; data-origin-height=&quot;933&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/088L1/btrx6ZOIQEL/TJvP65QnYsYDpP1KkcOwf0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/088L1/btrx6ZOIQEL/TJvP65QnYsYDpP1KkcOwf0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/088L1/btrx6ZOIQEL/TJvP65QnYsYDpP1KkcOwf0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F088L1%2Fbtrx6ZOIQEL%2FTJvP65QnYsYDpP1KkcOwf0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;778&quot; height=&quot;933&quot; data-origin-width=&quot;778&quot; data-origin-height=&quot;933&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;아래의 formatting의 ktlint format 은 auto로 잡아 주지만 간헐적으로 소스파일을 삭제하기 때문에 조심히 사용하는 것을 권장드립니다.&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;697&quot; data-origin-height=&quot;917&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c9tHXc/btrx9BTEBLg/EBTG20RbSuPmwRD55JMc50/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c9tHXc/btrx9BTEBLg/EBTG20RbSuPmwRD55JMc50/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c9tHXc/btrx9BTEBLg/EBTG20RbSuPmwRD55JMc50/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc9tHXc%2Fbtrx9BTEBLg%2FEBTG20RbSuPmwRD55JMc50%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;697&quot; height=&quot;917&quot; data-origin-width=&quot;697&quot; data-origin-height=&quot;917&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;빌드 성공 시: &lt;/b&gt;&lt;/p&gt;
&lt;div data-node-type=&quot;mediaSingle&quot; data-layout=&quot;center&quot; data-width=&quot;100&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1252&quot; data-origin-height=&quot;337&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/o0Rum/btrx6Hgqm8A/KM4kVqIsKVyK5UXyvYaPgk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/o0Rum/btrx6Hgqm8A/KM4kVqIsKVyK5UXyvYaPgk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/o0Rum/btrx6Hgqm8A/KM4kVqIsKVyK5UXyvYaPgk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fo0Rum%2Fbtrx6Hgqm8A%2FKM4kVqIsKVyK5UXyvYaPgk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1252&quot; height=&quot;337&quot; data-origin-width=&quot;1252&quot; data-origin-height=&quot;337&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;빌드 실패 시:&lt;/b&gt; &lt;/p&gt;
&lt;div data-node-type=&quot;mediaSingle&quot; data-layout=&quot;center&quot; data-width=&quot;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1253&quot; data-origin-height=&quot;309&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FXdNC/btrx5A3bRaM/6cRNQCJTn7FGCkOgnPfNVk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FXdNC/btrx5A3bRaM/6cRNQCJTn7FGCkOgnPfNVk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FXdNC/btrx5A3bRaM/6cRNQCJTn7FGCkOgnPfNVk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFXdNC%2Fbtrx5A3bRaM%2F6cRNQCJTn7FGCkOgnPfNVk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1253&quot; height=&quot;309&quot; data-origin-width=&quot;1253&quot; data-origin-height=&quot;309&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;IntelliJ kotlin style guide 적용 방법&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;IntelliJ &amp;gt; Preferences(MacOS 기준&amp;nbsp;&lt;span&gt;Command + ,&lt;/span&gt;) &amp;gt; Editor &amp;gt; Code Style &amp;gt; kotlin 메뉴로 진입&lt;/li&gt;
&lt;li&gt;우측 상단의 (&lt;span&gt;Set from...&lt;/span&gt;) 클릭&lt;/li&gt;
&lt;li&gt;kotlin style guide 클릭&lt;/li&gt;
&lt;li&gt;그 다음 중간 상단 탭의&amp;nbsp;&lt;span&gt;Imports&lt;/span&gt;&amp;nbsp;클릭&lt;/li&gt;
&lt;li&gt;&lt;span&gt;Top-Level Symbols&lt;/span&gt;&amp;nbsp;클릭 -&amp;gt;&amp;nbsp;&lt;span&gt;Use single name import&lt;/span&gt;&amp;nbsp;클릭&lt;/li&gt;
&lt;li&gt;&lt;span&gt;Java Statics and Enum Members&lt;/span&gt;&amp;nbsp;-&amp;gt;&amp;nbsp;&lt;span&gt;Use single name import&lt;/span&gt;&amp;nbsp;클릭&lt;/li&gt;
&lt;li&gt;아래의&amp;nbsp;&lt;span&gt;Packages to Use Import with&lt;/span&gt;&amp;nbsp;에서&amp;nbsp;&lt;span&gt;import java.util.*&lt;/span&gt;&amp;nbsp;remove&lt;/li&gt;
&lt;li&gt;&lt;span&gt;apply&lt;/span&gt;&amp;nbsp;후&amp;nbsp;&lt;span&gt;ok&lt;/span&gt;&amp;nbsp;클릭&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;reference:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://editorconfig.org/&quot;&gt;https://editorconfig.org/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/JLLeitschuh/ktlint-gradle#intellij-idea-only-plugin&quot;&gt;https://github.com/JLLeitschuh/ktlint-gradle#intellij-idea-only-plugin&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Maven &amp;amp; Gradle</category>
      <author>길순이</author>
      <guid isPermaLink="true">https://osy0907.tistory.com/120</guid>
      <comments>https://osy0907.tistory.com/120#entry120comment</comments>
      <pubDate>Thu, 31 Mar 2022 22:45:20 +0900</pubDate>
    </item>
    <item>
      <title>datadog apm setup</title>
      <link>https://osy0907.tistory.com/119</link>
      <description>&lt;ol style=&quot;list-style-type: disc;&quot; data-pm-slice=&quot;0 0 []&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Amazon Linux Agent set&lt;/li&gt;
&lt;li&gt;apm agent set&lt;/li&gt;
&lt;li&gt;jvm args set&lt;/li&gt;
&lt;/ol&gt;
&lt;div data-node-type=&quot;mediaSingle&quot; data-layout=&quot;center&quot; data-width=&quot;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1247&quot; data-origin-height=&quot;710&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Hoxws/btrx4TaT6V2/vobsK5ZbM19UFVxT7Yp6fk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Hoxws/btrx4TaT6V2/vobsK5ZbM19UFVxT7Yp6fk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Hoxws/btrx4TaT6V2/vobsK5ZbM19UFVxT7Yp6fk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHoxws%2Fbtrx4TaT6V2%2FvobsK5ZbM19UFVxT7Yp6fk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1247&quot; height=&quot;710&quot; data-origin-width=&quot;1247&quot; data-origin-height=&quot;710&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;div data-node-type=&quot;mediaSingle&quot; data-layout=&quot;center&quot; data-width=&quot;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1248&quot; data-origin-height=&quot;693&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dM0Vio/btrx5AIXhkX/mfTxKQvraQqZpECOEXhkyK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dM0Vio/btrx5AIXhkX/mfTxKQvraQqZpECOEXhkyK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dM0Vio/btrx5AIXhkX/mfTxKQvraQqZpECOEXhkyK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdM0Vio%2Fbtrx5AIXhkX%2FmfTxKQvraQqZpECOEXhkyK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1248&quot; height=&quot;693&quot; data-origin-width=&quot;1248&quot; data-origin-height=&quot;693&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 현재는 Host-Based 이기 때문에 Host 내부에 data-dog agent를 설치해주셔야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 datadog apm docs에 가시면 친절히 설명되어있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 배포는 서비스 스크립트를 이용해서 shop-api-dogpre-prod.conf 을 읽어서 pid, log, java_opts 등을 설정하고 있습니다. 여기에 추가적으로 등록해주시면 됩니다.&lt;/p&gt;
&lt;div data-node-type=&quot;mediaSingle&quot; data-layout=&quot;center&quot; data-width=&quot;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1256&quot; data-origin-height=&quot;1316&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cKjAWY/btrx8MVp2rs/5kzAOUubDKVQFOlvKypF20/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cKjAWY/btrx8MVp2rs/5kzAOUubDKVQFOlvKypF20/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cKjAWY/btrx8MVp2rs/5kzAOUubDKVQFOlvKypF20/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcKjAWY%2Fbtrx8MVp2rs%2F5kzAOUubDKVQFOlvKypF20%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1256&quot; height=&quot;1316&quot; data-origin-width=&quot;1256&quot; data-origin-height=&quot;1316&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;div data-node-type=&quot;mediaSingle&quot; data-layout=&quot;center&quot; data-width=&quot;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1250&quot; data-origin-height=&quot;1315&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7Ag7Z/btrx7zvtKXF/KTDI9GEV4NED8TddUJuJrk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7Ag7Z/btrx7zvtKXF/KTDI9GEV4NED8TddUJuJrk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7Ag7Z/btrx7zvtKXF/KTDI9GEV4NED8TddUJuJrk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7Ag7Z%2Fbtrx7zvtKXF%2FKTDI9GEV4NED8TddUJuJrk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1250&quot; height=&quot;1315&quot; data-origin-width=&quot;1250&quot; data-origin-height=&quot;1315&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;h1&gt;매트릭 결과&lt;/h1&gt;
&lt;div data-node-type=&quot;mediaSingle&quot; data-layout=&quot;center&quot; data-width=&quot;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1257&quot; data-origin-height=&quot;1307&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eDsmbd/btrx6Jk6tJC/dKNJzmj0y9GWTDwgSqZMJ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eDsmbd/btrx6Jk6tJC/dKNJzmj0y9GWTDwgSqZMJ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eDsmbd/btrx6Jk6tJC/dKNJzmj0y9GWTDwgSqZMJ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeDsmbd%2Fbtrx6Jk6tJC%2FdKNJzmj0y9GWTDwgSqZMJ0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1257&quot; height=&quot;1307&quot; data-origin-width=&quot;1257&quot; data-origin-height=&quot;1307&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;div data-node-type=&quot;mediaSingle&quot; data-layout=&quot;center&quot; data-width=&quot;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1260&quot; data-origin-height=&quot;1304&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/x1Tsb/btrx6Jk6vMz/oHfTnBBMGDaPJzkCsygh41/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/x1Tsb/btrx6Jk6vMz/oHfTnBBMGDaPJzkCsygh41/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/x1Tsb/btrx6Jk6vMz/oHfTnBBMGDaPJzkCsygh41/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fx1Tsb%2Fbtrx6Jk6vMz%2FoHfTnBBMGDaPJzkCsygh41%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1260&quot; height=&quot;1304&quot; data-origin-width=&quot;1260&quot; data-origin-height=&quot;1304&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;div data-node-type=&quot;mediaSingle&quot; data-layout=&quot;center&quot; data-width=&quot;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1254&quot; data-origin-height=&quot;655&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bNu5WJ/btrx5zwreYq/HGhMHZW0kPRygL2v4KugZ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bNu5WJ/btrx5zwreYq/HGhMHZW0kPRygL2v4KugZ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bNu5WJ/btrx5zwreYq/HGhMHZW0kPRygL2v4KugZ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbNu5WJ%2Fbtrx5zwreYq%2FHGhMHZW0kPRygL2v4KugZ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1254&quot; height=&quot;655&quot; data-origin-width=&quot;1254&quot; data-origin-height=&quot;655&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;div data-node-type=&quot;mediaSingle&quot; data-layout=&quot;center&quot; data-width=&quot;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1263&quot; data-origin-height=&quot;649&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BWSwq/btrx6YWAguO/f8pkU67LauKrQr7SJGPiz1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BWSwq/btrx6YWAguO/f8pkU67LauKrQr7SJGPiz1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BWSwq/btrx6YWAguO/f8pkU67LauKrQr7SJGPiz1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBWSwq%2Fbtrx6YWAguO%2Ff8pkU67LauKrQr7SJGPiz1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1263&quot; height=&quot;649&quot; data-origin-width=&quot;1263&quot; data-origin-height=&quot;649&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1250&quot; data-origin-height=&quot;656&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/VsCTu/btrx5AoA3HW/HMBqv7JtSpCkkk3rUkjTg1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/VsCTu/btrx5AoA3HW/HMBqv7JtSpCkkk3rUkjTg1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/VsCTu/btrx5AoA3HW/HMBqv7JtSpCkkk3rUkjTg1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FVsCTu%2Fbtrx5AoA3HW%2FHMBqv7JtSpCkkk3rUkjTg1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1250&quot; height=&quot;656&quot; data-origin-width=&quot;1250&quot; data-origin-height=&quot;656&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;1259&quot; data-origin-height=&quot;654&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/z0mbW/btrx6IfnfdI/R9sKwHB1DuBjiBTOKcbd91/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/z0mbW/btrx6IfnfdI/R9sKwHB1DuBjiBTOKcbd91/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/z0mbW/btrx6IfnfdI/R9sKwHB1DuBjiBTOKcbd91/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fz0mbW%2Fbtrx6IfnfdI%2FR9sKwHB1DuBjiBTOKcbd91%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1259&quot; height=&quot;654&quot; data-origin-width=&quot;1259&quot; data-origin-height=&quot;654&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;div data-node-type=&quot;mediaSingle&quot; data-layout=&quot;center&quot; data-width=&quot;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div data-node-type=&quot;mediaSingle&quot; data-layout=&quot;center&quot; data-width=&quot;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;h1&gt;매트릭 확인 목록&lt;/h1&gt;
&lt;div data-node-type=&quot;mediaSingle&quot; data-layout=&quot;center&quot; data-width=&quot;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1257&quot; data-origin-height=&quot;658&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bqezGA/btrx1xy6tkO/2TAZdtKMEjAuzqgRdHsFkK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bqezGA/btrx1xy6tkO/2TAZdtKMEjAuzqgRdHsFkK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bqezGA/btrx1xy6tkO/2TAZdtKMEjAuzqgRdHsFkK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbqezGA%2Fbtrx1xy6tkO%2F2TAZdtKMEjAuzqgRdHsFkK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1257&quot; height=&quot;658&quot; data-origin-width=&quot;1257&quot; data-origin-height=&quot;658&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;</description>
      <category>DevOps</category>
      <author>길순이</author>
      <guid isPermaLink="true">https://osy0907.tistory.com/119</guid>
      <comments>https://osy0907.tistory.com/119#entry119comment</comments>
      <pubDate>Thu, 31 Mar 2022 22:41:38 +0900</pubDate>
    </item>
    <item>
      <title>why datadog?</title>
      <link>https://osy0907.tistory.com/118</link>
      <description>&lt;h1 data-pm-slice=&quot;0 0 []&quot;&gt;DataDog은 어떻게 가장 큰 APM (성능 분석 솔루션) 회사가 되었나?&lt;/h1&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;datadog 장점&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;MSA 시대에 맞는 새로운 뷰&lt;/b&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;div data-node-type=&quot;mediaSingle&quot; data-layout=&quot;center&quot; data-width=&quot;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;828&quot; data-origin-height=&quot;479&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/upqU7/btrx4S37jd0/WUmzzyh6PEAkOy4QQSeU51/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/upqU7/btrx4S37jd0/WUmzzyh6PEAkOy4QQSeU51/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/upqU7/btrx4S37jd0/WUmzzyh6PEAkOy4QQSeU51/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FupqU7%2Fbtrx4S37jd0%2FWUmzzyh6PEAkOy4QQSeU51%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;828&quot; height=&quot;479&quot; data-origin-width=&quot;828&quot; data-origin-height=&quot;479&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;824&quot; data-origin-height=&quot;516&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rKtJr/btrx31fU0bv/ufMoLn9Wixn9dKkZz3L7i0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rKtJr/btrx31fU0bv/ufMoLn9Wixn9dKkZz3L7i0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rKtJr/btrx31fU0bv/ufMoLn9Wixn9dKkZz3L7i0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrKtJr%2Fbtrx31fU0bv%2FufMoLn9Wixn9dKkZz3L7i0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;824&quot; height=&quot;516&quot; data-origin-width=&quot;824&quot; data-origin-height=&quot;516&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;div data-node-type=&quot;mediaSingle&quot; data-layout=&quot;center&quot; data-width=&quot;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. &lt;b&gt;다양한 오픈소스 기술을 지원하는 에이전트, 커스텀마이징한 뷰&lt;/b&gt;&lt;/p&gt;
&lt;div data-node-type=&quot;mediaSingle&quot; data-layout=&quot;center&quot; data-width=&quot;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;844&quot; data-origin-height=&quot;866&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/OPhxU/btrx7yQSvK6/hlBtZYPT6kRdSRF88xxEz1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/OPhxU/btrx7yQSvK6/hlBtZYPT6kRdSRF88xxEz1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/OPhxU/btrx7yQSvK6/hlBtZYPT6kRdSRF88xxEz1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOPhxU%2Fbtrx7yQSvK6%2FhlBtZYPT6kRdSRF88xxEz1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;844&quot; height=&quot;866&quot; data-origin-width=&quot;844&quot; data-origin-height=&quot;866&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. 결정적 한 방 - 멀티 클라우드 환경도 한 곳에서.. / 빠른 기술 변화를 흡수..&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론 지금은 다른 업체들도 되지만, 멀티 클라우드 (AWS, Azure, GCP) 특화된 기능을 가장 빠르게 제공하고 이걸 통합해서 볼 수 있는 뷰를 누구보다 빠르게 제공했다. 또한 빠른 기술 스택의 변화를 따라가면서 Agent들을 쏟아내고 있다.&lt;/p&gt;</description>
      <category>DevOps</category>
      <author>길순이</author>
      <guid isPermaLink="true">https://osy0907.tistory.com/118</guid>
      <comments>https://osy0907.tistory.com/118#entry118comment</comments>
      <pubDate>Thu, 31 Mar 2022 22:37:03 +0900</pubDate>
    </item>
    <item>
      <title>infrastructure architecture</title>
      <link>https://osy0907.tistory.com/117</link>
      <description>&lt;h2 data-pm-slice=&quot;0 0 []&quot; data-ke-size=&quot;size26&quot;&gt;[ 2019 ~ 21.12.13(월) 기준 Funnc infrastructure architecture ]&lt;/h2&gt;
&lt;div data-node-type=&quot;mediaSingle&quot; data-layout=&quot;center&quot; data-width=&quot;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1257&quot; data-origin-height=&quot;705&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/byrtoM/btrx9Af7GBe/e31rjvxQTB5owtRjVoarRK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/byrtoM/btrx9Af7GBe/e31rjvxQTB5owtRjVoarRK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/byrtoM/btrx9Af7GBe/e31rjvxQTB5owtRjVoarRK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbyrtoM%2Fbtrx9Af7GBe%2Fe31rjvxQTB5owtRjVoarRK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1257&quot; height=&quot;705&quot; data-origin-width=&quot;1257&quot; data-origin-height=&quot;705&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&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;db 보안관련&lt;/li&gt;
&lt;li&gt;가용영역 관련&lt;/li&gt;
&lt;li&gt;오케스트레이션 사용하지 않고 있다는 점.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;[ 개선된 infrastructure architecture ]&lt;/h2&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1252&quot; data-origin-height=&quot;698&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/AL9d6/btrx6MaF1bA/krzwzyrgTteD2gJfEqKFQk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/AL9d6/btrx6MaF1bA/krzwzyrgTteD2gJfEqKFQk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/AL9d6/btrx6MaF1bA/krzwzyrgTteD2gJfEqKFQk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAL9d6%2Fbtrx6MaF1bA%2FkrzwzyrgTteD2gJfEqKFQk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1252&quot; height=&quot;698&quot; data-origin-width=&quot;1252&quot; data-origin-height=&quot;698&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;div data-node-type=&quot;mediaSingle&quot; data-layout=&quot;center&quot; data-width=&quot;&quot;&gt;&amp;nbsp;&lt;/div&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;# Reference&lt;/b&gt;&lt;/h3&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1242&quot; data-origin-height=&quot;696&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bIYUEm/btrx8T7XdFo/4P9ymfnF8hEDknd6UZpo01/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bIYUEm/btrx8T7XdFo/4P9ymfnF8hEDknd6UZpo01/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bIYUEm/btrx8T7XdFo/4P9ymfnF8hEDknd6UZpo01/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbIYUEm%2Fbtrx8T7XdFo%2F4P9ymfnF8hEDknd6UZpo01%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1242&quot; height=&quot;696&quot; data-origin-width=&quot;1242&quot; data-origin-height=&quot;696&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;1230&quot; data-origin-height=&quot;952&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/PKJ9t/btrx6rxTiil/a8gmdVWc3lEpgk4f681wJk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/PKJ9t/btrx6rxTiil/a8gmdVWc3lEpgk4f681wJk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/PKJ9t/btrx6rxTiil/a8gmdVWc3lEpgk4f681wJk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPKJ9t%2Fbtrx6rxTiil%2Fa8gmdVWc3lEpgk4f681wJk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1230&quot; height=&quot;952&quot; data-origin-width=&quot;1230&quot; data-origin-height=&quot;952&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;1227&quot; data-origin-height=&quot;898&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bcSI8N/btrx5uBywWL/5CDm0V7BAO4QdvHSWD430k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bcSI8N/btrx5uBywWL/5CDm0V7BAO4QdvHSWD430k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bcSI8N/btrx5uBywWL/5CDm0V7BAO4QdvHSWD430k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbcSI8N%2Fbtrx5uBywWL%2F5CDm0V7BAO4QdvHSWD430k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1227&quot; height=&quot;898&quot; data-origin-width=&quot;1227&quot; data-origin-height=&quot;898&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;1234&quot; data-origin-height=&quot;860&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DivtX/btrx6ZHXc2j/3D6tr3Oj9gKZBDp7JAMzVk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DivtX/btrx6ZHXc2j/3D6tr3Oj9gKZBDp7JAMzVk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DivtX/btrx6ZHXc2j/3D6tr3Oj9gKZBDp7JAMzVk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDivtX%2Fbtrx6ZHXc2j%2F3D6tr3Oj9gKZBDp7JAMzVk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1234&quot; height=&quot;860&quot; data-origin-width=&quot;1234&quot; data-origin-height=&quot;860&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;reference : &lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://devocean.sk.com/search/techBoardDetail.do?ID=163244&quot;&gt;https://devocean.sk.com/search/techBoardDetail.do?ID=163244&lt;/a&gt; &lt;br /&gt;&lt;a href=&quot;https://owin2828.github.io/devlog/2020/01/10/aws-2.html&quot;&gt;https://owin2828.github.io/devlog/2020/01/10/aws-2.html&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://tech.cloud.nongshim.co.kr/2018/10/16/4-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%EA%B5%AC%EC%84%B1%ED%95%98%EA%B8%B0vpc-subnet-route-table-internet-gateway/&quot;&gt;https://tech.cloud.nongshim.co.kr/2018/10/16/4-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%EA%B5%AC%EC%84%B1%ED%95%98%EA%B8%B0vpc-subnet-route-table-internet-gateway/&lt;/a&gt;&lt;/p&gt;
&lt;div data-node-type=&quot;mediaSingle&quot; data-layout=&quot;center&quot; data-width=&quot;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div data-node-type=&quot;mediaSingle&quot; data-layout=&quot;center&quot; data-width=&quot;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div data-node-type=&quot;mediaSingle&quot; data-layout=&quot;center&quot; data-width=&quot;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div data-node-type=&quot;mediaSingle&quot; data-layout=&quot;center&quot; data-width=&quot;&quot;&gt;&amp;nbsp;&lt;/div&gt;</description>
      <category>DevOps</category>
      <author>길순이</author>
      <guid isPermaLink="true">https://osy0907.tistory.com/117</guid>
      <comments>https://osy0907.tistory.com/117#entry117comment</comments>
      <pubDate>Thu, 31 Mar 2022 22:32:50 +0900</pubDate>
    </item>
    <item>
      <title>Deploying to Amazon Elastic Container Service</title>
      <link>https://osy0907.tistory.com/116</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;현 상황의 배포 시스템을 컨테이너 기반 배포시스템으로 빠르게 구축합니다. 추후 필요에 따라 k8s 기반으로 넘어갈 것이지만 현재 당면한 배포시스템의 문제로 인해 일단 빠르게 시스템을 구축하는 것을 목표로 합니다.&lt;/p&gt;
&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;오늘 오전 10:50 부터 약 3~40분 동안 강대 서비스 장애가 있었습니다. 장애 진행 상황, 원인 및 대응책을 말씀드리려고 합니다.&lt;b&gt;원인 및 대응책 요약:&lt;/b&gt;&lt;br /&gt;장애 원인은 요약하면 낙후된 배포 시스템과, 실수, 빠른 롤백이 불가한 배포 환경이라고 볼 수 있습니다. 다양한 프로젝트와 이슈 대응으로 배포 시스템 개선이 아직 이루어지지 못했는데 이번 스프린트에서 개발팀은 무조건 최신 기술을 활용한 배포 시스템을 도입하려고 합니다.&lt;b&gt;timeline:&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:40 경 강대 백엔드-1 서버 배포 완료: 문제가 있었지만 배포 시스템에 오류 표시 안됨&lt;/li&gt;
&lt;/ul&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;10:50 경 강대 백엔드-2 서버 배포 완료. 오류 메시지 없이 전체 서비스 장애 시작&lt;/li&gt;
&lt;/ul&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;11:00 원인 파악. 12/8 릴리즈를 위해 신규로 추가된 데이터베이스 테이블의 권한 설정에 문제가 있었음&lt;/li&gt;
&lt;/ul&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;11:30 경 수정 백엔드 배포 및 이슈 해결&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;장애 원인:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;우선적으로는 데이터베이스 테이블 권한 설정에 대한 실수&lt;/li&gt;
&lt;/ul&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;그럼에도 불구하고 동시 다발적으로 진행되는 많은 이슈로 인한 실수 가능성이 높은 상황인 것은 해결책을 생각할 때 고려 해야 함&lt;/li&gt;
&lt;/ul&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;배포 시스템에서 심각한 배포 문제에 대한 오류 메시지가 표시 되지 않는 것도 배포 중 사고 위험을 높이는 이유&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;action items:&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;빠르고 안전한 롤백을 가능하게하는 배포 시스템이 절실함. Docker를 사용하는 이미지 기반 배포 시스템이 있었으면 장애 시간을 10분 미만으로 할 수 있었음&lt;/li&gt;
&lt;/ul&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;프로덕션 배포를 하기 전에 stage 단계를 만들어서 백엔드 서버에 문제가 없는지 확인할 수 있는 배포 시스템 기능이 필요함&lt;/li&gt;
&lt;/ul&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;배포 중 서버 로그 및 메트릭을 손쉽게 확인할 수 있는 모니터링 시스템 추가 필요&lt;/li&gt;
&lt;/ul&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;메트릭은 좋은 상용 솔루션을 활용할 수 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;서버 로그는 내부 tool을 개선하여 개발자가 쉽게 배포 서버 로그를 확인할 수 있게 개선할 필요 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;실수를 줄이기 위해 사전 리뷰 및 테스트에 좀더 개발 시간을 사용할 필요가 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;그럼에도 불구하고 실수는 언제나 발생할 수 있기 때문에 그것을 확인 및 방지할 수 있는 다중의 안전책을 마련 해야함배포 시스템도 다양한 옵션이 있으나 가장 빠른 시간 안에 도입하여 배포 관련 안정성을 크게 높일 수 있는 방향으로 신속히 대응하도록 하겠습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;감사합니다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하나의 os에서 격리된 컨테이너 실행 환경을 제공합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;매번 실행환경을 셋팅 할 필요도 없다.&lt;br /&gt;간편하게 이미지라는 작업으로 가능하게 됩니다.&lt;/p&gt;
&lt;div data-node-type=&quot;mediaSingle&quot; data-layout=&quot;center&quot; data-width=&quot;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1262&quot; data-origin-height=&quot;627&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sgCIO/btrx2eTBOTY/jN1UkbCDnGFcrIcTJxbKo1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sgCIO/btrx2eTBOTY/jN1UkbCDnGFcrIcTJxbKo1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sgCIO/btrx2eTBOTY/jN1UkbCDnGFcrIcTJxbKo1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsgCIO%2Fbtrx2eTBOTY%2FjN1UkbCDnGFcrIcTJxbKo1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1262&quot; height=&quot;627&quot; data-origin-width=&quot;1262&quot; data-origin-height=&quot;627&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;ECS&lt;/b&gt;의&amp;nbsp;&lt;b&gt;클러스터&lt;/b&gt;는 도커 컨테이너를 실행할 수 있는 논리적인 공간이라고 볼 수 있는데요, 우리가 사용하는 도커 컨테이너는 도커가 설치된 컨테이너 인스턴스에서 컨테이너가 실행되며 이 인스턴스들을 목적에 따라 하나로 묶어주는 것이 바로&amp;nbsp;&lt;b&gt;클러스터&lt;/b&gt;라고 할 수 있습니다.&lt;/p&gt;
&lt;div data-node-type=&quot;mediaSingle&quot; data-layout=&quot;center&quot; data-width=&quot;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- 구현 된 아키텍처&lt;/b&gt;&lt;/p&gt;
&lt;div data-node-type=&quot;mediaSingle&quot; data-layout=&quot;center&quot; data-width=&quot;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1250&quot; data-origin-height=&quot;699&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bMvUlV/btrx3ZoRMdj/1PczNF96L9KSODtyhTgV3k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bMvUlV/btrx3ZoRMdj/1PczNF96L9KSODtyhTgV3k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bMvUlV/btrx3ZoRMdj/1PczNF96L9KSODtyhTgV3k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbMvUlV%2Fbtrx3ZoRMdj%2F1PczNF96L9KSODtyhTgV3k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1250&quot; height=&quot;699&quot; data-origin-width=&quot;1250&quot; data-origin-height=&quot;699&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>DevOps</category>
      <author>길순이</author>
      <guid isPermaLink="true">https://osy0907.tistory.com/116</guid>
      <comments>https://osy0907.tistory.com/116#entry116comment</comments>
      <pubDate>Thu, 31 Mar 2022 22:28:01 +0900</pubDate>
    </item>
    <item>
      <title>ElastiCache(Redis) 구축</title>
      <link>https://osy0907.tistory.com/115</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;ElastiCache for Redis를 구축할 때 고민해야 하는 것 중 하나가 &lt;b&gt;&lt;span data-text-custom-color=&quot;#ff5630&quot;&gt;클러스터&lt;/span&gt;&lt;/b&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;클러스터 모드 없이 Replication만 지원 (클러스터 모드 X )&lt;/li&gt;
&lt;li&gt;클러스터 모드와 Replication 모두 지원 (클러스터 모드 O)&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Redis는 Primary Node와 Replica Node로 구성하는게 일반적이며, 이런 구성을 shard로 여러 벌 준비하여 data parinioning을 수행하는 것이 클러스터 모드(clsuter mode)입니다.&lt;/p&gt;
&lt;div data-node-type=&quot;mediaSingle&quot; data-layout=&quot;center&quot; data-width=&quot;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;775&quot; data-origin-height=&quot;188&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HnhsQ/btrx0Lby5yI/3IdkBzi0hmKInkSRGGQhc1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HnhsQ/btrx0Lby5yI/3IdkBzi0hmKInkSRGGQhc1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HnhsQ/btrx0Lby5yI/3IdkBzi0hmKInkSRGGQhc1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHnhsQ%2Fbtrx0Lby5yI%2F3IdkBzi0hmKInkSRGGQhc1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;775&quot; height=&quot;188&quot; data-origin-width=&quot;775&quot; data-origin-height=&quot;188&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Redis의 쓰임새에 맞게 위 구성 중 하나를 선택해야 합니다. 선택의 기준은 최종 애플리케이션의 신뢰성, 사용성, 확장성에 기인합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ex)&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;주 노드(Primary Node) 문제 발생 &amp;rarr; Replica Nodes 사용 &amp;rarr; 복제 지연으로 인해 일부 데이터 손실 가능&lt;/li&gt;
&lt;li&gt;특정 가용 영역에 문제 발생 &amp;rarr; Multi-AZ 구성으로 타 가용 영역의 Replica Node 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각각의 특징은 다음과 같습니다.&lt;/p&gt;
&lt;div data-node-type=&quot;mediaSingle&quot; data-layout=&quot;center&quot; data-width=&quot;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;721&quot; data-origin-height=&quot;330&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xfoWl/btrxYc2hBei/B6jWGuKCWoo1PDGaMIbJ3k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xfoWl/btrxYc2hBei/B6jWGuKCWoo1PDGaMIbJ3k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xfoWl/btrxYc2hBei/B6jWGuKCWoo1PDGaMIbJ3k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxfoWl%2FbtrxYc2hBei%2FB6jWGuKCWoo1PDGaMIbJ3k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;721&quot; height=&quot;330&quot; data-origin-width=&quot;721&quot; data-origin-height=&quot;330&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;클러스터 모드는 언제 유용합니까?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일단 가용성이 중요한 상용 프로덕션 환경이라면 Replication은 필수적이라 할 수 있습니다. 다만 Replication은 수직 확장만 지원한다는 단점이 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클러스터 모드는 위 테이블에서 볼 수 있듯이 샤드를 이용한 수평 확장(scaling)이 가장 큰 특징입니다. 이를 이용해 최대 90개 샤드에서 100TB 용량의 큰 데이터 규모로 스케일 확장이 가능합니다. 이는 새로운 서비스의 워크 로드의 저장 용량 산정이 어려울 경우에 대한 대비도 가능합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;read 작업이 많을 때는 하나의 샤드 안에 read replica를 추가하는 방식(최대 5개)을 사용하고 write 작업이 많을 때엔 클러스터 모드를 통해 추가적인 write endpoints(추가적인 primart node)를 새로운 샤드를 통해 얻어오는 방식이 바람직합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;데이터 샤딩(Data Sharding)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Redis는 모든 캐시 키가 해시 슬롯(hash slot)에 매핑하는 방식으로 샤딩을 활용한다. 1개의 클러스터는 16,384개의 해시 슬롯을 사용할 수 있고 일반적으로 클러스터 내 총 샤드에 균등하게 배포한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 동일한 캐시키를 사용하는 데이터는 모든 Redis 노드에 read/write가 가능하다는 의미입니다. 워크 로드가 증가하면 가용성을 확보하고 성능 지연을 줄이기 위해 복수 노드에 워크 로드를 분산합니다. 이때에도 redis 클라이언트는 하나의 endpoint에 접속하며 redis 내부에서 로드를 분산하는 구조입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래는 캐시키 foo인 데이터를 찾는 알고리즘을 보여줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;e.g.) &lt;a href=&quot;https://en.wikipedia.org/wiki/Cyclic_redundancy_check&quot;&gt;CRC16&lt;/a&gt;(&amp;ldquo;foo&amp;rdquo;) mod 16384 = 12182 &amp;rarr; 3번째 샤드&lt;/p&gt;
&lt;div data-node-type=&quot;mediaSingle&quot; data-layout=&quot;center&quot; data-width=&quot;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;698&quot; data-origin-height=&quot;338&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JCqY2/btrx0EXP1JL/f13jbF07dRGbEtreRu9wSk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JCqY2/btrx0EXP1JL/f13jbF07dRGbEtreRu9wSk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JCqY2/btrx0EXP1JL/f13jbF07dRGbEtreRu9wSk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJCqY2%2Fbtrx0EXP1JL%2Ff13jbF07dRGbEtreRu9wSk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;698&quot; height=&quot;338&quot; data-origin-width=&quot;698&quot; data-origin-height=&quot;338&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;AWS 구축&lt;/h1&gt;
&lt;div data-node-type=&quot;mediaSingle&quot; data-layout=&quot;center&quot; data-width=&quot;100&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;771&quot; data-origin-height=&quot;447&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bH1p4C/btrxYcVycAg/4A9sDiiMd8s8yEgzQU6xAk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bH1p4C/btrxYcVycAg/4A9sDiiMd8s8yEgzQU6xAk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bH1p4C/btrxYcVycAg/4A9sDiiMd8s8yEgzQU6xAk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbH1p4C%2FbtrxYcVycAg%2F4A9sDiiMd8s8yEgzQU6xAk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;771&quot; height=&quot;447&quot; data-origin-width=&quot;771&quot; data-origin-height=&quot;447&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;search에서 elasticache를 선택합니다.&lt;/p&gt;
&lt;div data-node-type=&quot;mediaSingle&quot; data-layout=&quot;center&quot; data-width=&quot;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;764&quot; data-origin-height=&quot;408&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/djxx8G/btrxYcOLUSd/SxvNGrRt0h0mvmR89Yko1k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/djxx8G/btrxYcOLUSd/SxvNGrRt0h0mvmR89Yko1k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/djxx8G/btrxYcOLUSd/SxvNGrRt0h0mvmR89Yko1k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdjxx8G%2FbtrxYcOLUSd%2FSxvNGrRt0h0mvmR89Yko1k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;764&quot; height=&quot;408&quot; data-origin-width=&quot;764&quot; data-origin-height=&quot;408&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;redis tab에서 create를 눌러줍니다.&lt;/p&gt;
&lt;div data-node-type=&quot;mediaSingle&quot; data-layout=&quot;center&quot; data-width=&quot;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;741&quot; data-origin-height=&quot;421&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/PWL1d/btrxWB2zLaU/76WF7FMeOsEZjWAqy5P1o0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/PWL1d/btrxWB2zLaU/76WF7FMeOsEZjWAqy5P1o0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/PWL1d/btrxWB2zLaU/76WF7FMeOsEZjWAqy5P1o0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPWL1d%2FbtrxWB2zLaU%2F76WF7FMeOsEZjWAqy5P1o0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;741&quot; height=&quot;421&quot; data-origin-width=&quot;741&quot; data-origin-height=&quot;421&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;클러스터 모드를 활성화 해줍니다.&lt;/h4&gt;
&lt;div data-node-type=&quot;mediaSingle&quot; data-layout=&quot;center&quot; data-width=&quot;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;758&quot; data-origin-height=&quot;707&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wIjkz/btrxY5BPn94/tp0jQd6RTfkN5p2o6jBZC1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wIjkz/btrxY5BPn94/tp0jQd6RTfkN5p2o6jBZC1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wIjkz/btrxY5BPn94/tp0jQd6RTfkN5p2o6jBZC1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwIjkz%2FbtrxY5BPn94%2Ftp0jQd6RTfkN5p2o6jBZC1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/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;707&quot; data-origin-width=&quot;758&quot; data-origin-height=&quot;707&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반적인 노드유형을 선택했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 해당 유형으로1개의 샤드에 primary node1, replica node2를 배치했을 경우&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래와 같이 계산이 됩니다.&lt;/p&gt;
&lt;div data-node-type=&quot;mediaSingle&quot; data-layout=&quot;center&quot; data-width=&quot;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;753&quot; data-origin-height=&quot;749&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/brR2DZ/btrxYbWBHNi/t7vsyruE44sCIVbR7iLkS1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/brR2DZ/btrxYbWBHNi/t7vsyruE44sCIVbR7iLkS1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/brR2DZ/btrxYbWBHNi/t7vsyruE44sCIVbR7iLkS1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbrR2DZ%2FbtrxYbWBHNi%2Ft7vsyruE44sCIVbR7iLkS1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;753&quot; height=&quot;749&quot; data-origin-width=&quot;753&quot; data-origin-height=&quot;749&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고 가격정책: &lt;a href=&quot;https://aws.amazon.com/ko/elasticache/pricing/&quot;&gt;https://aws.amazon.com/ko/elasticache/pricing/&lt;/a&gt;&lt;/p&gt;
&lt;div data-node-type=&quot;mediaSingle&quot; data-layout=&quot;center&quot; data-width=&quot;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;675&quot; data-origin-height=&quot;312&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ewvVeO/btrxYaXHeYY/XoFAWvTbRvLTnWSVmvsJj0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ewvVeO/btrxYaXHeYY/XoFAWvTbRvLTnWSVmvsJj0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ewvVeO/btrxYaXHeYY/XoFAWvTbRvLTnWSVmvsJj0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FewvVeO%2FbtrxYaXHeYY%2FXoFAWvTbRvLTnWSVmvsJj0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;675&quot; height=&quot;312&quot; data-origin-width=&quot;675&quot; data-origin-height=&quot;312&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;고급 Redis 설정(log, 백업, maintenance)은 defalut로 설정해놓았습니다.이는 상황에 따라 설정 가능합니다.&lt;/h3&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;Bastion 서버를 통해 Redis 접속&lt;/h1&gt;
&lt;div data-panel-type=&quot;note&quot;&gt;
&lt;div data-panel-content=&quot;true&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 ElastiCache 보안그룹에서의 redis 6379 port와 ecs에서의 인바운드 규칙 작업을 선행해야 합니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Bastion 서버에 SSH를 통해서 접속&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;pem 파일의 경우 Bastion 인스턴스 생성 시 마지막 단계에서 생성한 Key Pair&lt;/li&gt;
&lt;li&gt;pem 파일이 있는 경로에서 아래 명령어를 실행&lt;/li&gt;
&lt;li&gt;주소의 경우 Bastion 서버의 퍼블릭 아이피 정보&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1175&quot; data-origin-height=&quot;453&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cziRN1/btrxYbI4e0J/VkUs5jCmvqZM1KomakMIAk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cziRN1/btrxYbI4e0J/VkUs5jCmvqZM1KomakMIAk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cziRN1/btrxYbI4e0J/VkUs5jCmvqZM1KomakMIAk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcziRN1%2FbtrxYbI4e0J%2FVkUs5jCmvqZM1KomakMIAk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1175&quot; height=&quot;453&quot; data-origin-width=&quot;1175&quot; data-origin-height=&quot;453&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;shpo-api-dev로 들어옵니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Bastion 서버에 접속 후 redis cli 설치&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;cs&quot;&gt;&lt;code&gt;# make를 위한 gcc 설치
[bation]$ sudo yum install -y gcc

# redis-cli 다운로드 &amp;amp; 설치
[bation]$ wget http://download.redis.io/redis-stable.tar.gz &amp;amp;&amp;amp; tar xvzf redis-stable.tar.gz &amp;amp;&amp;amp; cd redis-stable &amp;amp;&amp;amp; make

# 모든 위치에서 사용 가능하도록 /user/bin에 파일 복사
[bation]$ sudo cp src/redis-cli /usr/bin&lt;/code&gt;&lt;/pre&gt;
&lt;div data-node-type=&quot;mediaSingle&quot; data-layout=&quot;center&quot; data-width=&quot;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1073&quot; data-origin-height=&quot;1329&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/XDYPO/btrx0uOEU9G/V5zI96Le40se52EiHgtEVK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/XDYPO/btrx0uOEU9G/V5zI96Le40se52EiHgtEVK/img.png&quot; data-alt=&quot;redis-cli 관련 바이너리 파일들을 설치했습니다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/XDYPO/btrx0uOEU9G/V5zI96Le40se52EiHgtEVK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXDYPO%2Fbtrx0uOEU9G%2FV5zI96Le40se52EiHgtEVK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1073&quot; height=&quot;1329&quot; data-origin-width=&quot;1073&quot; data-origin-height=&quot;1329&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;redis-cli 관련 바이너리 파일들을 설치했습니다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Bastion 서버에서 redis-cli로 ElastiCache 접속&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;a href=&quot;http://funnc-catpre-redis.emyabw.clustercfg.apn2.cache.amazonaws.com&quot;&gt;&lt;b&gt;funnc-catpre-redis.xxxxxxxxxx.clustercfg.apn2.cache.amazonaws.com&lt;/b&gt;&lt;/a&gt;&lt;b&gt;:&lt;/b&gt;인 경우 아래와 같이 url과 port 번호 설정&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;stylus&quot;&gt;&lt;code&gt;redis-cli -h funnc-catpre-redis.xxxxxxxxxx.clustercfg.apn2.cache.amazonaws.com -p 6379&lt;/code&gt;&lt;/pre&gt;
&lt;div data-node-type=&quot;mediaSingle&quot; data-layout=&quot;center&quot; data-width=&quot;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1002&quot; data-origin-height=&quot;272&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KA4n2/btrxY4XfnHI/5xqOL56nkKk8XTDZE5yBk1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KA4n2/btrxY4XfnHI/5xqOL56nkKk8XTDZE5yBk1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KA4n2/btrxY4XfnHI/5xqOL56nkKk8XTDZE5yBk1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKA4n2%2FbtrxY4XfnHI%2F5xqOL56nkKk8XTDZE5yBk1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1002&quot; height=&quot;272&quot; data-origin-width=&quot;1002&quot; data-origin-height=&quot;272&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 cluster slots를 확인할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 캐쉬의 데이터 등을 확인하고 컨트롤 하려면 redis-cli 명령어를 통해 할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;redis 공식 docs를 이용하거나 redis-cli의 help 커멘드로 자세하게 확인할 수 있지만,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://freeblogger.tistory.com/10&quot;&gt;https://freeblogger.tistory.com/10&lt;/a&gt; 아래의 한국어로 정리되어 있는 글을 첨부해놓겠습니다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;Tuning&lt;/h1&gt;
&lt;div data-node-type=&quot;mediaSingle&quot; data-layout=&quot;center&quot; data-width=&quot;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1163&quot; data-origin-height=&quot;888&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ctGa2O/btrxYcOMtfp/XoiNmy2JRPfJHkWYnljMNK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ctGa2O/btrxYcOMtfp/XoiNmy2JRPfJHkWYnljMNK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ctGa2O/btrxYcOMtfp/XoiNmy2JRPfJHkWYnljMNK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FctGa2O%2FbtrxYcOMtfp%2FXoiNmy2JRPfJHkWYnljMNK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1163&quot; height=&quot;888&quot; data-origin-width=&quot;1163&quot; data-origin-height=&quot;888&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 tuning options 을 주어 master, replica&lt;/p&gt;
&lt;div data-panel-type=&quot;note&quot;&gt;
&lt;div data-panel-content=&quot;true&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;aws elasti-cache의 write to master, read from replica로 설정할 수 있습니다. aws elasti-cache의 cluster-mode의 또 하나의 특징은 각 샤드 내부의 노드들을 알고 있는 수퍼 구성 엔드포인트를 제공합니다. ( 다른 모드들은 node를 일일이 하나씩 주입을 시켜줘야 합니다. 물론 aws elasti-cache 관련 library를 사용하면 푸는 방법은 존재합니다. )&lt;/b&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;&lt;b&gt;Monitoring&lt;/b&gt;&lt;/h1&gt;
&lt;div data-node-type=&quot;mediaSingle&quot; data-layout=&quot;center&quot; data-width=&quot;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1179&quot; data-origin-height=&quot;648&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cuNBQV/btrxVeMTZBx/k86FkFEXkvcbg8YsbjekDk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cuNBQV/btrxVeMTZBx/k86FkFEXkvcbg8YsbjekDk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cuNBQV/btrxVeMTZBx/k86FkFEXkvcbg8YsbjekDk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcuNBQV%2FbtrxVeMTZBx%2Fk86FkFEXkvcbg8YsbjekDk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1179&quot; height=&quot;648&quot; data-origin-width=&quot;1179&quot; data-origin-height=&quot;648&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 cloudwatch를 이용할 수 있습니다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&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;a href=&quot;https://aws.amazon.com/ko/blogs/database/work-with-cluster-mode-on-amazon-elasticache-for-redis/&quot;&gt;https://aws.amazon.com/ko/blogs/database/work-with-cluster-mode-on-amazon-elasticache-for-redis/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://daddyprogrammer.org/post/1601/redis-cluster/&quot;&gt;https://daddyprogrammer.org/post/1601/redis-cluster/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Redis</category>
      <author>길순이</author>
      <guid isPermaLink="true">https://osy0907.tistory.com/115</guid>
      <comments>https://osy0907.tistory.com/115#entry115comment</comments>
      <pubDate>Wed, 30 Mar 2022 16:37:49 +0900</pubDate>
    </item>
    <item>
      <title>what is redis?</title>
      <link>https://osy0907.tistory.com/114</link>
      <description>&lt;h2 data-pm-slice=&quot;0 0 []&quot; data-ke-size=&quot;size26&quot;&gt;레디스란?&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Redis(Remote Dictionary Server)는 오픈 소스 인메모리 키-값 데이터 저장소로 주로 인메모리 데이터베이스, 캐시, 메시지 브로커, 큐로 사용됩니다. 오늘날 대부분의 최신 애플리케이션은 Redis를 캐시 서버로 사용합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;캐싱이 필요한 이유는 무엇입니까?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;캐싱은 불필요한 네트워크 호출, 데이터베이스 호출 및 하드 디스크에 대한 반복적인 읽기-쓰기 작업을 방지하여 응용 프로그램 성능을 향상시키는 데 주로 사용됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 애플리케이션이 국가 마스터, 언어 마스터, 애플리케이션 구성 등과 같은 일부 정적 데이터를 자주 사용하고 일부 파일이나 내부적으로 하드 디스크를 사용하는 데이터베이스에 저장되어 있다고 가정해 보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 이들은 가장 자주 사용되는 데이터이므로 응용 프로그램이 필요할 때마다 내부적으로 하나의 요청이 데이터베이스 또는 파일로 이동하여 밑줄이 있는 하드 디스크로 입출력 작업을 증가시키고 성능 문제를 일으킵니다.&lt;/p&gt;
&lt;div data-node-type=&quot;mediaSingle&quot; data-layout=&quot;center&quot; data-width=&quot;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;758&quot; data-origin-height=&quot;348&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bECCaB/btrxVG36KQB/PBKHqIkZKKBGlwLIr0x2mk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bECCaB/btrxVG36KQB/PBKHqIkZKKBGlwLIr0x2mk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bECCaB/btrxVG36KQB/PBKHqIkZKKBGlwLIr0x2mk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbECCaB%2FbtrxVG36KQB%2FPBKHqIkZKKBGlwLIr0x2mk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/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;348&quot; data-origin-width=&quot;758&quot; data-origin-height=&quot;348&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 성능을 향상시키기 위해 자주 사용하는 정적 데이터를 하드 디스크에서 인메모리(예: RAM)로 한 번 로드한 다음 후속 요청에 대해 디스크가 아닌 RAM에서 제공할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Redis의 인기 있는 사용 사례&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;데이터 캐싱&lt;/li&gt;
&lt;li&gt;세션 저장소&lt;/li&gt;
&lt;li&gt;Pub/Sub 메시징 시스템&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Who uses Redis?&lt;/h3&gt;
&lt;div data-node-type=&quot;mediaSingle&quot; data-layout=&quot;center&quot; data-width=&quot;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;722&quot; data-origin-height=&quot;557&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/btIcpD/btrx1HzKcjR/WF0hksFkRksLKncwVXrYCk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/btIcpD/btrx1HzKcjR/WF0hksFkRksLKncwVXrYCk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/btIcpD/btrx1HzKcjR/WF0hksFkRksLKncwVXrYCk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbtIcpD%2Fbtrx1HzKcjR%2FWF0hksFkRksLKncwVXrYCk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;722&quot; height=&quot;557&quot; data-origin-width=&quot;722&quot; data-origin-height=&quot;557&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;왜 Collection이 중요한가요?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;레디스는&amp;nbsp;&lt;b&gt;In-Memory 데이터베이스&lt;/b&gt;입니다. 즉, 모든 데이터를 메모리에 저장하고 조회합니다. 기존 관계형 데이터베이스(Oracle, MySQL) 보다 훨씬 빠른데 그 이유는 메모리 접근이 디스크 접근보다 빠르기 때문입니다. 하지만 빠르다는 것은 레디스의 여러 특징 중 일부분입니다. 다른 In-Memory 데이터베이스(ex. Memcached) 와의 가장 큰 차이점은&amp;nbsp;&lt;span&gt;다양한 자료구조&lt;/span&gt;&amp;nbsp;를 지원한다는 것입니다. 레디스는 아래처럼 다양한 자료구조를 Key-Value 형태로 저장합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;742&quot; data-origin-height=&quot;453&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/4iUpS/btrx0LCB4zi/BPdPZ4HdKTM2875NHOKqj0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/4iUpS/btrx0LCB4zi/BPdPZ4HdKTM2875NHOKqj0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/4iUpS/btrx0LCB4zi/BPdPZ4HdKTM2875NHOKqj0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F4iUpS%2Fbtrx0LCB4zi%2FBPdPZ4HdKTM2875NHOKqj0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/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;453&quot; data-origin-width=&quot;742&quot; data-origin-height=&quot;453&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;레디스는 기본적으로 String, Bitmap, Hash, List, Set, Sorted Set 를 제공했고, 버전이 올라가면서 현재는 Geospatial Index, Hyperloglog, Stream 등의 자료형도 지원하고 있습니다.&lt;/p&gt;
&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;바로&amp;nbsp;&lt;b&gt;개발의 편의성과 난이도&lt;/b&gt;&amp;nbsp;때문입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 실시간 랭킹 서버를 구현할 때 관계형 DBMS를 이용한다면 DB에 데이터를 저장하고, 저장된 SCORE 값으로 정렬하여 다시 읽어오는 과정이 필요할 것입니다. 개수가 많아지면 속도가 느려질 텐데요, 이 과정에서 디스크를 사용하기 때문입니다. In-memory 기반으로 서버에서 데이터를 처리하도록 직접 코드를 짤 수도 있겠지만.. 레디스의 Sorted-Set을 이용하는게 더 빠르고 간단한 방법일 것입니다.&lt;/p&gt;
&lt;div data-node-type=&quot;mediaSingle&quot; data-layout=&quot;center&quot; data-width=&quot;100&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;760&quot; data-origin-height=&quot;418&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/n9wfT/btrxUPGygcd/IufKm2EAxxsgaJFKMuugB0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/n9wfT/btrxUPGygcd/IufKm2EAxxsgaJFKMuugB0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/n9wfT/btrxUPGygcd/IufKm2EAxxsgaJFKMuugB0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fn9wfT%2FbtrxUPGygcd%2FIufKm2EAxxsgaJFKMuugB0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;760&quot; height=&quot;418&quot; data-origin-width=&quot;760&quot; data-origin-height=&quot;418&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;레디스는 트랜잭션의 문제도 해결해 줄 수 있습니다. 싱글 스레드로 동작하는 서버의 모든 자료구조는 atomic 하기 때문에, race condition을 피해 데이터의 정합성을 보장하기 쉽습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 외부의 Collections을 잘 이용하는 것만으로 개발 시간 단축이 가능하고, 생각하지 못한 여러가지 문제를 줄여줄 수 있으므로 개발자는 비즈니스 로직에 집중할 수 있다는 큰 장점이 존재합니다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;reference:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://redis.io/&quot;&gt;https://redis.io/&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://meetup.toast.com/posts/224&quot;&gt;https://meetup.toast.com/posts/224&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.steps2code.com/post/how-to-improve-api-performance-by-using-redis-cache&quot;&gt;https://www.steps2code.com/post/how-to-improve-api-performance-by-using-redis-cache&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Redis</category>
      <author>길순이</author>
      <guid isPermaLink="true">https://osy0907.tistory.com/114</guid>
      <comments>https://osy0907.tistory.com/114#entry114comment</comments>
      <pubDate>Wed, 30 Mar 2022 16:27:29 +0900</pubDate>
    </item>
    <item>
      <title>infinispan? redis ?</title>
      <link>https://osy0907.tistory.com/113</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;펀엔씨 프로젝트에서는 infinispan 이라는 로컬캐쉬를 클러스터 모드를 적용이 시켜 글로벌 캐쉬처럼 사용하여 적용되어 있는 상태입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 도커 컨테이너 환경에서의 사용이 되도록 알아보던 도중 관련된 캐쉬를 간략하게 알아보고 정리를 했습니다.&lt;/p&gt;
&lt;h1&gt;infinispan&lt;/h1&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://youtu.be/qA2MGwz8vD4&quot;&gt;https://youtu.be/qA2MGwz8vD4&lt;/a&gt;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;redis&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Redis는 선택적 내구성이 있는 분산형 인메모리 키-값 데이터베이스를 구현하는 오픈 소스 인메모리 데이터 구조 프로젝트입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Redis는 데이터베이스, 캐시 및 메시지 브로커로 사용되는 오픈 소스(BSD 라이선스), 인메모리 데이터 구조 저장소입니다.&amp;nbsp;문자열, 해시, 목록, 집합, 범위 쿼리가 있는 정렬된 집합, 비트맵, 하이퍼로그 로그, 반경 쿼리 및 스트림이 있는 지리 공간 인덱스와 같은 데이터 구조를 지원합니다.&amp;nbsp;Redis에는 복제, Lua 스크립팅, LRU 축출, 트랜잭션 및 다양한 수준의 디스크 지속성이 내장되어 있으며 Redis Sentinel 및 Redis 클러스터를 통한 자동 파티셔닝을 통해 고가용성을 제공합니다.&lt;br /&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=Wxd6sMUhgBg&quot;&gt;https://www.youtube.com/watch?v=Wxd6sMUhgBg&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;infinispan vs redis ?&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;redis는 memcached와 주로 비교되지만 현재 funnc 프로젝트에서는 infinispan을 적용 된 상태이기 때문에 비교 글을 서치해보았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://developers.redhat.com/devnation/tech-talks/redis-vs-infinispan&quot;&gt;https://developers.redhat.com/devnation/tech-talks/redis-vs-infinispan&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.saashub.com/compare-infinispan-vs-redis&quot;&gt;https://www.saashub.com/compare-infinispan-vs-redis&lt;/a&gt;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;reference: &lt;br /&gt;&lt;a href=&quot;https://infinispan.org/introduction/&quot;&gt;https://infinispan.org/introduction/&lt;/a&gt; &lt;br /&gt;&lt;a href=&quot;https://jsonobject.tistory.com/441&quot;&gt;https://jsonobject.tistory.com/441&lt;/a&gt;&lt;/p&gt;</description>
      <category>Redis</category>
      <author>길순이</author>
      <guid isPermaLink="true">https://osy0907.tistory.com/113</guid>
      <comments>https://osy0907.tistory.com/113#entry113comment</comments>
      <pubDate>Wed, 30 Mar 2022 16:23:47 +0900</pubDate>
    </item>
    <item>
      <title>DB트랜잭션의 격리 수준(isolation Level)</title>
      <link>https://osy0907.tistory.com/112</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;ACID란?&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span style=&quot;color: #000000;&quot;&gt;ACID(원자성, 일관성, 고립성, 지속성)는 데이터베이스 트랜잭션이 안전하게 수행된다는 것을 보장하기 위한 성질을 가리키는 약어&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;원자성(Atomicity)&lt;/b&gt;은 트랜잭션과 관련된 작업들이 부분적으로 실행되다가 중단되지 않는 것을 보장하는 능력이다. 예를 들어, 자금 이체는 성공할 수도 실패할 수도 있지만 보내는 쪽에서 돈을 빼 오는 작업만 성공하고 받는 쪽에 돈을 넣는 작업을 실패해서는 안된다. 원자성은 이와 같이 중간 단계까지 실행되고 실패하는 일이 없도록 하는 것이다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;일관성(Consistency)&lt;/b&gt;은 트랜잭션이 실행을 성공적으로 완료하면 언제나 일관성 있는 데이터베이스 상태로 유지하는 것을 의미한다. 무결성 제약이 모든 계좌는 잔고가 있어야 한다면 이를 위반하는 트랜잭션은 중단된다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;독립성(Isolation)&lt;/b&gt;은 트랜잭션을 수행 시 다른 트랜잭션의 연산 작업이 끼어들지 못하도록 보장하는 것을 의미한다. 이것은 트랜잭션 밖에 있는 어떤 연산도 중간 단계의 데이터를 볼 수 없음을 의미한다. 은행 관리자는 이체 작업을 하는 도중에 쿼리를 실행하더라도 특정 계좌간 이체하는 양 쪽을 볼 수 없다. 공식적으로 고립성은 트랜잭션 실행내역은 연속적이어야 함을 의미한다. 성능관련 이유로 인해 이 특성은 가장 유연성 있는 제약 조건이다. 자세한 내용은 관련 문서를 참조해야 한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;지속성(Durability)&lt;/b&gt;은 성공적으로 수행된 트랜잭션은 영원히 반영되어야 함을 의미한다. 시스템 문제, DB 일관성 체크 등을 하더라도 유지되어야 함을 의미한다. 전형적으로 모든 트랜잭션은 로그로 남고 시스템 장애 발생 전 상태로 되돌릴 수 있다. 트랜잭션은 로그에 모든 것이 저장된 후에만 commit 상태로 간주될 수 있다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;Transaction-Isolation-Level&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;Transaction Isolation Level&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span style=&quot;color: #000000;&quot;&gt;ACID의 원칙을 너무 타이트하기 지키면&amp;nbsp;동시성(Concurrency)에 대한 퍼포먼스가 너무 떨어지기 때문에&amp;nbsp;Isolation Level별로 차등을 두어 동시성에 대한 이점을 가질 수 있게 하지만 아무래도 문제가 발생할 가능성이 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이와 연관되어 데이터베이스에서 데이터를 읽은 다음 애플리케이션에서 처리 후 다시 쓰는 경우에 주의가 필요한데 왜 그런지 정리해봅니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;ANSI/ISO SQL Standard&lt;/b&gt;&amp;nbsp;에서 정의한&amp;nbsp;&lt;b&gt;Isolation Level&lt;/b&gt;은 다음과 같습니다.&lt;/span&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;READ UNCOMMITTED&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;READ COMMITTED&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;REPEATABLE READ&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;SERIALIZABLE&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;read-uncommitted&quot; style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;READ UNCOMMITTED&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;SELECT&amp;nbsp;쿼리 실행시에 다른 트랜잭션에서&amp;nbsp;COMMIT&amp;nbsp;되지 않은 데이터를 읽어올 수 있습니다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;COMMIT&amp;nbsp;되지 않은 데이터를 읽는 현상을&amp;nbsp;&lt;b&gt;Dirty read&lt;/b&gt;라고 말합니다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;INSERT만 진행되고&amp;nbsp;ROLLBACK&amp;nbsp;될 수도 있는, 즉 한번도&amp;nbsp;COMMIT&amp;nbsp;되지 않은 데이터를 읽을 수 있어 유의해야합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 id=&quot;read-committed&quot; style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;READ COMMITTED&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Read Committed에서는&amp;nbsp;COMMIT이 완료된 데이터만&amp;nbsp;SELECT시에 보이는 수준을 보장하는 Level이며 대부분의 DBMS에서&amp;nbsp;Read Committed를 기본으로 설정합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Read Committed에서는&amp;nbsp;Read Uncommitted에서 발생하는&amp;nbsp;&lt;b&gt;Dirty read&lt;/b&gt;가 발생하지 않도록 보장해줍니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;트랜잭션에서&amp;nbsp;COMMIT을 수행하지 않더라도 DB에 이미 값이 반영이 되어있는 상태인데&amp;nbsp;COMMIT이전의 데이터를 보장 받기 위해서는&amp;nbsp;COMMIT&amp;nbsp;되지 않은 쿼리를 복구하는 과정이 필요하게 됩니다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;즉, 이 시점에서는&amp;nbsp;&lt;b&gt;Consistent Read&lt;/b&gt;를 수행해야 함을 의미합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Read Committed의 문제는 하나의 트랜잭션 안에서&amp;nbsp;SELECT를 수행 할 때마다 데이터가 동일하다는 보장을 해주지 않습니다. 그 이유는 다른 트랜젝션에서 해당 데이터를&amp;nbsp;COMMIT&amp;nbsp;했을 경우에는&amp;nbsp;COMMIT된 데이터를 반환해주는게&amp;nbsp;Read Committed의 특징이기 때문입니다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;위와 같은 이유로&amp;nbsp;Read Committed를&amp;nbsp;Non-repeatable Read&amp;nbsp;라고도 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 id=&quot;repeatable-read&quot; style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;REPEATABLE READ&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Read Committed와는 다르게&amp;nbsp;Repeatable Read는 한 트랜잭션 안에서 반복해서&amp;nbsp;SELECT를 수행하더라도 읽어 들이는 값이 변화하지 않음을 보장합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Repeatable Read&amp;nbsp;트랜잭션은 처음으로&amp;nbsp;SELECT을 수행한 시간을 기록한 뒤 그 이후에는 모든&amp;nbsp;SELECT&amp;nbsp;마다 해당 시점을 기준으로&amp;nbsp;&lt;b&gt;Consistent Read&lt;/b&gt;를 수행하여줍니다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그러므로 트랜잭션 도중 다른 트랜잭션이&amp;nbsp;COMMIT&amp;nbsp;되더라도 새로이&amp;nbsp;COMMIT&amp;nbsp;된 데이터는 보이지 않게됩니다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그 이유는 첫&amp;nbsp;SELECT&amp;nbsp;시에 생성된&amp;nbsp;SNAPSHOT을 읽기 때문입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;해당하는 Row를 INSERT하는 것은 가능합니다. 따라서 동일 트랜잭션에서 Read되는 데이터 수가 달라질 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;h4 id=&quot;serializable&quot; style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;SERIALIZABLE&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Serializable은 모든 작업을 하나의 트랜젝션에서 처리하는 것과 같은 가장 높은 고립수준을 제공합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Read Committed,&amp;nbsp;Repeatable Read&amp;nbsp;두개의 공통적인 이슈는&amp;nbsp;Phantom Read가 발생한다는 점입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Transaction Isolation&amp;nbsp;Level 은 Read Uncommited 에서 Serializable&amp;nbsp; 순으로 Concurrency&amp;nbsp;는 높아지고 속도는 느려진다. 따라서 이 둘의 균형을 잘 맞추는 것이 중요합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #000000;&quot;&gt;위 네가지 Isolation Level &amp;nbsp;에 따라 나타나는 현상이 세가지가 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;Dirty Read&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;Repeatable Read&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;Phantom Read&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;Dirty Read&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;어떤 트랜잭션에서 아직 실행이 끝난지 않은 다른 트랜잭션에 의한 변경 사항을 보게 되는 되는 경우를 dirty read 라고 합니다. 만약 원래 트랜잭션에서 그 변경 사항을 롤백하면&amp;nbsp;그 데이터를 읽은 트랜잭션은 dirty 데이터를 가지고 있다고 말합니다.&lt;b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;Repeatable Read&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;어떤 트랜잭션에서 같은 질의를 사용했을 때 질의를 아무리 여러번 해도 그리고 다른 트랜잭션에서 아무리 여러 번 그 행을 변경해도 항상 같은 데이터만 읽어드리는 경우를 repeatable read 라고 합니다. 즉 repeatable read 가 요구되는 트랜잭션에서는 다른 트랜잭션에 의한 변경 사항을 볼 수가 없습니다. 그러한 변경 사항을 보고 싶으면 어플리케이션에서 트랜잭션을 새로 시작해야 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;Phantom Read&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;phantom read 는 다른 트랜잭션에 의한 변경 사항으로 인해 현재 사용 중인 트랜잭션의 WHERE 절의 조건에 맞는 새로운 행이 생길 수 있는 경우에 관한 것입니다. 예를 들어, 잔고가 $100&amp;nbsp;미만인 계좌를 모두 찾아내는 트랜잭션이&amp;nbsp;있고, 이 트랜잭션에서 그 데이터를 두 번 읽는다고 가정합시다. 처음 데이터를 읽어들이고&amp;nbsp;난 후에 다른 트랜잭션에서 잔고가 $0인 계좌를 새로 만들면 이 계좌도 잔고가 $100 이하라는 조건에 맞게 됩니다. 트랜잭션 격리 수준(Transaction Isolation Level)에서 phantom read 를 지원하면 새로운 &amp;ldquo;유령(phantom)&amp;rdquo;행이 나오지만 지원하지 않으면 새로 생긴 행을 볼 수 없습니다.&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;스크린샷 2021-04-07 오전 1.18.39.png&quot; data-origin-width=&quot;1456&quot; data-origin-height=&quot;384&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/UWrJS/btq1XMglZ6p/GiGy7a26t9YiOp3Mbh6no0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/UWrJS/btq1XMglZ6p/GiGy7a26t9YiOp3Mbh6no0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/UWrJS/btq1XMglZ6p/GiGy7a26t9YiOp3Mbh6no0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FUWrJS%2Fbtq1XMglZ6p%2FGiGy7a26t9YiOp3Mbh6no0%2Fimg.png&quot; data-filename=&quot;스크린샷 2021-04-07 오전 1.18.39.png&quot; data-origin-width=&quot;1456&quot; data-origin-height=&quot;384&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;h3 id=&quot;SERIALIZABLE이-아니면-UPDATE-DELETE에-주의하라&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;결론 : SERIALIZABLE이 아니면&amp;nbsp;UPDATE,&amp;nbsp;DELETE에 주의&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span style=&quot;color: #000000;&quot;&gt;참고 : &lt;a style=&quot;color: #000000;&quot; href=&quot;https://ko.wikipedia.org/wiki/ACID&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;ko.wikipedia.org/wiki/ACID&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;a style=&quot;color: #000000;&quot; href=&quot;https://velog.io/@lsb156/Transaction-Isolation-Level#%EC%9B%90%EC%9E%90%EC%84%B1--atomicity-&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;velog.io/@lsb156/Transaction-Isolation-Level#%EC%9B%90%EC%9E%90%EC%84%B1--atomicity-&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;a style=&quot;color: #000000;&quot; href=&quot;https://blog.sapzil.org/2017/04/01/do-not-trust-sql-transaction/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;blog.sapzil.org/2017/04/01/do-not-trust-sql-transaction/&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;a style=&quot;color: #000000;&quot; href=&quot;https://suhwan.dev/2019/06/09/transaction-isolation-level-and-lock/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;suhwan.dev/2019/06/09/transaction-isolation-level-and-lock/&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1617726010850&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Lock으로 이해하는 Transaction의 Isolation Level&quot; data-og-description=&quot;개요 내게 transaction의 isolation level은 개발할 때 항상 큰 찝찝함을 남기게 하는 요소였다. row를 읽기만 할 때는 REPEATABLE READ로, row를 삽입 / 수정 / 삭제할 때는 SERIALIZABLE로 isolation level을 지정했지&quot; data-og-host=&quot;suhwan.dev&quot; data-og-source-url=&quot;https://suhwan.dev/2019/06/09/transaction-isolation-level-and-lock/&quot; data-og-url=&quot;https://suhwan.dev/2019/06/09/transaction-isolation-level-and-lock/&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://suhwan.dev/2019/06/09/transaction-isolation-level-and-lock/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://suhwan.dev/2019/06/09/transaction-isolation-level-and-lock/&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;Lock으로 이해하는 Transaction의 Isolation Level&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;개요 내게 transaction의 isolation level은 개발할 때 항상 큰 찝찝함을 남기게 하는 요소였다. row를 읽기만 할 때는 REPEATABLE READ로, row를 삽입 / 수정 / 삭제할 때는 SERIALIZABLE로 isolation level을 지정했지&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;suhwan.dev&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;figure id=&quot;og_1617726007310&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;website&quot; data-og-title=&quot;SQL 트랜잭션 - 믿는 도끼에 발등 찍힌다&quot; data-og-description=&quot;RDBMS를 쓰는 이유 중 하나는 트랜잭션입니다. 하지만 RDBMS의 트랜잭션을 너무 믿다가는 깜짝 놀랄 일이 벌어질 수도 있습니다.&quot; data-og-host=&quot;blog.sapzil.org&quot; data-og-source-url=&quot;https://blog.sapzil.org/2017/04/01/do-not-trust-sql-transaction/&quot; data-og-url=&quot;https://blog.sapzil.org/2017/04/01/do-not-trust-sql-transaction/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/uI90f/hyJN8ewPz1/2sxXWTOf34skwIk6kHmo1K/img.jpg?width=530&amp;amp;height=430&amp;amp;face=221_72_300_159&quot;&gt;&lt;a href=&quot;https://blog.sapzil.org/2017/04/01/do-not-trust-sql-transaction/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://blog.sapzil.org/2017/04/01/do-not-trust-sql-transaction/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/uI90f/hyJN8ewPz1/2sxXWTOf34skwIk6kHmo1K/img.jpg?width=530&amp;amp;height=430&amp;amp;face=221_72_300_159');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;SQL 트랜잭션 - 믿는 도끼에 발등 찍힌다&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;RDBMS를 쓰는 이유 중 하나는 트랜잭션입니다. 하지만 RDBMS의 트랜잭션을 너무 믿다가는 깜짝 놀랄 일이 벌어질 수도 있습니다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;blog.sapzil.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;figure id=&quot;og_1617725987713&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Transaction Isolation Level 정리&quot; data-og-description=&quot;Isolation을 알기전에 먼저 트랜잭션이 중요시 여기는 ACID라는 것을 먼저 알아야 합니다.Atomicity, Consistency, Isolation, Durability의 앞글자를 따서 ACID라고 불리웁니다.하나의 트랜잭션이 작업이 그중에 &quot; data-og-host=&quot;velog.io&quot; data-og-source-url=&quot;https://velog.io/@lsb156/Transaction-Isolation-Level#%EC%9B%90%EC%9E%90%EC%84%B1--atomicity-&quot; data-og-url=&quot;https://velog.io/@lsb156/Transaction-Isolation-Level&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dUMxSs/hyJN8r3VZU/v8aDQYwdAHl4qwt4hQaakK/img.png?width=1380&amp;amp;height=762&amp;amp;face=0_0_1380_762,https://scrap.kakaocdn.net/dn/duQhu9/hyJNZhBv5t/SoQJVYncmmKeL1moDZOLBK/img.png?width=1380&amp;amp;height=762&amp;amp;face=0_0_1380_762,https://scrap.kakaocdn.net/dn/cI0qzD/hyJN4iVk5n/3HyQaeUz5AZCeBftpjz890/img.png?width=1380&amp;amp;height=762&amp;amp;face=0_0_1380_762&quot;&gt;&lt;a href=&quot;https://velog.io/@lsb156/Transaction-Isolation-Level#%EC%9B%90%EC%9E%90%EC%84%B1--atomicity-&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://velog.io/@lsb156/Transaction-Isolation-Level#%EC%9B%90%EC%9E%90%EC%84%B1--atomicity-&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dUMxSs/hyJN8r3VZU/v8aDQYwdAHl4qwt4hQaakK/img.png?width=1380&amp;amp;height=762&amp;amp;face=0_0_1380_762,https://scrap.kakaocdn.net/dn/duQhu9/hyJNZhBv5t/SoQJVYncmmKeL1moDZOLBK/img.png?width=1380&amp;amp;height=762&amp;amp;face=0_0_1380_762,https://scrap.kakaocdn.net/dn/cI0qzD/hyJN4iVk5n/3HyQaeUz5AZCeBftpjz890/img.png?width=1380&amp;amp;height=762&amp;amp;face=0_0_1380_762');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;Transaction Isolation Level 정리&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;Isolation을 알기전에 먼저 트랜잭션이 중요시 여기는 ACID라는 것을 먼저 알아야 합니다.Atomicity, Consistency, Isolation, Durability의 앞글자를 따서 ACID라고 불리웁니다.하나의 트랜잭션이 작업이 그중에&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;velog.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;figure id=&quot;og_1617725980349&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;website&quot; data-og-title=&quot;ACID - 위키백과, 우리 모두의 백과사전&quot; data-og-description=&quot;위키백과, 우리 모두의 백과사전. 다른 뜻에 대해서는 애시드 문서를 참조하십시오. ACID(원자성, 일관성, 고립성, 지속성)는 데이터베이스 트랜잭션이 안전하게 수행된다는 것을 보장하기 위한 &quot; data-og-host=&quot;ko.wikipedia.org&quot; data-og-source-url=&quot;https://ko.wikipedia.org/wiki/ACID&quot; data-og-url=&quot;https://ko.wikipedia.org/wiki/ACID&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://ko.wikipedia.org/wiki/ACID&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://ko.wikipedia.org/wiki/ACID&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;ACID - 위키백과, 우리 모두의 백과사전&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;위키백과, 우리 모두의 백과사전. 다른 뜻에 대해서는 애시드 문서를 참조하십시오. ACID(원자성, 일관성, 고립성, 지속성)는 데이터베이스 트랜잭션이 안전하게 수행된다는 것을 보장하기 위한&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;</description>
      <category>Computer Science/데이터베이스</category>
      <author>길순이</author>
      <guid isPermaLink="true">https://osy0907.tistory.com/112</guid>
      <comments>https://osy0907.tistory.com/112#entry112comment</comments>
      <pubDate>Wed, 7 Apr 2021 01:20:49 +0900</pubDate>
    </item>
    <item>
      <title>[기술 면접 질문] 기술 면접 예상 질문 대비하기 - Java편</title>
      <link>https://osy0907.tistory.com/100</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;java 프로그래밍이란&lt;/b&gt;&lt;/h2&gt;
&lt;h3&gt;Java SE와 Java EE 애플리케이션 차이&lt;/h3&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.ibm.com/support/knowledgecenter/ko/SSQP76_8.9.1/com.ibm.odm.dserver.rules.res.managing/topics/con_javase_javaee_applis.html&quot;&gt;https://www.ibm.com/support/knowledgecenter/ko/SSQP76_8.9.1/com.ibm.odm.dserver.rules.res.managing/topics/con_javase_javaee_applis.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3&gt;&lt;a id=&quot;user-content-java와-cc의-차이점&quot; href=&quot;https://github.com/WeareSoft/tech-interview/blob/master/contents/java.md#java%EC%99%80-cc%EC%9D%98-%EC%B0%A8%EC%9D%B4%EC%A0%90&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt;java와 c/c++의 차이점&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;java와 c/c++의 가장 큰 차이점은 실행 환경이다.&lt;/li&gt;
&lt;li&gt;java에서의 개발: 컴파일 혹은 컴파일 + jar압축
&lt;ul&gt;
&lt;li&gt;자바는 링크 과정이 없이 컴파일러가 바로 바이트 코드를 생성&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;c/c++에서의 개발: 컴파일 + 링크&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;a id=&quot;user-content-java-언어의-장단점&quot; href=&quot;https://github.com/WeareSoft/tech-interview/blob/master/contents/java.md#java-%EC%96%B8%EC%96%B4%EC%9D%98-%EC%9E%A5%EB%8B%A8%EC%A0%90&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt;&lt;b&gt;java 언어의 장단점&lt;/b&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;장점
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;운영체제에 독립적이다.&lt;/b&gt;
&lt;ul&gt;
&lt;li&gt;JVM에서 동작하기 때문에, 특정 운영체제에 종속되지 않는다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;객체지향 언어이다.&lt;/b&gt;
&lt;ul&gt;
&lt;li&gt;객체지향적으로 프로그래밍 하기 위해 여러 언어적 지원을 하고있다. (캡슐화, 상속, 추상화, 다형성 등)&lt;/li&gt;
&lt;li&gt;객체지향 패러다임의 특성상 비교적 이해하고 배우기 쉽다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;자동으로 메모리 관리를 해준다.&lt;/b&gt;
&lt;ul&gt;
&lt;li&gt;JVM에서 Garbage Collector라고 불리는 데몬 쓰레드에 의해 GC(Garbage Collection)가 일어난다. GC로 인해 별도의 메모리 관리가 필요 없으며 비지니스 로직에 집중할 수 있다.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;http://www.jpstory.net/2013/12/15/garbage-collection-in-java/&quot;&gt;(참고)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;오픈소스이다.&lt;/b&gt;
&lt;ul&gt;
&lt;li&gt;정확히 말하면 OpenJDK가 오픈소스이다. OracleJDK는 사용 목적에 따라서 유료가 될 수 있다.
&lt;ul&gt;
&lt;li&gt;OracleJDK의 유료화 이슈는 다음을 참고.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://okky.kr/article/490213&quot;&gt;(참고)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;많은 Java 개발자가 존재하고 생태계가 잘 구축되어있다. 덕분에 오픈소스 라이브러리가 풍부하며 잘 활용한다면 짧은 개발 시간 내에 안정적인 애플리케이션을 쉽게 구현할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;멀티스레드를 쉽게 구현할 수 있다.&lt;/b&gt;
&lt;ul&gt;
&lt;li&gt;자바는 스레드 생성 및 제어와 관련된 라이브러리 API를 제공하고 있기 때문에 실행되는 운영체제에 상관없이 멀티 스레드를 쉽게 구현할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;동적 로딩(Dynamic Loading)을 지원한다&lt;/b&gt;
&lt;ul&gt;
&lt;li&gt;애플리케이션이 실행될 때 모든 객체가 생성되지 않고, 각 객체가 필요한 시점에 클래스를 동적 로딩해서 생성한다. 또한 유지보수 시 해당 클래스만 수정하면 되기 때문에 전체 애플리케이션을 다시 컴파일할 필요가 없다. 따라서 유지보수가 쉽고 빠르다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;단점
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;비교적 속도가 느리다.&lt;/b&gt;
&lt;ul&gt;
&lt;li&gt;자바는 한 번의 컴파일링으로 실행 가능한 기계어가 만들어지지 않고 JVM에 의해 기계어로 번역되고 실행하는 과정을 거치기 때문에 C나 C++의 컴파일 단계에서 만들어지는 완전한 기계어보다는 속도가 느리다. 그러나 하드웨어의 성능 향상과 바이트 코드를 기계어로 변환해주는 JIT 컴파일러 같은 기술 적용으로 JVM의 기능이 향상되어 속도의 격차가 많이 줄어들었다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;예외처리가 불편하다.&lt;/b&gt;
&lt;ul&gt;
&lt;li&gt;프로그래머 검사가 필요한 예외가 등장한다면 무조건 프로그래머가 선언을 해줘야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://yolojeb.tistory.com/17&quot;&gt;http://yolojeb.tistory.com/17&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://huhghiza.tistory.com/7&quot;&gt;http://huhghiza.tistory.com/7&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3&gt;&lt;a id=&quot;user-content-java의-접근-제어자의-종류와-특징&quot; href=&quot;https://github.com/WeareSoft/tech-interview/blob/master/contents/java.md#java%EC%9D%98-%EC%A0%91%EA%B7%BC-%EC%A0%9C%EC%96%B4%EC%9E%90%EC%9D%98-%EC%A2%85%EB%A5%98%EC%99%80-%ED%8A%B9%EC%A7%95&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt;java의 접근 제어자의 종류와 특징&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;70%&quot; height=&quot;70%&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/boMCcv/btqJsjJkL5g/7QnwCEEBhRpLmJ6JIOBTk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/boMCcv/btqJsjJkL5g/7QnwCEEBhRpLmJ6JIOBTk0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/boMCcv/btqJsjJkL5g/7QnwCEEBhRpLmJ6JIOBTk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FboMCcv%2FbtqJsjJkL5g%2F7QnwCEEBhRpLmJ6JIOBTk0%2Fimg.png&quot; width=&quot;70%&quot; height=&quot;70%&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;h3&gt;&lt;a id=&quot;user-content-java의-데이터-타입&quot; href=&quot;https://github.com/WeareSoft/tech-interview/blob/master/contents/java.md#java%EC%9D%98-%EB%8D%B0%EC%9D%B4%ED%84%B0-%ED%83%80%EC%9E%85&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt;java의 데이터 타입&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;기본 데이터 타입(Primitive Data Type)
&lt;ul&gt;
&lt;li&gt;기본 타입의 종류는 byte, short, char, int, float, double, boolean이 있다.
&lt;ul&gt;
&lt;li&gt;정수형 : byte, short, int, long&lt;/li&gt;
&lt;li&gt;실수형 : float, double&lt;/li&gt;
&lt;li&gt;논리형 : boolean(ture/false)&lt;/li&gt;
&lt;li&gt;문자형 : char&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;기본 타입의 크기가 작고 고정적이기 때문에 메모리의&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;Stack&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;영역에 저장된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;참조 타입(Reference Data Type)
&lt;ul&gt;
&lt;li&gt;참조 타입의 종류는 class, array, interface, Enumeration이 있다.
&lt;ul&gt;
&lt;li&gt;기본형을 제외하고는 모두 참조형이다.&lt;/li&gt;
&lt;li&gt;new 키워드를 이용하여 객체를 생성하여 데이터가 생성된 주소를 참조하는 타입이다.&lt;/li&gt;
&lt;li&gt;String, StringBuffer, List, 개인이 만든 클래스 등&lt;/li&gt;
&lt;li&gt;String과 배열은 참조 타입과 달리 new 없이 생성이 가능하지만 기본 타입이 아닌 참조 타입이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;참조 타입의 데이터의 크기가 가변적, 동적이기 때문에 동적으로 관리되는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;Heap&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;영역에 저장된다.&lt;/li&gt;
&lt;li&gt;더 이상 참조하는 변수가 없을 때 가비지 컬렉션에 의해 파괴된다.&lt;/li&gt;
&lt;li&gt;참조 타입은 값이 저장된 곳의 주소를 저장하는 공간으로 객체의 주소를 저장한다. (Call-By-Value)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://robyncloud.tistory.com/entry/&quot;&gt;http://robyncloud.tistory.com/entry/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://m.blog.naver.com/PostView.nhn?blogId=roropoly1&amp;amp;logNo=220649338545&amp;amp;proxyReferer=https%3A%2F%2Fwww.google.co.kr%2F&quot;&gt;https://m.blog.naver.com/PostView.nhn?blogId=roropoly1&amp;amp;logNo=220649338545&amp;amp;proxyReferer=https%3A%2F%2Fwww.google.co.kr%2F&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3&gt;&lt;a id=&quot;user-content-oop의-4가지-특징&quot; href=&quot;https://github.com/WeareSoft/tech-interview/blob/master/contents/java.md#oop%EC%9D%98-4%EA%B0%80%EC%A7%80-%ED%8A%B9%EC%A7%95&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt;OOP의 4가지 특징&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;추상화(Abstraction)
&lt;ul&gt;
&lt;li&gt;구체적인 사물들의 공통적인 특징을 파악해서 이를 하나의 개념(집합)으로 다루는 것&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;캡슐화(Encapsulation)
&lt;ul&gt;
&lt;li&gt;정보 은닉(information hiding): 필요가 없는 정보는 외부에서 접근하지 못하도록 제한하는 것&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;일반화 관계(Inheritance, 상속)
&lt;ul&gt;
&lt;li&gt;여러 개체들이 가진 공통된 특성을 부각시켜 하나의 개념이나 법칙으로 성립시키는 과정&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;다형성(Polymorphism)
&lt;ul&gt;
&lt;li&gt;서로 다른 클래스의 객체가 같은 메시지를 받았을 때 각자의 방식으로 동작하는 능력&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://gmlwjd9405.github.io/2018/07/05/oop-features.html&quot;&gt;https://gmlwjd9405.github.io/2018/07/05/oop-features.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3&gt;&lt;a id=&quot;user-content-oop의-5대-원칙&quot; href=&quot;https://github.com/WeareSoft/tech-interview/blob/master/contents/java.md#oop%EC%9D%98-5%EB%8C%80-%EC%9B%90%EC%B9%99&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt;OOP의 5대 원칙&lt;/h3&gt;
&lt;p&gt;&quot;&lt;b&gt;SOLID&lt;/b&gt;&quot; 원칙&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;S&lt;/b&gt;: 단일 책임 원칙(SRP, Single Responsibility Principle)
&lt;ul&gt;
&lt;li&gt;객체는 단 하나의 책임만 가져야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;O&lt;/b&gt;: 개방-폐쇄 원칙(OCP, Open Closed Principle)
&lt;ul&gt;
&lt;li&gt;기존의 코드를 변경하지 않으면서 기능을 추가할 수 있도록 설계가 되어야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;L&lt;/b&gt;: 리스코프 치환 원칙(LSP, Liskov Substitution Principle)
&lt;ul&gt;
&lt;li&gt;일반화 관계에 대한 이야기며, 자식 클래스는 최소한 자신의 부모 클래스에서 가능한 행위는 수행할 수 있어야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;I&lt;/b&gt;: 인터페이스 분리 원칙(ISP, Interface Segregation Principle)
&lt;ul&gt;
&lt;li&gt;인터페이스를 클라이언트에 특화되도록 분리시키라는 설계 원칙이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;D&lt;/b&gt;: 의존 역전 원칙(DIP, Dependency Inversion Principle)
&lt;ul&gt;
&lt;li&gt;의존 관계를 맺을 때 변화하기 쉬운 것 또는 자주 변화하는 것보다는 변화하기 어려운 것, 거의 변화가 없는 것에 의존하라는 것이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://gmlwjd9405.github.io/2018/07/05/oop-solid.html&quot;&gt;https://gmlwjd9405.github.io/2018/07/05/oop-solid.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3&gt;&lt;a id=&quot;user-content-객체지향-프로그래밍과-절차지향-프로그래밍의-차이&quot; href=&quot;https://github.com/WeareSoft/tech-interview/blob/master/contents/java.md#%EA%B0%9D%EC%B2%B4%EC%A7%80%ED%96%A5-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D%EA%B3%BC-%EC%A0%88%EC%B0%A8%EC%A7%80%ED%96%A5-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D%EC%9D%98-%EC%B0%A8%EC%9D%B4&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt;객체지향 프로그래밍과 절차지향 프로그래밍의 차이&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;절차지향 프로그래밍
&lt;ul&gt;
&lt;li&gt;실행하고자 하는 절차를 정하고, 이 절차대로 프로그래밍하는 방법&lt;/li&gt;
&lt;li&gt;목적을 달성하기 위한 일의 흐름에 중점을 둔다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;객체지향 프로그래밍
&lt;ul&gt;
&lt;li&gt;실세상의 물체를 객체로 표현하고, 이들 사이의 관계, 상호 작용을 프로그램으로 나타낸다.&lt;/li&gt;
&lt;li&gt;객체를 추출하고 객체들의 관계를 결정하고 이들의 상호 작용에 필요한 함수(메서드)와 변수(필드)를 설계 및 구현하다.&lt;/li&gt;
&lt;li&gt;객체 지향의 핵심은 연관되어 있는 변수와 메서드를 하나의 그룹으로 묶어서 그룹핑하는 것이다.&lt;/li&gt;
&lt;li&gt;사람의 사고와 가장 비슷하게 프로그래밍을 하기 위해서 생성된 기법&lt;/li&gt;
&lt;li&gt;하나의 클래스를 바탕으로 서로 다른 상태를 가진 인스턴스를 만들면 서로 다른 행동을 하게 된다. 즉, 하나의 클래스가 여러 개의 인스턴스가 될 수 있다는 점이 객체 지향이 제공하는 가장 기본적인 재활용성이라고 할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;a id=&quot;user-content-java의-non-static-멤버와-static-멤버의-차이&quot; href=&quot;https://github.com/WeareSoft/tech-interview/blob/master/contents/java.md#java%EC%9D%98-non-static-%EB%A9%A4%EB%B2%84%EC%99%80-static-%EB%A9%A4%EB%B2%84%EC%9D%98-%EC%B0%A8%EC%9D%B4&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt;java의 non-static 멤버와 static 멤버의 차이&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;non-static 멤버
&lt;ul&gt;
&lt;li&gt;공간적 특성:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;멤버는 객체마다 별도로 존재한다.&lt;/b&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;인스턴스 멤버&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;라고 부른다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;시간적 특성:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;객체 생성 시에 멤버가 생성된다.&lt;/b&gt;
&lt;ul&gt;
&lt;li&gt;객체가 생길 때 멤버도 생성된다.&lt;/li&gt;
&lt;li&gt;객체 생성 후 멤버 사용이 가능하다.&lt;/li&gt;
&lt;li&gt;객체가 사라지면 멤버도 사라진다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;공유의 특성:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;공유되지 않는다.&lt;/b&gt;
&lt;ul&gt;
&lt;li&gt;멤버는 객체 내에 각각의 공간을 유지한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;static 멤버
&lt;ul&gt;
&lt;li&gt;공간적 특성:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;멤버는 클래스당 하나가 생성된다.&lt;/b&gt;
&lt;ul&gt;
&lt;li&gt;멤버는 객체 내부가 아닌 별도의 공간에 생성된다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;클래스 멤버&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;라고 부른다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;시간적 특성:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;클래스 로딩 시에 멤버가 생성된다.&lt;/b&gt;
&lt;ul&gt;
&lt;li&gt;객체가 생기기 전에 이미 생성된다.&lt;/li&gt;
&lt;li&gt;객체가 생기기 전에도 사용이 가능하다. (즉, 객체를 생성하지 않고도 사용할 수 있다.)&lt;/li&gt;
&lt;li&gt;객체가 사라져도 멤버는 사라지지 않는다.&lt;/li&gt;
&lt;li&gt;멤버는 프로그램이 종료될 때 사라진다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;공유의 특성:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;동일한 클래스의 모든 객체들에 의해 공유된다.&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://gmlwjd9405.github.io/2018/08/04/java-static.html&quot;&gt;https://gmlwjd9405.github.io/2018/08/04/java-static.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3&gt;&lt;a id=&quot;user-content-questionjava의-main-메서드가-static인-이유&quot; href=&quot;https://github.com/WeareSoft/tech-interview/blob/master/contents/java.md#questionjava%EC%9D%98-main-%EB%A9%94%EC%84%9C%EB%93%9C%EA%B0%80-static%EC%9D%B8-%EC%9D%B4%EC%9C%A0&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt;❓java의 main 메서드가 static인 이유&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;static&lt;span&gt;&amp;nbsp;&lt;/span&gt;키워드
&lt;ul&gt;
&lt;li&gt;static&lt;span&gt;&amp;nbsp;&lt;/span&gt;멤버는 클래스 로딩(프로그램 시작) 시 메모리에 로드되어 인스턴트를 생성하지 않아도 호출이 가능하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;main 메서드가&lt;span&gt;&amp;nbsp;&lt;/span&gt;static인 이유
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;span&gt;public&lt;/span&gt; &lt;span&gt;static&lt;/span&gt; &lt;span&gt;void&lt;/span&gt; main(&lt;span&gt;String&lt;/span&gt;[] args){&lt;span&gt;...&lt;/span&gt;}&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;위와 같은 형식은 java에서의&lt;span&gt;&amp;nbsp;&lt;/span&gt;main()&lt;span&gt;&amp;nbsp;&lt;/span&gt;관례이다. 위와 같은 시그니처를 가진 메소드가 없으면 실행되지 않는다.&lt;/li&gt;
&lt;li&gt;JVM은 인스턴스가 없는 클래스의&lt;span&gt;&amp;nbsp;&lt;/span&gt;main()을 호출해야하기 때문에&lt;span&gt;&amp;nbsp;&lt;/span&gt;static이어야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;JVM과&lt;span&gt;&amp;nbsp;&lt;/span&gt;static
&lt;ul&gt;
&lt;li&gt;코드를 실행하면 컴파일러가&lt;span&gt;&amp;nbsp;&lt;/span&gt;.java&lt;span&gt;&amp;nbsp;&lt;/span&gt;코드를&lt;span&gt;&amp;nbsp;&lt;/span&gt;.class(byte code)로 변환한다.&lt;/li&gt;
&lt;li&gt;클래스 로더가&lt;span&gt;&amp;nbsp;&lt;/span&gt;.class파일을 메모리 영역(Runtime Data Area)에 로드한다.&lt;/li&gt;
&lt;li&gt;Runtime Data Area 중 Meathod Area(= Class area = Static area)라고 불리는 영역에 Class Variable이 저장되는데,&lt;span&gt;&amp;nbsp;&lt;/span&gt;static&lt;span&gt;&amp;nbsp;&lt;/span&gt;변수 또한 여기에 포함된다.&lt;/li&gt;
&lt;li&gt;JVM은 Meathod Area에 로드된&lt;span&gt;&amp;nbsp;&lt;/span&gt;main()을 실행한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&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/bp6en0/btqJtZwPU18/Fk5VOlrSlIf8IK5gf7Gvu0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bp6en0/btqJtZwPU18/Fk5VOlrSlIf8IK5gf7Gvu0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bp6en0/btqJtZwPU18/Fk5VOlrSlIf8IK5gf7Gvu0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbp6en0%2FbtqJtZwPU18%2FFk5VOlrSlIf8IK5gf7Gvu0%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;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.holaxprogramming.com/2013/07/16/java-jvm-runtime-data-area/&quot;&gt;JVM의 Runtime Data Area - Minhyeok Jung&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://stackoverflow.com/questions/146576/why-is-the-java-main-method-static&quot;&gt;Why is the Java main method static? - Stack Overflow&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://m.blog.naver.com/PostView.nhn?blogId=blogpyh&amp;amp;logNo=220041002621&amp;amp;proxyReferer=https%3A%2F%2Fwww.google.co.kr%2F&quot;&gt;main에 static 사용하는이유 :: public static void main(String[] args) - PYH&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://itpangpang.xyz/71&quot;&gt;[자바]static, JVM memory의 기본(1편) - ITPangPang&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://wanzargen.tistory.com/16&quot;&gt;JAVA :: 자바의 메모리 구조 - 1. 메소드 영역(Method Area) - WANZARGEN&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3&gt;&lt;a id=&quot;user-content-java의-final-키워드&quot; href=&quot;https://github.com/WeareSoft/tech-interview/blob/master/contents/java.md#java%EC%9D%98-final-%ED%82%A4%EC%9B%8C%EB%93%9C&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt;java의 final 키워드&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;final 키워드&lt;/b&gt;
&lt;ul&gt;
&lt;li&gt;개념: 변수나 메서드 또는 클래스가 '변경 불가능'하도록 만든다.&lt;/li&gt;
&lt;li&gt;원시(Primitive) 변수에 적용 시
&lt;ul&gt;
&lt;li&gt;해당 변수의 값은 변경이 불가능하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;참조(Reference) 변수에 적용 시
&lt;ul&gt;
&lt;li&gt;참조 변수가 힙(heap) 내의 다른 객체를 가리키도록 변경할 수 없다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;메서드에 적용 시
&lt;ul&gt;
&lt;li&gt;해당 메서드를 오버라이드할 수 없다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;클래스에 적용 시
&lt;ul&gt;
&lt;li&gt;해당 클래스의 하위 클래스를 정의할 수 없다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;finally 키워드&lt;/b&gt;
&lt;ul&gt;
&lt;li&gt;개념: try/catch 블록이 종료될 때 항상 실행될 코드 블록을 정의하기 위해 사용한다.&lt;/li&gt;
&lt;li&gt;finally는 선택적으로 try 혹은 catch 블록 뒤에 정의할 때 사용한다.&lt;/li&gt;
&lt;li&gt;finally 블록은 예외가 발생하더라도 항상 실행된다.
&lt;ul&gt;
&lt;li&gt;단, JVM이 try 블록 실행 중에 종료되는 경우는 제외한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;finally 블록은 종종 뒷마무리 코드를 작성하는 데 사용된다.&lt;/li&gt;
&lt;li&gt;finally 블록은 try와 catch 블록 다음과, 통제권이 이전으로 다시 돌아가기 전 사이에 실행된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;finalize() 메서드&lt;/b&gt;
&lt;ul&gt;
&lt;li&gt;개념: 쓰레기 수집기(GC, Garbage Collector)가 더 이상의 참조가 존재하지 않는 객체를 메모리에서 삭제하겠다고 결정하는 순간 호출된다.&lt;/li&gt;
&lt;li&gt;Object 클래스의 finalize() 메서드를 오버라이드해서 맞춤별 GC를 정의할 수 있다.
&lt;ul&gt;
&lt;li&gt;protected void finalize() throws Throwable { // 파일 닫기, 자원 반환 등등 }&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://gmlwjd9405.github.io/2018/08/06/java-final.html&quot;&gt;https://gmlwjd9405.github.io/2018/08/06/java-final.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3&gt;&lt;a id=&quot;user-content-java의-제네릭과-c의-템플릿의-차이&quot; href=&quot;https://github.com/WeareSoft/tech-interview/blob/master/contents/java.md#java%EC%9D%98-%EC%A0%9C%EB%84%A4%EB%A6%AD%EA%B3%BC-c%EC%9D%98-%ED%85%9C%ED%94%8C%EB%A6%BF%EC%9D%98-%EC%B0%A8%EC%9D%B4&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt;java의 제네릭과 c++의 템플릿의 차이&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;java의 제네릭(Generic)
&lt;ul&gt;
&lt;li&gt;개념: 모든 종류의 타입을 다룰 수 있도록 일반화된 타입 매개 변수(generic type)로 클래스나 메서드를 선언하는 기법&lt;/li&gt;
&lt;li&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;60%&quot; height=&quot;60%&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/nlZAO/btqJnFs2lMk/s0l6uBAzQpNS2trwXJvn70/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nlZAO/btqJnFs2lMk/s0l6uBAzQpNS2trwXJvn70/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nlZAO/btqJnFs2lMk/s0l6uBAzQpNS2trwXJvn70/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnlZAO%2FbtqJnFs2lMk%2Fs0l6uBAzQpNS2trwXJvn70%2Fimg.png&quot; width=&quot;60%&quot; height=&quot;60%&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;/li&gt;
&lt;li&gt;처리 방법: 타입 제거(type erasure)라는 개념에 근거한다.
&lt;ul&gt;
&lt;li&gt;소스 코드를 JVM이 인식하는 바이트 코드로 변환할 때 인자로 주어진 타입을 제거하는 기술이다.&lt;/li&gt;
&lt;li&gt;제네릭이 있다고 해서 크게 달라지는 것은 없다. 단지 코드를 좀 더 예쁘게 할 뿐이다.&lt;/li&gt;
&lt;li&gt;그래서 java의 제네릭(Generic)은 때로는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;문법적 양념(syntactic sugar)&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;이라고 부른다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1600925610807&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Vector&amp;lt;String&amp;gt; vector = new Vector&amp;lt;String&amp;gt;();
vector.add(new String(&quot;hello&quot;));
String str = vector.get(0);

// 컴파일러가 아래와 같이 변환
Vector vector = new Vector();
vector.add(new String(&quot;hello&quot;));
String str = (String) vector.get(0);&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;c++의 템플릿(Template)
&lt;ul&gt;
&lt;li&gt;개념: 템플릿은 하나의 클래스를 서로 다른 여러 타입에 재사용할 수 있도록 하는 방법
&lt;ul&gt;
&lt;li&gt;예를 들어 여러 타입의 객체를 저장할 수 있는 연결리스트와 같은 자료구조를 만들 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;처리 방법: 컴파일러는 인자로 주어진 각각의 타입에 대해 별도의 템플릿 코드를 생성한다.
&lt;ul&gt;
&lt;li&gt;예를 들어 MyClass가 MyClass와 정적 변수(static variable)를 공유하지 않는다.&lt;/li&gt;
&lt;li&gt;하지만 java에서 정적 변수는 제네릭(Generic) 인자로 어떤 타입을 주었는지에 관계없이 MyClass로 만든 모든 객체가 공유한다.&lt;/li&gt;
&lt;li&gt;즉, 템플릿은 좀 더&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;우아한 형태의 매크로&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1600925640662&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/** MyClass.h **/
template&amp;lt;class T&amp;gt; class MyClass {
  public:
    static int val;
    MyClass(int v) { val = v; }
};

/** MyClass.cpp **/
template&amp;lt;typename T&amp;gt;
int MyClass&amp;lt;T&amp;gt;::bar;
template class MyClass&amp;lt;Foo&amp;gt;;
template class MyClass&amp;lt;Bar&amp;gt;;

/** main.cpp **/
MyClass&amp;lt;Foo&amp;gt; * foo1 = new MyClass&amp;lt;Foo&amp;gt;(10);
MyClass&amp;lt;Foo&amp;gt; * foo2 = new MyClass&amp;lt;Foo&amp;gt;(15);
MyClass&amp;lt;Bar&amp;gt; * bar1 = new MyClass&amp;lt;Bar&amp;gt;(20);
MyClass&amp;lt;Bar&amp;gt; * bar2 = new MyClass&amp;lt;Bar&amp;gt;(35);
int f1 = foo1-&amp;gt;val; // 15
int f2 = foo2-&amp;gt;val; // 15
int b1 = bar1-&amp;gt;val; // 35
int b2 = bar2-&amp;gt;val; // 35&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;java의 제네릭과 c++의 템플릿의 차이
&lt;ol&gt;
&lt;li&gt;List처럼 코드를 작성할 수 있다는 이유에서 동등한 개념으로 착각하기 쉽지만 두 언어가 이를 처리하는 방법은 아주 많이 다르다.&lt;/li&gt;
&lt;li&gt;c++의 Template에는 int와 같은 기본 타입을 인자로 넘길 수 있지만, java의 Generic에서는 Integer을 대신 사용해야 한다.&lt;/li&gt;
&lt;li&gt;c++의 Template은 인자로 주어진 타입으로부터 객체를 만들어 낼 수 있지만, java에서는 불가능하다.&lt;/li&gt;
&lt;li&gt;java에서 MyClass로 만든 모든 객체는 Generic 타입 인자가 무엇이냐에 관계없이 전부 동등한 타입이다.(실행 시간에 타입 인자 정보는 삭제된다.)
&lt;ul&gt;
&lt;li&gt;c++에서는 다른 Template 타입 인자를 사용해 만든 객체는 서로 다른 타입의 객체이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;java의 경우 Generic 타입 인자를 특정한 타입이 되도록 제한할 수 있다.
&lt;ul&gt;
&lt;li&gt;예를 들어 CardDeck을 Generic 클래스로 정의할 때 CardGame의 하위 클래스만 사용되도록 제한할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;java에서 Generic 타입의 인자는 정적 메서드나 변수를 선언하는 데 사용될 수 없다.
&lt;ul&gt;
&lt;li&gt;왜냐하면 MyClass나 MyClass가 이 메서드와 변수를 공유하기 때문이다.&lt;/li&gt;
&lt;li&gt;c++ Template은 이 두 클래스를 다른 클래스로 처리하므로 Template 타입 인자를 정적 메서드나 변수를 선언하는 데 사용할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.kyobobook.co.kr/product/detailViewKor.laf?mallGb=KOR&amp;amp;ejkGb=KOR&amp;amp;barcode=9788966263080&amp;amp;OV_REFFER=http://click.linkprice.com/click.php?m=kbbook&amp;amp;a=A100532541&amp;amp;l=9999&amp;amp;l_cd1=0&amp;amp;u_id=jm0gctc7ca029ofs02yqe&amp;amp;l_cd2=0&amp;amp;tu=https%3A%2F%2Fwww.kyobobook.co.kr%2Fproduct%2FdetailViewKor.laf%3FmallGb%3DKOR%26ejkGb%3DKOR%26barcode%3D9788966263080&quot;&gt;코딩 인터뷰 완전 분석, 프로그래밍인사이트&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3&gt;&lt;a id=&quot;user-content-java-직렬화와-역직렬화란-무엇인가&quot; href=&quot;https://github.com/WeareSoft/tech-interview/blob/master/contents/java.md#java-%EC%A7%81%EB%A0%AC%ED%99%94%EC%99%80-%EC%97%AD%EC%A7%81%EB%A0%AC%ED%99%94%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt;java 직렬화와 역직렬화란 무엇인가&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;자바 직렬화(Serialization)란
&lt;ul&gt;
&lt;li&gt;자바 시스템 내부에서 사용되는 객체 또는 데이터를 외부의 자바 시스템에서도 사용할 수 있도록 바이트(byte) 형태로 데이터 변환하는 기술&lt;/li&gt;
&lt;li&gt;시스템적으로 이야기하자면 JVM(Java Virtual Machine 이하 JVM)의 메모리에 상주(힙 또는 스택)되어 있는 객체 데이터를 바이트 형태로 변환하는 기술&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;자바 직렬화 조건
&lt;ol&gt;
&lt;li&gt;자바 기본(primitive) 타입&lt;/li&gt;
&lt;li&gt;java.io.Serializable&lt;span&gt;&amp;nbsp;&lt;/span&gt;인터페이스를 상속받은 객체&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;직렬화 방법
&lt;ul&gt;
&lt;li&gt;java.io.ObjectOutputStream&lt;span&gt;&amp;nbsp;&lt;/span&gt;객체를 이용&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;자바 역직렬화(Deserialization)란
&lt;ul&gt;
&lt;li&gt;바이트로 변환된 데이터를 다시 객체로 변환하는 기술&lt;/li&gt;
&lt;li&gt;직렬화된 바이트 형태의 데이터를 객체로 변환해서 JVM으로 상주시키는 형태의 기술&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;자바 역직렬화 조건
&lt;ol&gt;
&lt;li&gt;직렬화 대상이 된 객체의 클래스가 클래스 패스에 존재해야 하며 import 되어 있어야 한다.
&lt;ul&gt;
&lt;li&gt;중요한 점은 직렬화와 역직렬화를 진행하는 시스템이 서로 다를 수 있다는 것을 반드시 고려해야 한다. (같은 시스템 내부이라도 소스 버전이 다를 수 있다.)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;자바 직렬화 대상 객체는 동일한 serialVersionUID 를 가지고 있어야 한다.
&lt;ul&gt;
&lt;li&gt;private static final long serialVersionUID = 1L;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;역직렬화 방법
&lt;ul&gt;
&lt;li&gt;java.io.ObjectInputStream&lt;span&gt;&amp;nbsp;&lt;/span&gt;객체를 이용&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://woowabros.github.io/experience/2017/10/17/java-serialize.html&quot;&gt;http://woowabros.github.io/experience/2017/10/17/java-serialize.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://woowabros.github.io/experience/2017/10/17/java-serialize2.html&quot;&gt;http://woowabros.github.io/experience/2017/10/17/java-serialize2.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://nesoy.github.io/articles/2018-04/Java-Serialize&quot;&gt;https://nesoy.github.io/articles/2018-04/Java-Serialize&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3&gt;&lt;a id=&quot;user-content-클래스-객체-인스턴스의-차이&quot; href=&quot;https://github.com/WeareSoft/tech-interview/blob/master/contents/java.md#%ED%81%B4%EB%9E%98%EC%8A%A4-%EA%B0%9D%EC%B2%B4-%EC%9D%B8%EC%8A%A4%ED%84%B4%EC%8A%A4%EC%9D%98-%EC%B0%A8%EC%9D%B4&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt;클래스 객체 인스턴스의 차이&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;클래스(Class)
&lt;ul&gt;
&lt;li&gt;객체를 만들어 내기 위한&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;설계도&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;혹은 틀&lt;/li&gt;
&lt;li&gt;연관되어 있는 변수와 메서드의 집합&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;객체(Object)
&lt;ul&gt;
&lt;li&gt;소프트웨어 세계에&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;구현할 대상&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;클래스에 선언된 모양 그대로 생성된 실체&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;'클래스의 인스턴스(instance)'&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;라고도 부른다.&lt;/li&gt;
&lt;li&gt;객체는 모든 인스턴스를 대표하는 포괄적인 의미를 갖는다.&lt;/li&gt;
&lt;li&gt;oop의 관점에서 클래스의 타입으로 선언되었을 때 '객체'라고 부른다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;인스턴스(Instance)
&lt;ul&gt;
&lt;li&gt;설계도를 바탕으로 소프트웨어 세계에&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;구현된 구체적인 실체&lt;/b&gt;
&lt;ul&gt;
&lt;li&gt;즉, 객체를 소프트웨어에 실체화 하면 그것을 '인스턴스'라고 부른다.&lt;/li&gt;
&lt;li&gt;실체화된 인스턴스는 메모리에 할당된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;인스턴스는 객체에 포함된다고 볼 수 있다.&lt;/li&gt;
&lt;li&gt;oop의 관점에서 객체가 메모리에 할당되어 실제 사용될 때 '인스턴스'라고 부른다.&lt;/li&gt;
&lt;li&gt;추상적인 개념(또는 명세)과 구체적인 객체 사이의&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;관계&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;에 초점을 맞출 경우에 사용한다.
&lt;ul&gt;
&lt;li&gt;'~의 인스턴스'&lt;span&gt;&amp;nbsp;&lt;/span&gt;의 형태로 사용된다.&lt;/li&gt;
&lt;li&gt;객체는 클래스의 인스턴스다.&lt;/li&gt;
&lt;li&gt;객체 간의 링크는 클래스 간의 연관 관계의 인스턴스다.&lt;/li&gt;
&lt;li&gt;실행 프로세스는 프로그램의 인스턴스다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;즉, 인스턴스라는 용어는 반드시 클래스와 객체 사이의 관계로 한정지어서 사용할 필요는 없다.&lt;/li&gt;
&lt;li&gt;인스턴스는 어떤 원본(추상적인 개념)으로부터 '생성된 복제본'을 의미한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1600925705688&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* 클래스 */
public class Animal {
  ...
}
/* 객체와 인스턴스 */
public class Main {
  public static void main(String[] args) {
    Animal cat, dog; // '객체'

    // 인스턴스화
    cat = new Animal(); // cat은 Animal 클래스의 '인스턴스'(객체를 메모리에 할당)
    dog = new Animal(); // dog은 Animal 클래스의 '인스턴스'(객체를 메모리에 할당)
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Q. 클래스 VS 객체
&lt;ul&gt;
&lt;li&gt;클래스는 '설계도', 객체는 '설계도로 구현한 모든 대상'을 의미한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Q. 객체 VS 인스턴스
&lt;ul&gt;
&lt;li&gt;클래스의 타입으로 선언되었을 때 객체라고 부르고, 그 객체가 메모리에 할당되어 실제 사용될 때 인스턴스라고 부른다.&lt;/li&gt;
&lt;li&gt;객체는 현실 세계에 가깝고, 인스턴스는 소프트웨어 세계에 가깝다.&lt;/li&gt;
&lt;li&gt;객체는 '실체', 인스턴스는 '관계'에 초점을 맞춘다.
&lt;ul&gt;
&lt;li&gt;객체를 '클래스의 인스턴스'라고도 부른다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;'방금 인스턴스화하여 레퍼런스를 할당한' 객체를 인스턴스라고 말하지만, 이는 원본(추상적인 개념)으로부터 생성되었다는 것에 의미를 부여하는 것일 뿐 엄격하게 객체와 인스턴스를 나누긴 어렵다.&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;추상화 기법
&lt;ol&gt;
&lt;li&gt;분류(Classification)
&lt;ul&gt;
&lt;li&gt;객체 -&amp;gt; 클래스&lt;/li&gt;
&lt;li&gt;실재하는 객체들을 공통적인 속성을 공유하는 범부 또는 추상적인 개념으로 묶는 것&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;인스턴스화(Instantiation)
&lt;ul&gt;
&lt;li&gt;클래스 -&amp;gt; 인스턴스&lt;/li&gt;
&lt;li&gt;분류의 반대 개념. 범주나 개념으로부터 실재하는 객체를 만드는 과정&lt;/li&gt;
&lt;li&gt;구체적으로 클래스 내의 객체에 대해 특정한 변형을 정의하고, 이름을 붙인 다음, 그것을 물리적인 어떤 장소에 위치시키는 등의 작업을 통해 인스턴스를 만드는 것을 말한다.&lt;/li&gt;
&lt;li&gt;'예시(Exemplification)'라고도 부른다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.slipp.net/questions/126&quot;&gt;https://www.slipp.net/questions/126&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://opentutorials.org/course/1223/5400&quot;&gt;https://opentutorials.org/course/1223/5400&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://cerulean85.tistory.com/149&quot;&gt;http://cerulean85.tistory.com/149&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.ijemin.com/blog/%EC%98%A4%EB%B8%8C%EC%A0%9D%ED%8A%B8%EC%99%80-%EC%9D%B8%EC%8A%A4%ED%84%B4%EC%8A%A4%EC%9D%98-%EC%B0%A8%EC%9D%B4-difference-between-obect-and-instance/&quot;&gt;https://www.ijemin.com/blog/%EC%98%A4%EB%B8%8C%EC%A0%9D%ED%8A%B8%EC%99%80-%EC%9D%B8%EC%8A%A4%ED%84%B4%EC%8A%A4%EC%9D%98-%EC%B0%A8%EC%9D%B4-difference-between-obect-and-instance/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3&gt;&lt;a id=&quot;user-content-오버로딩과-오버라이딩의-차이&quot; href=&quot;https://github.com/WeareSoft/tech-interview/blob/master/contents/java.md#%EC%98%A4%EB%B2%84%EB%A1%9C%EB%94%A9%EA%B3%BC-%EC%98%A4%EB%B2%84%EB%9D%BC%EC%9D%B4%EB%94%A9%EC%9D%98-%EC%B0%A8%EC%9D%B4&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt;오버로딩과 오버라이딩의 차이&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;오버로딩(Overloading)
&lt;ul&gt;
&lt;li&gt;두 메서드가 같은 이름을 갖고 있으나 인자의 수나 자료형이 다른 경우&lt;/li&gt;
&lt;li&gt;Ex)
&lt;ul&gt;
&lt;li&gt;public double computeArea(Circle c) { ... }&lt;/li&gt;
&lt;li&gt;public double computeArea(Circle c1, Circle c2) { ... }&lt;/li&gt;
&lt;li&gt;public double computeArea(Square c) { ... }&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;오버라이딩(Overriding)
&lt;ul&gt;
&lt;li&gt;상위 클래스의 메서드와 이름과 용례(signature)가 같은 함수를 하위 클래스에 재정의하는 것&lt;/li&gt;
&lt;li&gt;상속 관계에 있는 클래스 간에 같은 이름의 메서드를 정의&lt;/li&gt;
&lt;li&gt;Ex) Circle에서 printMe() 메서드를 재정의한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1600925746287&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public abstract class Shape {
    public void printMe() { System.out.println(&quot;Shape&quot;); }
    public abstract double computeArea();
}
public class Circle extends Shape {
    private double rad = 5;
    @Override // 개발자의 실수를 방지하기 위해 @Override(annotation) 쓰는 것을 권장
    public void printMe() { System.out.println(&quot;Circle&quot;); }
    public double computeArea() { return rad * rad * 3.15; }
}
public class Ambiguous extends Shape {
    private double area = 10;
    public double computeArea() { return area; }&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://gmlwjd9405.github.io/2018/08/09/java-overloading-vs-overriding.html&quot;&gt;https://gmlwjd9405.github.io/2018/08/09/java-overloading-vs-overriding.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3&gt;&lt;a id=&quot;user-content-call-by-reference와-call-by-value의-차이&quot; href=&quot;https://github.com/WeareSoft/tech-interview/blob/master/contents/java.md#call-by-reference%EC%99%80-call-by-value%EC%9D%98-%EC%B0%A8%EC%9D%B4&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt;Call by Reference와 Call by Value의 차이&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Call by Value (값에 의한 호출)
&lt;ul&gt;
&lt;li&gt;함수가 호출될 때, 메모리 공간 안에서는 함수를 위한 별도의 임시 공간이 생성된다.&lt;/li&gt;
&lt;li&gt;함수 호출시 인자로 전달되는 변수의 값을 복사하여 함수의 인자로 전달한다.&lt;/li&gt;
&lt;li&gt;복사된 인자는 함수 안에서 지역적으로 사용되는 local value의 특성을 가진다.&lt;/li&gt;
&lt;li&gt;따라서 함수 안에서 인자의 값이 변경되어도, 외부의 변수의 값은 변경되지 않는다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Call by Reference (참조에 의한 호출)
&lt;ul&gt;
&lt;li&gt;함수가 호출될 때, 메모리 공간 안에서는 함수를 위한 별도의 임시 공간이 생성된다.&lt;/li&gt;
&lt;li&gt;함수 호출시 인자로 전달되는 변수의 레퍼런스를 전달한다. (해당 변수를 가리킨다.)&lt;/li&gt;
&lt;li&gt;따라서 함수 안에서 인자의 값이 변경되면, 인자로 전달된 변수의 값도 함께 변경된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Java는 Call by Value 일까? Call by Reference 일까?&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1600925865341&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Person {
  private String name;
  public Person(String name) {
    this.name = name;
  }
  public setName(String name) {
    this.name = name;
  }
  @Override
  public String toString() {
    return &quot;name is &quot; + this.name;
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1600925860325&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class FunctionCallTest {
  public static void assignNewPerson(Person p) {
    p = new Person(&quot;hee&quot;);
  }
  public static void changeName(Person p) {
    p.setName(&quot;hee&quot;);
  }

  public static void main(String[] args) {
    Person p = new Person(&quot;doy&quot;);

    assignNewPerson(p);
    System.out.println(p); // name is doy

    changeName(p);
    System.out.println(p); // name is hee
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1600925773175&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class FunctionCallTest2 {
    /* parameter는 참조변수 array 자체의 Reference가 아닌 array가 &quot;저장하고 있는 주소값(Value)&quot; */
    public static void changeContent(int[] array) {
        // If we change the content of arr,
        array[0] = 10;  // Will change the content of array in main()
        array[1] = 11;
    }
    public static void changeRef(int[] array) {
        // If we change the reference,
        array = new int[2];  // Will not change the array in main()
        array[0] = 20;
        array[1] = 21;
    }

    public static void main(String[] args) {
        int[] array = new int[2];
        array[0] = 0;
        array[1] = 1;

        changeContent(array);
        for (int i = 0; i &amp;lt; array.length; i++) {
            // Will print 10 11
            System.out.print(array[i] + &quot; &quot;);  // 10 11
        }
        changeRef(array);
        for (int i = 0; i &amp;lt; array.length; i++) {
            // Will still print 10 11
            // (Change the reference doesn't reflect change here)
            System.out.print(array[i] + &quot; &quot;);  // 10 11
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;기본자료형은 Call By Value이고, 참조자료형은 Call By Reference이다??&lt;/li&gt;
&lt;li&gt;오해 1. 특정 메서드 내에서 전달 받은 객체의 상태를 변경 할 수 있다.
&lt;ul&gt;
&lt;li&gt;changeName&lt;span&gt;&amp;nbsp;&lt;/span&gt;메서드는 참조변수 p가 가리키는 [이름 속성이 &quot;doy&quot;인 Person 객체]를 [이름 속성이 &quot;hee&quot;인 새로운 Person 객체]로 변경한 것이 아니라, 단지 이름 속성만 변경했을 뿐이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;오해 2. 참조변수는 임의의 객체에 대한 레퍼런스를 저장하므로 메서드로 전달한 값이 레퍼런스(Call by Reference)이다.
&lt;ul&gt;
&lt;li&gt;전달된 레퍼런스는 참조변수 p 자체의 레퍼런스가 아닌 p가 저장하고 있는 값(이것도 레퍼런스)이다.&lt;/li&gt;
&lt;li&gt;만약 Java가 Call by Reference를 지원한다면&lt;span&gt;&amp;nbsp;&lt;/span&gt;assignNewPerson&lt;span&gt;&amp;nbsp;&lt;/span&gt;메서드 실행 후에 p 참조변수가 가리키는 객체가 [이름 속성이 &quot;hee&quot;인 새로운 Person 객체]로 변경되어야 한다.&lt;/li&gt;
&lt;li&gt;또한 참조변수 p 자체의 레퍼런스를 얻을 수 있는 방법이 있어야 한다. 그러나 Java는 이 방법을 지원하지 않는다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;따라서 Java는 항상 Call by Value 이다.&lt;/b&gt;
&lt;ul&gt;
&lt;li&gt;여기서 value 란?
&lt;ul&gt;
&lt;li&gt;기본자료형의 값 또는 객체에 대한 레퍼런스&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;기본자료형의 경우 해당하는 변수의 값을 복사해서 전달한다.&lt;/li&gt;
&lt;li&gt;참조자료형의 경우 해당하는 변수가 가지는 값이 레퍼런스이므로 인자로 넘길 때 Call by Value에 의해 변수가 가지고 있는 레퍼런스가 복사되어 전달된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://wayhome25.github.io/cs/2017/04/11/cs-13/&quot;&gt;https://wayhome25.github.io/cs/2017/04/11/cs-13/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://wonwoo.ml/index.php/post/1679&quot;&gt;http://wonwoo.ml/index.php/post/1679&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://brunch.co.kr/@kd4/2&quot;&gt;https://brunch.co.kr/@kd4/2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://mussebio.blogspot.com/2012/05/java-call-by-valuereference.html&quot;&gt;http://mussebio.blogspot.com/2012/05/java-call-by-valuereference.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://code.i-harness.com/ko-kr/q/c2ab51&quot;&gt;https://code.i-harness.com/ko-kr/q/c2ab51&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3&gt;&lt;a id=&quot;user-content-인터페이스와-추상-클래스의-차이&quot; href=&quot;https://github.com/WeareSoft/tech-interview/blob/master/contents/java.md#%EC%9D%B8%ED%84%B0%ED%8E%98%EC%9D%B4%EC%8A%A4%EC%99%80-%EC%B6%94%EC%83%81-%ED%81%B4%EB%9E%98%EC%8A%A4%EC%9D%98-%EC%B0%A8%EC%9D%B4&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt;인터페이스와 추상 클래스의 차이&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;추상 메서드(Abstract Method)
&lt;ul&gt;
&lt;li&gt;abstract 키워드와 함께 원형만 선언되고, 코드는 작성되지 않은 메서드&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1600925937213&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public abstract String getName(); // 추상 메서드
public abstract String fail() { return &quot;Fail&quot;; } // 추상 메서드 아님. 컴파일 오류 발생&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;추상 클래스(Abstract Class)
&lt;ul&gt;
&lt;li&gt;개념: abstract 키워드로 선언된 클래스
&lt;ol&gt;
&lt;li&gt;추상 메서드를 최소 한 개 이상 가지고 abstract로 선언된 클래스
&lt;ul&gt;
&lt;li&gt;최소 한 개의 추상 메서드를 포함하는 경우&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;반드시&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;추상 클래스로 선언하여야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;추상 메서드가 없어도 abstract로 선언한 클래스
&lt;ul&gt;
&lt;li&gt;그러나 추상 메서드가 하나도 없는 경우라도 추상 클래스로 선언할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;추상 클래스의 구현
&lt;ul&gt;
&lt;li&gt;서브 클래스에서 슈퍼 클래스의 모든 추상 메서드를 오버라이딩하여 실행가능한 코드로 구현한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;추상 클래스의 목적
&lt;ul&gt;
&lt;li&gt;객체(인스턴스)를 생성하기 위함이 아니며, 상속을 위한 부모 클래스로 활용하기 위한 것이다.&lt;/li&gt;
&lt;li&gt;여러 클래스들의&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;공통된 부분을 추상화(추상 메서드)&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;하여 상속받는 클래스에게 구현을 강제화하기 위한 것이다. (메서드의 동작을 구현하는 자식 클래스로 책임을 위임)&lt;/li&gt;
&lt;li&gt;즉, 추상 클래스의 추상 메서드를 자식 클래스가 구체화하여 그 기능을 확장하는 데 목적이 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1600926008349&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* 개념 a의 예시 */
abstract class Shape { // 추상 클래스
  Shape() {...}
  void edit() {...}
  abstract public void draw(); // 추상 메서드
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1600926002457&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* 개념 b의 예시 */
abstract class Shape { // 추상 클래스
  Shape() {...}
  void edit() {...}
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1600925961901&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* 추상 클래스의 구현 */
class Circle extends Shape {
  public void draw() { System.out.println(&quot;Circle&quot;); } // 추상 메서드 (오버라이딩)
  void show() { System.out.println(&quot;동그라미 모양&quot;); }
}&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;인터페이스(Interface)
&lt;ul&gt;
&lt;li&gt;개념: 추상 메서드와 상수만을 포함하며, interface 키워드를 사용하여 선언한다.&lt;/li&gt;
&lt;li&gt;인터페이스의 구현
&lt;ul&gt;
&lt;li&gt;인터페이스를 상속받고, 추상 메서드를 모두 구현한 클래스를 작성한다.&lt;/li&gt;
&lt;li&gt;implements 키워드를 사용하여 구현한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&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;즉, 서로 관련이 없는 클래스에서 공통적으로 사용하는 방식이 필요하지만 기능을 각각 구현할 필요가 있는 경우에 사용한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;인터페이스의 특징
&lt;ol&gt;
&lt;li&gt;인터페이스는 상수 필드와 추상 메서드만으로 구성된다.&lt;/li&gt;
&lt;li&gt;모든 메서드는 추상 메서드로서, abstract public 속성이며 생략 가능하다.&lt;/li&gt;
&lt;li&gt;상수는 public static final 속성이며, 생략하여 선언할 수 있다.&lt;/li&gt;
&lt;li&gt;인터페이스를 상속받아 새로운 인터페이스를 만들 수 있다.
&lt;ul&gt;
&lt;li&gt;interface MobilePhone extends Phone { }&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1600926081268&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* 인터페이스의 개념 */
interface Phone { // 인터페이스
  int BUTTONS = 20; // 상수 필드 (public static final int BUTTONS = 20;과 동일)
  void sendCall(); // 추상 메서드 (abstract public void sendCall();과 동일)
  abstract public void receiveCall(); // 추상 메서드
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1600926076276&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* 인터페이스의 구현 */
class FeaturePhone implements Phone {
  // Phone의 모든 추상 메서드를 구현한다.
  public void sendCall() {...}
  public void receiveCall() {...}

  // 추가적으로 다른 메서드를 작성할 수 있다.
  public int getButtons() {...}
}&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;추상 클래스와 인터페이스의&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;공통점&lt;/b&gt;
&lt;ul&gt;
&lt;li&gt;인스턴스(객체)는 생성할 수 없다.&lt;/li&gt;
&lt;li&gt;선언만 있고 구현 내용이 없다.&lt;/li&gt;
&lt;li&gt;자식 클래스가 메서드의 구체적인 동작을 구현하도록 책임을 위임한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;추상 클래스와 인터페이스의&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;차이점&lt;/b&gt;
&lt;ul&gt;
&lt;li&gt;서로 다른 목적을 가지고 있다.
&lt;ul&gt;
&lt;li&gt;추상 클래스는 추상 메서드를 자식 클래스가 구체화하여 그 기능을 확장하는 데 목적이 있다. (상속을 위한 부모 클래스)&lt;/li&gt;
&lt;li&gt;인터페이스는 서로 관련이 없는 클래스에서 공통적으로 사용하는 방식이 필요하지만 기능을 각각 구현할 필요가 있는 경우에 사용한다. (구현 객체의 같은 동작을 보장)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;추상 클래스는 클래스이지만 인터페이스는 클래스가 아니다.&lt;/li&gt;
&lt;li&gt;추상 클래스는 단일 상속이지만 인터페이스는 다중 상속이 가능하다.&lt;/li&gt;
&lt;li&gt;추상 클래스는 &amp;ldquo;is a kind of&amp;rdquo; 인터페이스는 &amp;ldquo;can do this&amp;rdquo;
&lt;ul&gt;
&lt;li&gt;Ex) 추상 클래스: Appliances(Abstract Class) - TV, Refrigerator&lt;/li&gt;
&lt;li&gt;Ex) 인터페이스: Flyable(Interface) - Plane, Bird&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://loustler.io/languages/oop_interface_and_abstract_class/&quot;&gt;http://loustler.io/languages/oop_interface_and_abstract_class/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://alecture.blogspot.com/2011/05/abstract-class-interface.html&quot;&gt;http://alecture.blogspot.com/2011/05/abstract-class-interface.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3&gt;&lt;a id=&quot;user-content-jvm-구조&quot; href=&quot;https://github.com/WeareSoft/tech-interview/blob/master/contents/java.md#jvm-%EA%B5%AC%EC%A1%B0&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt;JVM 구조&lt;/h3&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.itworld.co.kr/news/110837&quot;&gt;http://www.itworld.co.kr/news/110837&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://hoonmaro.tistory.com/19&quot;&gt;http://hoonmaro.tistory.com/19&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3&gt;&lt;a id=&quot;user-content-java-collections-framework&quot; href=&quot;https://github.com/WeareSoft/tech-interview/blob/master/contents/java.md#java-collections-framework&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt;Java Collections Framework&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;70%&quot; height=&quot;70%&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/bnd7wa/btqJvUILEA8/SUZ2rxeNTAYDkL4QqsazTk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bnd7wa/btqJvUILEA8/SUZ2rxeNTAYDkL4QqsazTk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bnd7wa/btqJvUILEA8/SUZ2rxeNTAYDkL4QqsazTk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbnd7wa%2FbtqJvUILEA8%2FSUZ2rxeNTAYDkL4QqsazTk%2Fimg.png&quot; width=&quot;70%&quot; height=&quot;70%&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;ul&gt;
&lt;li&gt;Map
&lt;ul&gt;
&lt;li&gt;검색할 수 있는 인터페이스&lt;/li&gt;
&lt;li&gt;데이터를 삽입할 때 Key와 Value의 형태로 삽입되며, Key를 이용해서 Value를 얻을 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Collection
&lt;ul&gt;
&lt;li&gt;List
&lt;ul&gt;
&lt;li&gt;순서가 있는 Collection&lt;/li&gt;
&lt;li&gt;데이터를 중복해서 포함할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Set
&lt;ul&gt;
&lt;li&gt;집합적인 개념의 Collection&lt;/li&gt;
&lt;li&gt;순서의 의미가 없다.&lt;/li&gt;
&lt;li&gt;데이터를 중복해서 포함할 수 없다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Collections Framework 선택 과정
&lt;ol&gt;
&lt;li&gt;Map과 Collection 인터페이스 중 선택 1-1. Collection 선택 시 사용 목적에 따라 List와 Set중 선택&lt;/li&gt;
&lt;li&gt;사용 목적에 따라 Map, List, Set 각각의 하위 구현체를 선택 2-1. Map: HashMap, LinkedHashMap, HashTable, TreeMap 2-2. List: LinkedList, ArrayList 2-3. Set: TreeSet, HashSet&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;Collections Framework 동기화
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://madplay.github.io/post/java-collection-synchronize&quot;&gt;https://madplay.github.io/post/java-collection-synchronize&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;a id=&quot;user-content-java-map-인터페이스-구현체의-종류&quot; href=&quot;https://github.com/WeareSoft/tech-interview/blob/master/contents/java.md#java-map-%EC%9D%B8%ED%84%B0%ED%8E%98%EC%9D%B4%EC%8A%A4-%EA%B5%AC%ED%98%84%EC%B2%B4%EC%9D%98-%EC%A2%85%EB%A5%98&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt;java Map 인터페이스 구현체의 종류&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;HashMap
&lt;ul&gt;
&lt;li&gt;Entry&amp;lt;K,V&amp;gt;의 배열로 저장되며, 배열의 index는 내부 해쉬 함수를 통해 계산된다.&lt;/li&gt;
&lt;li&gt;내부 hash값에 따라서 키순서가 정해지므로 특정 규칙없이 출력된다.&lt;/li&gt;
&lt;li&gt;key와 value에 null값을 허용한다.&lt;/li&gt;
&lt;li&gt;비동기 처리&lt;/li&gt;
&lt;li&gt;시간복잡도: O(1)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;LinkedHashMap
&lt;ul&gt;
&lt;li&gt;HaspMap을 상속받으며, Linked List로 저장된다.&lt;/li&gt;
&lt;li&gt;입력 순서대로 출력된다.&lt;/li&gt;
&lt;li&gt;비동기 처리&lt;/li&gt;
&lt;li&gt;시간복잡도: O(n)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;TreeMap
&lt;ul&gt;
&lt;li&gt;내부적으로 레드-블랙 트리(Red-Black tree)로 저장된다.&lt;/li&gt;
&lt;li&gt;키값이 기본적으로 오름차순 정렬되어 출력된다.&lt;/li&gt;
&lt;li&gt;키값에 대한 Compartor 구현으로 정렬 방법을 지정할 수 있다.&lt;/li&gt;
&lt;li&gt;시간복잡도: O(logn)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;ConCurrentHashMap
&lt;ul&gt;
&lt;li&gt;multiple lock&lt;/li&gt;
&lt;li&gt;update할 때만 동기 처리&lt;/li&gt;
&lt;li&gt;key와 value에 null값을 허용하지 않는다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;HashTable
&lt;ul&gt;
&lt;li&gt;single lock&lt;/li&gt;
&lt;li&gt;모든 메서드에 대해 동기 처리&lt;/li&gt;
&lt;li&gt;key와 value에 null값을 허용하지 않는다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;a id=&quot;user-content-java-set-인터페이스-구현체의-종류&quot; href=&quot;https://github.com/WeareSoft/tech-interview/blob/master/contents/java.md#java-set-%EC%9D%B8%ED%84%B0%ED%8E%98%EC%9D%B4%EC%8A%A4-%EA%B5%AC%ED%98%84%EC%B2%B4%EC%9D%98-%EC%A2%85%EB%A5%98&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt;java Set 인터페이스 구현체의 종류&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;HashSet
&lt;ul&gt;
&lt;li&gt;저장 순서를 유지하지 않는 데이터의 집합이다.&lt;/li&gt;
&lt;li&gt;해시 알고리즘(hash algorithm)을 사용하여 검색 속도가 매우 빠르다.&lt;/li&gt;
&lt;li&gt;내부적으로 HashMap 인스턴스를 이용하여 요소를 저장한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;LinkedHashSet
&lt;ul&gt;
&lt;li&gt;저장 순서를 유지하는 HashSet&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;TreeSet
&lt;ul&gt;
&lt;li&gt;데이터가 정렬된 상태로 저장되는 이진 탐색 트리(binary search tree)의 형태로 요소를 저장한다.&lt;/li&gt;
&lt;li&gt;이진 탐색 트리 중에 성능을 향상시킨 레드-블랙 트리(Red-Black tree)로 구현되어 있다.&lt;/li&gt;
&lt;li&gt;Compartor 구현으로 정렬 방법을 지정할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;a id=&quot;user-content-java-list-인터페이스-구현체의-종류&quot; href=&quot;https://github.com/WeareSoft/tech-interview/blob/master/contents/java.md#java-list-%EC%9D%B8%ED%84%B0%ED%8E%98%EC%9D%B4%EC%8A%A4-%EA%B5%AC%ED%98%84%EC%B2%B4%EC%9D%98-%EC%A2%85%EB%A5%98&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt;java List 인터페이스 구현체의 종류&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;ArrayList
&lt;ul&gt;
&lt;li&gt;단방향 포인터 구조로 각 데이터에 대한 인덱스를 가지고 있어 데이터 검색에 적합하다.&lt;/li&gt;
&lt;li&gt;데이터의 삽입, 삭제 시 해당 데이터 이후 모든 데이터가 복사되므로 삽입, 삭제가 빈번한 데이터에는 부적합하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;LinkedList
&lt;ul&gt;
&lt;li&gt;양방향 포인터 구조로 데이터의 삽입, 삭제 시 해당 노드의 주소지만 바꾸면 되므로 삽입, 삭제가 빈번한 데이터에 적합하다.&lt;/li&gt;
&lt;li&gt;데이터의 검색 시 처음부터 노드를 순회하므로 검색에는 부적합하다.&lt;/li&gt;
&lt;li&gt;스택, 큐, 양방향 큐 등을 만들기 위한 용도로 쓰인다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Vector
&lt;ul&gt;
&lt;li&gt;내부에서 자동으로 동기화 처리가 일어난다.&lt;/li&gt;
&lt;li&gt;성능이 좋지 않고 무거워 잘 쓰이지 않는다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;a id=&quot;user-content-string-stringbuilder-stringbuffer&quot; href=&quot;https://github.com/WeareSoft/tech-interview/blob/master/contents/java.md#string-stringbuilder-stringbuffer&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt;String StringBuilder StringBuffer&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;String
&lt;ul&gt;
&lt;li&gt;새로운 값을 할당할 때마다 새로 클래스에 대한 객체가 생성된다.&lt;/li&gt;
&lt;li&gt;String에서 저장되는 문자열은 private final char[]의 형태이기 때문에 String 값은 바꿀수 없다.
&lt;ul&gt;
&lt;li&gt;private: 외부에서 접근 불가&lt;/li&gt;
&lt;li&gt;final: 초기값 변경 불가&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;String + String + String...
&lt;ul&gt;
&lt;li&gt;각각의 String 주솟값이 Stack에 쌓이고, Garbage Collector가 호출되기 전까지 생성된 String 객체들은 Heap에 쌓이기 때문에 메모리 관리에 치명적이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;String을 직접 더하는 것보다는 StringBuffer나 StringBuilder를 사용하는 것이 좋다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;StringBuilder, StringBuffer
&lt;ul&gt;
&lt;li&gt;memory에 append하는 방식으로, 클래스에 대한 객체를 직접 생성하지 않는다.&lt;/li&gt;
&lt;li&gt;StringBuilder
&lt;ul&gt;
&lt;li&gt;변경가능한 문자열&lt;/li&gt;
&lt;li&gt;비동기 처리&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;StringBuffer
&lt;ul&gt;
&lt;li&gt;변경가능한 문자열&lt;/li&gt;
&lt;li&gt;동기 처리&lt;/li&gt;
&lt;li&gt;multiple thread 환경에서 안전한 클래스(thread safe)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Java 버전별 String Class 변경 사항
&lt;ul&gt;
&lt;li&gt;JDK 1.5 버전 이전에서는 문자열 연산(+, concat)을 할 때 조합된 문자열을 새로운 메모리에 할당하여 참조해 성능상의 이슈 존재&lt;/li&gt;
&lt;li&gt;JDK 1.5 버전 이후에는 컴파일 단계에서 String 객체를 StringBuilder로 컴파일 되도록 변경됨&lt;/li&gt;
&lt;li&gt;그래서 JDK 1.5 이후 버전에서는 String 클래스를 사용해도 StringBuilder와 성능 차이가 없어짐&lt;/li&gt;
&lt;li&gt;하지만 반복 루프를 사용해서 문자열을 더할 때에는 객체를 계속 새로운 메모리에 할당함&lt;/li&gt;
&lt;li&gt;String 클래스를 사용하는 것 보다는 스레드와 관련이 있으면 StringBuffer, 스레드 안전 여부와 상관이 없으면 StringBuilder를 사용하는 것을 권장&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://12bme.tistory.com/42&quot;&gt;https://12bme.tistory.com/42&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3&gt;&lt;a id=&quot;user-content-java에서-와-equals의-차이&quot; href=&quot;https://github.com/WeareSoft/tech-interview/blob/master/contents/java.md#java%EC%97%90%EC%84%9C-%EC%99%80-equals%EC%9D%98-%EC%B0%A8%EC%9D%B4&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt;java에서 ==와 equals()의 차이&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&quot;==&quot;
&lt;ul&gt;
&lt;li&gt;항등&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;연산자(Operator)&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;이다.
&lt;ul&gt;
&lt;li&gt;&amp;lt;--&amp;gt; !=&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;참조 비교(Reference Comparison)&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;; (주소 비교, Address Comparison)
&lt;ul&gt;
&lt;li&gt;두 객체가 같은 메모리 공간을 가리키는지 확인한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;반환 형태: boolean type
&lt;ul&gt;
&lt;li&gt;같은 주소면 return true, 다른 주소면 return false&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;모든 기본 유형(Primitive Types)에 대해 적용할 수 있다.
&lt;ul&gt;
&lt;li&gt;byte, short, char, int, float, double, boolean&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&quot;equals()&quot;
&lt;ul&gt;
&lt;li&gt;객체 비교&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;메서드(Method)&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;이다.&lt;/li&gt;
&lt;li&gt;&amp;lt;--&amp;gt; !(s1.equals(s2));&lt;/li&gt;
&lt;li&gt;&lt;b&gt;내용 비교(Content Comparison)&lt;/b&gt;
&lt;ul&gt;
&lt;li&gt;두 객체의 값이 같은지 확인한다.&lt;/li&gt;
&lt;li&gt;즉, 문자열의 데이터/내용을 기반으로 비교한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;기본 유형(Primitive Types)에 대해서는 적용할 수 없다.&lt;/li&gt;
&lt;li&gt;반환 형태: boolean type
&lt;ul&gt;
&lt;li&gt;같은 내용이면 return true, 다른 내용이면 return false&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&quot;==&quot; VS &quot;equals()&quot; 예시&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;90%&quot; height=&quot;90%&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/bbJ6Wq/btqJvTbZgQm/ui6n5sNiPDttkkkKxkxsmK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bbJ6Wq/btqJvTbZgQm/ui6n5sNiPDttkkkKxkxsmK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bbJ6Wq/btqJvTbZgQm/ui6n5sNiPDttkkkKxkxsmK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbbJ6Wq%2FbtqJvTbZgQm%2Fui6n5sNiPDttkkkKxkxsmK%2Fimg.png&quot; width=&quot;90%&quot; height=&quot;90%&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;pre id=&quot;code_1600926181630&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class Test {
    public static void main(String[] args) {
        // Thread 객체
        Thread t1 = new Thread();
        Thread t2 = new Thread(); // 새로운 객체 생성. 즉, s1과 다른 객체.
        Thread t3 = t1; // 같은 대상을 가리킨다.
        // String 객체
        String s1 = new String(&quot;WORLD&quot;);
        String s2 = new String(&quot;WORLD&quot;);
        /* --print-- */
        System.out.println(t1 == t3); // true
        System.out.println(t1 == t2); // false(서로 다른 객체이므로 별도의 주소를 갖는다.)
        System.out.println(t1.equals(t2)); // false
        System.out.println(s1.equals(s2)); // true(모두 &quot;WORLD&quot;라는 동일한 내용을 갖는다.)
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://gmlwjd9405.github.io/2018/10/06/java-==-and-equals.html&quot;&gt;https://gmlwjd9405.github.io/2018/10/06/java-==-and-equals.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3&gt;&lt;a id=&quot;user-content-java의-리플렉션-이란&quot; href=&quot;https://github.com/WeareSoft/tech-interview/blob/master/contents/java.md#java%EC%9D%98-%EB%A6%AC%ED%94%8C%EB%A0%89%EC%85%98-%EC%9D%B4%EB%9E%80&quot; aria-hidden=&quot;true&quot;&gt;&lt;/a&gt;java의 리플렉션 이란&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;리플렉션(Reflection) 이란?
&lt;ul&gt;
&lt;li&gt;자바에서 이미 로딩이 완료된 클래스에서 또 다른 클래스를 동적으로 로딩(Dynamic Loading)하여 생성자(Constructor), 멤버 필드(Member Variables) 그리고 멤버 메서드(Member Method) 등을 사용할 수 있는 기법이다.&lt;/li&gt;
&lt;li&gt;클래스의 패키지 정보, 접근 지정자, 수퍼 클래스, 어노테이션(Annotation) 등을 얻을 수 있다.&lt;/li&gt;
&lt;li&gt;컴파일 시간(Compile Time)이 아니라 실행 시간(Run Time)에 동적으로 특정 클래스의 정보를 객체화를 통해 분석 및 추출해낼 수 있는 프로그래밍 기법이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;사용 방법
&lt;ul&gt;
&lt;li&gt;Class.forName(&quot;클래스이름&quot;)&lt;/li&gt;
&lt;li&gt;클래스의 이름으로부터 인스턴스를 생성할 수 있고, 이를 이용하여 클래스의 정보를 가져올 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1600926527019&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class DoHee {
    public String name;
    public int number;
    public void setDoHee (String name, int number) {
      this.name = name;
      this.number = number;
    }
    public void setNumber(int number) {
        this.number = number;
    }
    public void sayHello(String name) {
      System.out.println(&quot;Hello, &quot; + name);
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1600926513499&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.lang.reflect.Method;
import java.lang.reflect.Field;

public class ReflectionTest {
    public void reflectionTest() {
        try {
            Class myClass = Class.forName(&quot;DoHee&quot;);
            Method[] methods = myClass.getDeclaredMethods();

            /* 클래스 내 선언된 메서드의 목록 출력 */
            /* 출력 : public void DoHee.setDoHee(java.lang.String,int)
                     public void DoHee.setNumber(int)
                     public void DoHee.sayHello(java.lang.String) */
            for (Method method : methods) {
                System.out.println(method.toString());
            }

            /* 메서드의 매개변수와 반환 타입 확인 */
            /* 출력 : Class Name : class DoHee
                     Method Name : setDoHee
                     Return Type : void */
            Method method = methods[0];
            System.out.println(&quot;Class Name : &quot; + method.getDeclaringClass());
            System.out.println(&quot;Method Name : &quot; + method.getName());
            System.out.println(&quot;Return Type : &quot; + method.getReturnType());

            /* 출력 : Param Type : class java.lang.String
                     Param Type : int */
            Class[] paramTypes = method.getParameterTypes();
            for(Class paramType : paramTypes) {
                System.out.println(&quot;Param Type : &quot; + paramType);
            }

            /* 메서드 이름으로 호출 */
            Method sayHelloMethod = myClass.getMethod(&quot;sayHello&quot;, String.class);
            sayHelloMethod.invoke(myClass.newInstance(), new String(&quot;DoHee&quot;)); // 출력 : Hello, DoHee

            /* 다른 클래스의 멤버 필드의 값 수정 */
            Field field = myClass.getField(&quot;number&quot;);
            DoHee obj = (DoHee) myClass.newInstance();
            obj.setNumber(5);
            System.out.println(&quot;Before Number : &quot; + field.get(obj)); // 출력 : Before Number : 5
            field.set(obj, 10);
            System.out.println(&quot;After Number : &quot; + field.get(obj)); // 출력 : After Number : 10
        } catch (Exception e) {
            // Exception Handling
        }
    }

    public static void main(String[] args) {
        new ReflectionTest().reflectionTest();
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;왜 사용할까?
&lt;ul&gt;
&lt;li&gt;실행 시간에 다른 클래스를 동적으로 로딩하여 접근할 때&lt;/li&gt;
&lt;li&gt;클래스와 멤버 필드 그리고 메서드 등에 관한 정보를 얻어야할 때&lt;/li&gt;
&lt;li&gt;리플렉션 없이도 완성도 높은 코드를 구현할 수 있지만 사용한다면 조금 더 유연한 코드를 만들 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;주의할 점
&lt;ul&gt;
&lt;li&gt;외부에 공개되지 않는 private 멤버도&lt;span&gt;&amp;nbsp;&lt;/span&gt;Field.setAccessible()&lt;span&gt;&amp;nbsp;&lt;/span&gt;메서드를 true로 지정하면 접근과 조작이 가능하기 때문에 주의해야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://madplay.github.io/post/java-reflection&quot;&gt;https://madplay.github.io/post/java-reflection&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;참고 : &lt;a href=&quot;https://github.com/WeareSoft/tech-interview/blob/master/contents/java.md#java-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D%EC%9D%B4%EB%9E%80&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;github.com/WeareSoft/tech-interview/blob/master/contents/java.md#java-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D%EC%9D%B4%EB%9E%80&lt;/a&gt;&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;동기화와 비동기화의 차이&lt;/p&gt;
&lt;p&gt;객체란 무엇인가? (Object란?)&lt;/p&gt;
&lt;p&gt;Java의 가비지 컬렉션 처리 방법&lt;/p&gt;
&lt;p&gt;객체지향(Object-Oriented)이란?&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Wrapper Class&lt;/p&gt;</description>
      <category>Programming Language/Java</category>
      <author>길순이</author>
      <guid isPermaLink="true">https://osy0907.tistory.com/100</guid>
      <comments>https://osy0907.tistory.com/100#entry100comment</comments>
      <pubDate>Thu, 24 Sep 2020 15:06:14 +0900</pubDate>
    </item>
  </channel>
</rss>