<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>JOO's story</title>
    <link>https://jhjoo.tistory.com/</link>
    <description>기록장</description>
    <language>ko</language>
    <pubDate>Mon, 11 May 2026 03:43:16 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>주토마</managingEditor>
    <image>
      <title>JOO's story</title>
      <url>https://tistory1.daumcdn.net/tistory/6301781/attach/44d045dc440f44258c680fc05578e63f</url>
      <link>https://jhjoo.tistory.com</link>
    </image>
    <item>
      <title>PostgreSQL 시간 관련 함수들</title>
      <link>https://jhjoo.tistory.com/70</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;CURRENT_TIMESTAMP&lt;/code&gt; , &lt;code&gt;LOCALTIMESTAMP&lt;/code&gt; , &lt;code&gt;transaction_timestamp()&lt;/code&gt; , &lt;code&gt;now()&lt;/code&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;transaction 시작된 시각을 반환&lt;/li&gt;
&lt;li&gt;transaction 안에서 여러 번 호출해도 같은 값을 반환&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;statement_timestamp()&lt;/code&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;해당 함수가 포함된 SQL이 실행된 시각을 반환&lt;/li&gt;
&lt;li&gt;같은 transaction 안이라도, 새로운 SQL 문이 실행될 때마다 값이 갱신&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;clock_timestamp()&lt;/code&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;진짜 현재 시각을 반환&lt;/li&gt;
&lt;li&gt;같은 문 안에서도 호출 시마다 값이 달라진다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;샘플 쿼리&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;pgsql&quot;&gt;&lt;code&gt;select 
    CURRENT_TIMESTAMP, 
    LOCALTIMESTAMP, 
    transaction_timestamp(), 
    statement_timestamp(), 
    clock_timestamp(),
    now()
;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;참조&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공식문서 | &lt;a href=&quot;https://www.postgresql.org/docs/17/functions-datetime.html#FUNCTIONS-DATETIME-CURRENT&quot;&gt;https://www.postgresql.org/docs/17/functions-datetime.html#FUNCTIONS-DATETIME-CURRENT&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1752197806273&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;9.9.&amp;nbsp;Date/Time Functions and Operators&quot; data-og-description=&quot;9.9.&amp;nbsp;Date/Time Functions and Operators # 9.9.1. EXTRACT, date_part 9.9.2. date_trunc 9.9.3. date_bin 9.9.4. AT TIME ZONE and AT LOCAL 9.9.5. &amp;hellip;&quot; data-og-host=&quot;www.postgresql.org&quot; data-og-source-url=&quot;https://www.postgresql.org/docs/17/functions-datetime.html#FUNCTIONS-DATETIME-CURRENT&quot; data-og-url=&quot;https://www.postgresql.org/docs/17/functions-datetime.html&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/KEKes/hyZja2I7T0/DGdzrg4Hw8z9shtGU8SdhK/img.png?width=540&amp;amp;height=557&amp;amp;face=0_0_540_557&quot;&gt;&lt;a href=&quot;https://www.postgresql.org/docs/17/functions-datetime.html#FUNCTIONS-DATETIME-CURRENT&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.postgresql.org/docs/17/functions-datetime.html#FUNCTIONS-DATETIME-CURRENT&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/KEKes/hyZja2I7T0/DGdzrg4Hw8z9shtGU8SdhK/img.png?width=540&amp;amp;height=557&amp;amp;face=0_0_540_557');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;9.9.&amp;nbsp;Date/Time Functions and Operators&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;9.9.&amp;nbsp;Date/Time Functions and Operators # 9.9.1. EXTRACT, date_part 9.9.2. date_trunc 9.9.3. date_bin 9.9.4. AT TIME ZONE and AT LOCAL 9.9.5. &amp;hellip;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.postgresql.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Software engineer/DB</category>
      <category>clock_timestamp</category>
      <category>CURRENT_TIMESTAMP</category>
      <category>LOCALTIMESTAMP</category>
      <category>Now</category>
      <category>postgresql</category>
      <category>statement_timestamp</category>
      <category>transaction_timestamp</category>
      <author>주토마</author>
      <guid isPermaLink="true">https://jhjoo.tistory.com/70</guid>
      <comments>https://jhjoo.tistory.com/70#entry70comment</comments>
      <pubDate>Fri, 11 Jul 2025 10:40:49 +0900</pubDate>
    </item>
    <item>
      <title>VSCODE Prettier 적용기</title>
      <link>https://jhjoo.tistory.com/69</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;1. VSCODE Extension 에서 Prettier - code formatter 설치&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;image (2).png&quot; data-origin-width=&quot;681&quot; data-origin-height=&quot;141&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dKSxPZ/btsMrCqWrf5/OFgOQ5TVxY5ECYCUXVRD11/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dKSxPZ/btsMrCqWrf5/OFgOQ5TVxY5ECYCUXVRD11/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dKSxPZ/btsMrCqWrf5/OFgOQ5TVxY5ECYCUXVRD11/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdKSxPZ%2FbtsMrCqWrf5%2FOFgOQ5TVxY5ECYCUXVRD11%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;681&quot; height=&quot;141&quot; data-filename=&quot;image (2).png&quot; data-origin-width=&quot;681&quot; data-origin-height=&quot;141&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. &lt;span style=&quot;letter-spacing: 0px;&quot;&gt;VSCODE 설정 에서 Format on Save 확인&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #eb5757;&quot; data-token-index=&quot;0&quot;&gt;ctrl + ,&lt;/span&gt; : Settings 열기&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;image (1).png&quot; data-origin-width=&quot;718&quot; data-origin-height=&quot;186&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bkBPUe/btsMqctuaSl/B1idTAy0jxtXplKROCKA20/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bkBPUe/btsMqctuaSl/B1idTAy0jxtXplKROCKA20/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bkBPUe/btsMqctuaSl/B1idTAy0jxtXplKROCKA20/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbkBPUe%2FbtsMqctuaSl%2FB1idTAy0jxtXplKROCKA20%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;718&quot; height=&quot;186&quot; data-filename=&quot;image (1).png&quot; data-origin-width=&quot;718&quot; data-origin-height=&quot;186&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. VSCODE 설정 에서 Default Formatter 확인&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;image.png&quot; data-origin-width=&quot;726&quot; data-origin-height=&quot;202&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/drNYvW/btsMpITJVOp/qKLjMV2YCiFtIoC0DnTWok/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/drNYvW/btsMpITJVOp/qKLjMV2YCiFtIoC0DnTWok/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/drNYvW/btsMpITJVOp/qKLjMV2YCiFtIoC0DnTWok/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdrNYvW%2FbtsMpITJVOp%2FqKLjMV2YCiFtIoC0DnTWok%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;726&quot; height=&quot;202&quot; data-filename=&quot;image.png&quot; data-origin-width=&quot;726&quot; data-origin-height=&quot;202&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>Software engineer/Tool</category>
      <category>fomatter</category>
      <category>Prettier</category>
      <category>vsCode</category>
      <author>주토마</author>
      <guid isPermaLink="true">https://jhjoo.tistory.com/69</guid>
      <comments>https://jhjoo.tistory.com/69#entry69comment</comments>
      <pubDate>Fri, 21 Feb 2025 12:58:47 +0900</pubDate>
    </item>
    <item>
      <title>AWS EC2 Free Tier 기반 부하 테스트</title>
      <link>https://jhjoo.tistory.com/68</link>
      <description>&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;토이 프로젝트를 진행하던 중 AWS의 EC2 Free Tier는 과연 어느정도 트래픽을 견딜 수 있을까? 라는 의문에서 시작해서 직접 부하 테스트를 진행하고 그 결과를 정리한 내용입니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;목차&lt;/h2&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;프로젝트 개요&lt;/li&gt;
&lt;li&gt;프로젝트 준비&lt;/li&gt;
&lt;li&gt;프로젝트 수행&lt;/li&gt;
&lt;li&gt;프로젝트 결과&lt;/li&gt;
&lt;li&gt;제언&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;프로젝트 개요&lt;/h2&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;목표:&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;AWS EC2 Free Tier 인스턴스를 활용해 애플리케이션의 최대 안정적인 RPS(초당 처리할 수 있는 요청의 수)를 측정하고, 부하 분산 효과를 확인.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;환경:&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Backend: Java17 + Springboot 3.4&lt;/li&gt;
&lt;li&gt;인프라 구성: EC2 Free Tier 인스턴스 3개 + ALB&lt;/li&gt;
&lt;li&gt;부하 테스트 도구: k6(javascript)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;주요 작업:&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;부하 테스트를 통한 인스턴스 수에 따른 RPS 한계치 분석&lt;/li&gt;
&lt;li&gt;ALB를 통한 분산 처리 효과 확인&lt;/li&gt;
&lt;li&gt;안정적인 RPS와 성능 개선 방안 도출&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;프로젝트 준비&lt;/h2&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Spring boot 애플리케이션 개발&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;평소 서버요청에 대한 응답처리에 걸리는 시간을 구현하기 위해 0~500ms 의 랜덤 지연시간을 생성하고, 해당시간동안 Sleep 이후 응답을 하도록 개발했다.&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;Github | &lt;a href=&quot;https://github.com/dev-jhjoo/TrafficServer&quot;&gt;https://github.com/dev-jhjoo/TrafficServer&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;인프라 구축&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;loadtest.drawio.png&quot; data-origin-width=&quot;661&quot; data-origin-height=&quot;481&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/beujlO/btsK8kl0L0Y/gkQ7DZoLLJHcb5YKP5RLDk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/beujlO/btsK8kl0L0Y/gkQ7DZoLLJHcb5YKP5RLDk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/beujlO/btsK8kl0L0Y/gkQ7DZoLLJHcb5YKP5RLDk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbeujlO%2FbtsK8kl0L0Y%2FgkQ7DZoLLJHcb5YKP5RLDk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;661&quot; height=&quot;481&quot; data-filename=&quot;loadtest.drawio.png&quot; data-origin-width=&quot;661&quot; data-origin-height=&quot;481&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ALB를 통해 인터넷에서 들어오는 요청을 퍼블릭 서브넷 내의 EC2 인스턴스들로 분배합니다. EC2는 모두 Free Tier로 구성했으며, Spring boot 프로젝트를 Docker 이미지로 빌드 후 EC2에 실행하는 방법으로 구현.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간단히 구현한 트래픽 분산 인프라 구조(alb + ec2 free tier * 3)&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;부하 테스트 도구 선정&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Javascript 코드 기반으로 부하 테스트 진행가능한 K6라는 오픈소스를 사용. K6의 경우 Go 언어로 개발된 부하 테스트 오픈소스로서, Grafana Labs에서 제공.&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;Web Page | &lt;a href=&quot;https://k6.io/&quot;&gt;https://k6.io/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;코드저장소:&lt;/li&gt;
&lt;li&gt;Github | &lt;a href=&quot;https://github.com/dev-jhjoo/traffic-monitor&quot;&gt;https://github.com/dev-jhjoo/traffic-monitor&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;프로젝트 수행&lt;/h2&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;인스턴스 증가에 따른 분산환경에서의 처리량 분석&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;테스트 환경:&lt;/li&gt;
&lt;li&gt;{ duration: '1s', target: 1000 }, // 1초 동안 1000명의 사용자 { duration: '1m', target: 10000 }, // 1분 동안 10000명의 사용자&lt;/li&gt;
&lt;li&gt;결과:지표 인스턴스 1개 인스턴스 2개 (ALB 사용) 인스턴스 3개 (ALB 사용) 분석 및 개선 점
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;총 요청 수&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;57,417 (631 RPS)&lt;/td&gt;
&lt;td&gt;95,429 (1,048 RPS)&lt;/td&gt;
&lt;td&gt;120,368 (1,322 RPS)&lt;/td&gt;
&lt;td&gt;처리량이 인스턴스 수에 따라 선형적으로 증가.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;응답 실패율&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;4.04% (2,321 실패)&lt;/td&gt;
&lt;td&gt;6.65% (6,347 실패)&lt;/td&gt;
&lt;td&gt;5.34% (6,428 실패)&lt;/td&gt;
&lt;td&gt;3개 인스턴스에서 실패율 감소 (분산 효과).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;평균 응답 시간&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;5.13초&lt;/td&gt;
&lt;td&gt;1.16초&lt;/td&gt;
&lt;td&gt;655ms&lt;/td&gt;
&lt;td&gt;응답 시간이 크게 개선됨.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;95% 응답 시간&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;8.81초&lt;/td&gt;
&lt;td&gt;2.76초&lt;/td&gt;
&lt;td&gt;1.52초&lt;/td&gt;
&lt;td&gt;응답 시간 분포가 안정적으로 감소.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;최대 응답 시간&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;15.57초&lt;/td&gt;
&lt;td&gt;3.24초&lt;/td&gt;
&lt;td&gt;1.86초&lt;/td&gt;
&lt;td&gt;병목 구간(최대 응답 시간)도 줄어듦.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;데이터 전송량&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;9MB 받음 / 5MB 보냄&lt;/td&gt;
&lt;td&gt;17MB 받음 / 11MB 보냄&lt;/td&gt;
&lt;td&gt;21MB 받음 / 15MB 보냄&lt;/td&gt;
&lt;td&gt;요청 처리량 증가에 따라 데이터 전송량도 증가.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;동시 사용자 (VUs)&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;최대 9,924&lt;/td&gt;
&lt;td&gt;최대 9,906&lt;/td&gt;
&lt;td&gt;최대 9,907&lt;/td&gt;
&lt;td&gt;동시 사용자 수는 테스트 조건에서 동일.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;네트워크 대기 시간&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;2.62ms (최대 3.02초)&lt;/td&gt;
&lt;td&gt;20.81ms (최대 11.03초)&lt;/td&gt;
&lt;td&gt;15.71ms (최대 7.13초)&lt;/td&gt;
&lt;td&gt;네트워크 대기 시간이 3개 인스턴스에서 감소.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;스파이크, 점진적, 지속적 부하에 따른 처리량 분석&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;테스트 환경:
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;{ duration: '10s', target: 1000 }, // 10초 동안 1,000명
{ duration: '30s', target: 5000 }, // 30초 동안 5,000명
{ duration: '10s', target: 0 },    // 10초 동안 사용자 수 감소
&lt;/code&gt;&lt;/pre&gt;
EC2 Free Tier 3대: 점진적 부하EC2 Free Tier 3대: 지속 부하&lt;/li&gt;
&lt;li&gt;{ duration: '5m', target: 1000 }, // 5분 동안 1,000명 유지&lt;/li&gt;
&lt;li&gt;{ duration: '10s', target: 100 }, // 10초 동안 100명 { duration: '20s', target: 500 }, // 20초 동안 500명 { duration: '30s', target: 1000 }, // 30초 동안 1,000명 { duration: '1m', target: 2000 }, // 1분 동안 2,000명 { duration: '1m', target: 3000 }, // 1분 동안 3,000명&lt;/li&gt;
&lt;li&gt;EC2 Free Tier 3대: 스파이크 부하&lt;/li&gt;
&lt;li&gt;결과:지표 스파이크 부하 테스트 점진적 부하 테스트 지속 부하 테스트 분석 및 결론
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;총 요청 수&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;53,504 (697 RPS)&lt;/td&gt;
&lt;td&gt;161,358 (768 RPS)&lt;/td&gt;
&lt;td&gt;100,320 (304 RPS)&lt;/td&gt;
&lt;td&gt;요청 수와 RPS는 부하 패턴에 따라 다름.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;응답 실패율&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;5.65% (3,024 실패)&lt;/td&gt;
&lt;td&gt;1.54% (2,499 실패)&lt;/td&gt;
&lt;td&gt;0.84% (850 실패)&lt;/td&gt;
&lt;td&gt;지속 부하에서 실패율이 가장 낮음.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;평균 응답 시간&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;249.17ms&lt;/td&gt;
&lt;td&gt;257.89ms&lt;/td&gt;
&lt;td&gt;260.05ms&lt;/td&gt;
&lt;td&gt;모든 테스트에서 안정적으로 250ms 근처 유지.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;95% 응답 시간&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;488.48ms&lt;/td&gt;
&lt;td&gt;486.68ms&lt;/td&gt;
&lt;td&gt;486.98ms&lt;/td&gt;
&lt;td&gt;모든 테스트에서 95% 응답 시간 &amp;lt; 500ms.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;최대 응답 시간&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;641.09ms&lt;/td&gt;
&lt;td&gt;656.51ms&lt;/td&gt;
&lt;td&gt;1.19s&lt;/td&gt;
&lt;td&gt;최대 응답 시간은 지속 부하 테스트에서 가장 큼.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;데이터 전송량&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;9.4MB 받음 / 6.4MB 보냄&lt;/td&gt;
&lt;td&gt;30MB 받음 / 20MB 보냄&lt;/td&gt;
&lt;td&gt;19MB 받음 / 13MB 보냄&lt;/td&gt;
&lt;td&gt;점진적 부하 테스트에서 가장 많은 데이터 처리.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;처리된 반복(iterations)&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;53,435&lt;/td&gt;
&lt;td&gt;161,344&lt;/td&gt;
&lt;td&gt;100,319&lt;/td&gt;
&lt;td&gt;반복 횟수는 점진적 부하 테스트에서 가장 많음.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;동시 사용자 (VUs)&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;최대 4,963&lt;/td&gt;
&lt;td&gt;최대 2,997&lt;/td&gt;
&lt;td&gt;최대 999&lt;/td&gt;
&lt;td&gt;부하 패턴에 따라 동시 사용자가 달라짐.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;프로젝트 결과&lt;/b&gt;&lt;/h2&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;인스턴스 증가에 따른 분산환경에서의 처리 결과&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;처리량:&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;인스턴스 1개에서 2개로 증설됨에 따라 요청 처리량이 약 1.66배 증가 (631 RPS &amp;rarr; 1,048 RPS). 인스턴스 2개에서 3개로 증설될때는 요청 처리량이 약 1.26배 증가 (1,048 RPS &amp;rarr; 1,322 RPS). 이를 통해 인스턴스 수에 따라 처리량이 선형적으로 증가하며, 분산 처리의 효과를 확인할 수 있었다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;응답 시간:&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;평균 응답 시간이 인스턴스가 늘어남에 따라 5.13초, 1.16초, 655ms로 안정적으로 감소하는 모습을 확인했다. 클라이언트 요청에 대해 분산처리의 효과를 직접적으로 확인 했다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;스파이크, 점진적, 지속적 부하에 따른 처리 결과&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테스트 유형 최대 RPS 평균 응답 시간 95% 응답 시간 실패율 최대 안정 RPS&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;스파이크 부하&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;697&lt;/td&gt;
&lt;td&gt;249ms&lt;/td&gt;
&lt;td&gt;488ms&lt;/td&gt;
&lt;td&gt;5.65%&lt;/td&gt;
&lt;td&gt;약 600 RPS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;점진적 부하&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;768&lt;/td&gt;
&lt;td&gt;257ms&lt;/td&gt;
&lt;td&gt;486ms&lt;/td&gt;
&lt;td&gt;1.54%&lt;/td&gt;
&lt;td&gt;약 750 RPS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;지속 부하&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;304&lt;/td&gt;
&lt;td&gt;260ms&lt;/td&gt;
&lt;td&gt;486ms&lt;/td&gt;
&lt;td&gt;0.84%&lt;/td&gt;
&lt;td&gt;약 300~350 RPS&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;스파이크 부하: &lt;/b&gt;순간적인 트래픽 급증에 비교적 잘 대응했지만, 실패율이 높아졌다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;점진적 부하: &lt;/b&gt;동시 사용자 수와 요청이 점진적으로 증가했을 때 서버가 안정적으로 대응했다. 또한 실패율이 1.54%로 애초 생각했던 1%에 약간 미달하는 성능을 보였다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;지속적 부하: &lt;/b&gt;장시간 일정한 부하에 대해서 실패율이 가장 낮았지만, 안정적으로 처리가능한 RPS도 낮았다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Free Tier 3개와 ALB로 구성된 환경에서 최대 안정 RPS&lt;/b&gt;: 600~750 RPS는 단기 부하에서 안정적으로 처리 가능하고, 300~350 RPS는 장기적인 안정성을 유지하며 처리 가능하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;제언&lt;/h2&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 프로젝트를 통해 AWS EC2 Free Tier 인스턴스 3대와 ALB를 활용하여 분산처리에 다른 처리량 변화와 안정적인 RPS 수치를 확인했습니다. 이를 바탕으로 다음과 같이 제언합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;적정 RPS 활용 방안:&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;Free Tier 3대와 ALB 환경에서는 &lt;b&gt;600~750 RPS&lt;/b&gt;가 단기 부하에서 안정적으로 처리 가능하며, 장기적인 안정성을 고려할 경우 &lt;b&gt;300~350 RPS&lt;/b&gt;로 운영하는 것이 적합 합니다.&lt;/li&gt;
&lt;li&gt;트래픽 패턴이 일정하거나 예상 가능하다면, Auto Scaling 대신 정적으로 3개 인스턴스를 유지하여 비용 효율적인 운영이 가능합니다.&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;b&gt;인프라 업그레이드:&lt;/b&gt; EC2 Free Tier에서 T3.medium 이상의 인스턴스로 업그레이드 시 처리량이 2배 이상 증가할 것으로 예상되며, 기회가 된다면 검증하는 프로젝트를 진행해 보고 싶습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;캐싱 및 비동기 처리:&lt;/b&gt; Redis와 같은 캐싱 솔루션 도입과 비동기 처리 방식을 적용하면 응답 시간을 더욱 줄일 수 있을 것으로 사료됩니다.&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;k6 스크립트를 &lt;b&gt;CI/CD 파이프라인에 통합&lt;/b&gt;하여 코드 변경 시마다 성능을 &lt;b&gt;자동으로 검증&lt;/b&gt;하는 방식을 도입하는 방식도 고려해볼 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Software engineer/Infra</category>
      <author>주토마</author>
      <guid isPermaLink="true">https://jhjoo.tistory.com/68</guid>
      <comments>https://jhjoo.tistory.com/68#entry68comment</comments>
      <pubDate>Fri, 6 Dec 2024 11:45:47 +0900</pubDate>
    </item>
    <item>
      <title>ChatGPT로 Java 공부하기 #3 자바 컬렉션 프레임워크와 주요 클래스</title>
      <link>https://jhjoo.tistory.com/67</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Java thumnail.webp&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bmcMxl/btsKPeSQ6Zd/tbJyKypkJqImKtRlbob1Q0/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bmcMxl/btsKPeSQ6Zd/tbJyKypkJqImKtRlbob1Q0/img.webp&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bmcMxl/btsKPeSQ6Zd/tbJyKypkJqImKtRlbob1Q0/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbmcMxl%2FbtsKPeSQ6Zd%2FtbJyKypkJqImKtRlbob1Q0%2Fimg.webp&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1024&quot; height=&quot;1024&quot; data-filename=&quot;Java thumnail.webp&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;자바 컬렉션 프레임워크와 주요 클래스&lt;/b&gt;&lt;/h3&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. 자바 컬렉션 프레임워크란?&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;정의&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바 컬렉션 프레임워크(Java Collections Framework, JCF)는 데이터를 효율적으로 저장하고 관리하기 위해 제공되는 클래스와 인터페이스의 집합입니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;주요 특징&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;데이터 구조 구현&lt;/b&gt;: 리스트, 스택, 큐, 집합 등 다양한 자료구조 제공&lt;/li&gt;
&lt;li&gt;&lt;b&gt;표준화&lt;/b&gt;: 일관된 API를 제공&lt;/li&gt;
&lt;li&gt;&lt;b&gt;유연성&lt;/b&gt;: 다양한 데이터 타입과 크기를 동적으로 처리 가능&lt;/li&gt;
&lt;li&gt;&lt;b&gt;알고리즘 제공&lt;/b&gt;: 정렬, 검색, 순회 등 기본적인 알고리즘 내장&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. 주요 인터페이스와 클래스&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2.1 주요 인터페이스&lt;/b&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;List&lt;/b&gt;: 순서가 있는 데이터의 집합 (중복 허용)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;주요 구현 클래스: ArrayList, LinkedList&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Set&lt;/b&gt;: 중복을 허용하지 않는 데이터의 집합
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;주요 구현 클래스: HashSet, TreeSet&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Queue&lt;/b&gt;: FIFO(First In First Out) 구조의 데이터 집합
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;주요 구현 클래스: PriorityQueue, LinkedList&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Map&lt;/b&gt;: 키-값 쌍으로 데이터를 저장 (키는 중복 불가)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;주요 구현 클래스: HashMap, TreeMap&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2.2 주요 클래스&lt;/b&gt;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2.2.1 ArrayList&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배열 기반의 리스트로, 크기를 동적으로 조정 가능하며 순차적인 데이터 접근에 최적화되어 있습니다.&lt;/p&gt;
&lt;pre class=&quot;arduino&quot;&gt;&lt;code&gt;import java.util.ArrayList;

public class ArrayListExample {
    public static void main(String[] args) {
        ArrayList&amp;lt;String&amp;gt; names = new ArrayList&amp;lt;&amp;gt;();
        names.add(&quot;Alice&quot;);
        names.add(&quot;Bob&quot;);
        names.add(&quot;Charlie&quot;);

        // 데이터 출력
        for (String name : names) {
            System.out.println(name);
        }

        // 특정 인덱스의 데이터 접근
        System.out.println(&quot;첫 번째 이름: &quot; + names.get(0));

        // 데이터 제거
        names.remove(&quot;Bob&quot;);
        System.out.println(&quot;Bob 제거 후: &quot; + names);
    }
}

&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2.2.2 HashSet&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;중복을 허용하지 않으며 순서가 없는 데이터 구조입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내부적으로 HashMap을 사용하여 빠른 검색과 삽입을 지원합니다.&lt;/p&gt;
&lt;pre class=&quot;cs&quot;&gt;&lt;code&gt;import java.util.HashSet;

public class HashSetExample {
    public static void main(String[] args) {
        HashSet&amp;lt;Integer&amp;gt; numbers = new HashSet&amp;lt;&amp;gt;();
        numbers.add(1);
        numbers.add(2);
        numbers.add(2); // 중복된 값은 무시

        // 데이터 출력
        for (int number : numbers) {
            System.out.println(number);
        }
    }
}

&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2.2.3 HashMap&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;키-값 쌍으로 데이터를 저장하며, 키의 중복을 허용하지 않습니다.&lt;/p&gt;
&lt;pre class=&quot;arduino&quot;&gt;&lt;code&gt;import java.util.HashMap;

public class HashMapExample {
    public static void main(String[] args) {
        HashMap&amp;lt;String, String&amp;gt; capitals = new HashMap&amp;lt;&amp;gt;();
        capitals.put(&quot;USA&quot;, &quot;Washington&quot;);
        capitals.put(&quot;France&quot;, &quot;Paris&quot;);
        capitals.put(&quot;Korea&quot;, &quot;Seoul&quot;);

        // 데이터 출력
        for (String country : capitals.keySet()) {
            System.out.println(country + &quot;의 수도는 &quot; + capitals.get(country));
        }
    }
}

&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2.2.4 PriorityQueue&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선순위에 따라 데이터를 정렬하며, 기본적으로 최소값이 가장 먼저 출력됩니다.&lt;/p&gt;
&lt;pre class=&quot;arduino&quot;&gt;&lt;code&gt;import java.util.PriorityQueue;

public class PriorityQueueExample {
    public static void main(String[] args) {
        PriorityQueue&amp;lt;Integer&amp;gt; queue = new PriorityQueue&amp;lt;&amp;gt;();
        queue.add(10);
        queue.add(5);
        queue.add(20);

        // 데이터 출력 (오름차순)
        while (!queue.isEmpty()) {
            System.out.println(queue.poll()); // 가장 작은 값부터 제거
        }
    }
}

&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. 실무 적용 예제: 학생 관리 시스템&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;요구사항&lt;/b&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;학생의 이름과 점수를 저장&lt;/li&gt;
&lt;li&gt;점수를 기준으로 정렬&lt;/li&gt;
&lt;li&gt;특정 점수 이상의 학생 목록 출력&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;코드 구현&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;arduino&quot;&gt;&lt;code&gt;import java.util.*;

class Student {
    String name;
    int score;

    public Student(String name, int score) {
        this.name = name;
        this.score = score;
    }

    @Override
    public String toString() {
        return name + &quot;: &quot; + score;
    }
}

public class StudentManagement {
    public static void main(String[] args) {
        // 학생 데이터 저장
        List&amp;lt;Student&amp;gt; students = new ArrayList&amp;lt;&amp;gt;();
        students.add(new Student(&quot;Alice&quot;, 85));
        students.add(new Student(&quot;Bob&quot;, 90));
        students.add(new Student(&quot;Charlie&quot;, 70));

        // 점수 기준으로 정렬
        students.sort(Comparator.comparingInt(s -&amp;gt; s.score));
        System.out.println(&quot;정렬된 학생 목록:&quot;);
        for (Student student : students) {
            System.out.println(student);
        }

        // 특정 점수 이상의 학생 출력 (Stream API 활용)
        int threshold = 80;
        System.out.println(&quot;\\n점수가 &quot; + threshold + &quot; 이상인 학생:&quot;);
        students.stream()
				        // 조건에 맞는 학생 필터링
                .filter(student -&amp;gt; student.score &amp;gt;= threshold) 
                // 각 학생 출력
                .forEach(System.out::println);                 
    }
}

&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>ChatGPT로 공부하기/Java</category>
      <author>주토마</author>
      <guid isPermaLink="true">https://jhjoo.tistory.com/67</guid>
      <comments>https://jhjoo.tistory.com/67#entry67comment</comments>
      <pubDate>Tue, 19 Nov 2024 17:25:01 +0900</pubDate>
    </item>
    <item>
      <title>ChatGPT로 Java 공부하기 #2 자바의 예외 처리와 실전 예제</title>
      <link>https://jhjoo.tistory.com/66</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Java thumnail.webp&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bLsmyX/btsKO6tZdTx/kbk2XhvKuAMY9m52KAEFSk/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bLsmyX/btsKO6tZdTx/kbk2XhvKuAMY9m52KAEFSk/img.webp&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bLsmyX/btsKO6tZdTx/kbk2XhvKuAMY9m52KAEFSk/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbLsmyX%2FbtsKO6tZdTx%2Fkbk2XhvKuAMY9m52KAEFSk%2Fimg.webp&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1024&quot; height=&quot;1024&quot; data-filename=&quot;Java thumnail.webp&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;자바의 예외 처리와 실전 예제&lt;/b&gt;&lt;/h3&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. 자바의 예외 처리란?&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;예외(Exception)란?&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;정의&lt;/b&gt;: 프로그램 실행 중에 발생하는 비정상적인 상황&lt;/li&gt;
&lt;li&gt;&lt;b&gt;종류&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Checked Exception&lt;/b&gt;: 컴파일 시점에 반드시 처리해야 하는 예외 (예: IOException, SQLException)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Unchecked Exception&lt;/b&gt;: 런타임 시 발생하는 예외 (예: NullPointerException, ArrayIndexOutOfBoundsException)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;자바의 예외 처리 방법&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바는 예외 처리를 위해 try-catch-finally 블록을 제공합니다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. 예외 처리 기본 문법&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2.1 try-catch 블록&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예외가 발생할 수 있는 코드를 try 블록에 작성하고, 발생한 예외를 catch 블록에서 처리합니다.&lt;/p&gt;
&lt;pre class=&quot;arduino&quot;&gt;&lt;code&gt;public class ExceptionExample {
    public static void main(String[] args) {
        try {
            int result = 10 / 0; // ArithmeticException 발생
        } catch (ArithmeticException e) {
            System.out.println(&quot;예외 발생: &quot; + e.getMessage());
        }
    }
}

&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2.2 finally 블록&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;finally 블록은 예외 발생 여부와 상관없이 항상 실행됩니다.&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;public class FinallyExample {
    public static void main(String[] args) {
        try {
            int[] numbers = {1, 2, 3};
            System.out.println(numbers[5]); // ArrayIndexOutOfBoundsException 발생
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println(&quot;예외 발생: &quot; + e.getMessage());
        } finally {
            System.out.println(&quot;이 블록은 항상 실행됩니다.&quot;);
        }
    }
}

&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2.3 throw와 throws&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;throw&lt;/b&gt;: 예외를 직접 발생시킬 때 사용&lt;/li&gt;
&lt;li&gt;&lt;b&gt;throws&lt;/b&gt;: 메서드가 예외를 던질 가능성을 명시&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;arduino&quot;&gt;&lt;code&gt;public class ThrowThrowsExample {
    public static void main(String[] args) {
        try {
            validateAge(15);
        } catch (IllegalArgumentException e) {
            System.out.println(&quot;예외 처리: &quot; + e.getMessage());
        }
    }

    public static void validateAge(int age) throws IllegalArgumentException {
        if (age &amp;lt; 18) {
            throw new IllegalArgumentException(&quot;나이는 18 이상이어야 합니다.&quot;);
        }
    }
}

&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. 실무 적용 예제&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;요구사항&lt;/b&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;사용자 입력에서 숫자가 아닌 값을 입력하면 프로그램이 종료되지 않고 적절한 메시지를 출력해야 함.&lt;/li&gt;
&lt;li&gt;데이터베이스 연결 시, 실패할 경우 사용자에게 연결 실패 메시지를 출력.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3.1 사용자 입력 예외 처리&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;arduino&quot;&gt;&lt;code&gt;import java.util.Scanner;

public class InputValidation {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int number = 0;

        while (true) {
            System.out.print(&quot;숫자를 입력하세요: &quot;);
            try {
                number = Integer.parseInt(scanner.nextLine()); // 숫자 변환 시도
                break; // 성공하면 반복문 종료
            } catch (NumberFormatException e) {
                System.out.println(&quot;유효하지 않은 입력입니다. 숫자를 입력해주세요.&quot;);
            }
        }

        System.out.println(&quot;입력된 숫자: &quot; + number);
        scanner.close();
    }
}

&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3.2 데이터베이스 연결 예외 처리&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;pgsql&quot;&gt;&lt;code&gt;import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class DatabaseConnection {
    public static void main(String[] args) {
        String url = &quot;jdbc:mysql://localhost:3306/mydb&quot;;
        String user = &quot;root&quot;;
        String password = &quot;password&quot;;

        Connection connection = null;
        try {
            // 데이터베이스 연결 시도
            connection = DriverManager.getConnection(url, user, password);
            System.out.println(&quot;데이터베이스 연결 성공!&quot;);
        } catch (SQLException e) {
            System.out.println(&quot;데이터베이스 연결 실패: &quot; + e.getMessage());
        } finally {
            // 연결 종료
            if (connection != null) {
                try {
                    connection.close();
                    System.out.println(&quot;연결이 종료되었습니다.&quot;);
                } catch (SQLException e) {
                    System.out.println(&quot;연결 종료 중 예외 발생: &quot; + e.getMessage());
                }
            }
        }
    }
}

&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4. 사용자 정의 예외&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실무에서는 특정 비즈니스 로직에 대한 예외를 사용자 정의 예외로 처리할 수 있습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;예제: 주문 금액이 0 이하일 때 예외 발생&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;arduino&quot;&gt;&lt;code&gt;class InvalidOrderAmountException extends Exception {
    public InvalidOrderAmountException(String message) {
        super(message);
    }
}

public class CustomExceptionExample {
    public static void main(String[] args) {
        try {
            processOrder(-500);
        } catch (InvalidOrderAmountException e) {
            System.out.println(&quot;예외 처리: &quot; + e.getMessage());
        }
    }

    public static void processOrder(int amount) throws InvalidOrderAmountException {
        if (amount &amp;lt;= 0) {
            throw new InvalidOrderAmountException(&quot;주문 금액은 0보다 커야 합니다.&quot;);
        }
        System.out.println(&quot;주문 처리 완료: &quot; + amount + &quot;원&quot;);
    }
}

&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>ChatGPT로 공부하기/Java</category>
      <author>주토마</author>
      <guid isPermaLink="true">https://jhjoo.tistory.com/66</guid>
      <comments>https://jhjoo.tistory.com/66#entry66comment</comments>
      <pubDate>Tue, 19 Nov 2024 17:24:25 +0900</pubDate>
    </item>
    <item>
      <title>ChatGPT로 Java 공부하기 #1 자바의 기본 문법 및 객체 지향 개념 정리</title>
      <link>https://jhjoo.tistory.com/65</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Java thumnail.webp&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Iap7b/btsKPDSnK1K/TOhrwrIVWwF226MK4LjFmK/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Iap7b/btsKPDSnK1K/TOhrwrIVWwF226MK4LjFmK/img.webp&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Iap7b/btsKPDSnK1K/TOhrwrIVWwF226MK4LjFmK/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIap7b%2FbtsKPDSnK1K%2FTOhrwrIVWwF226MK4LjFmK%2Fimg.webp&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1024&quot; height=&quot;1024&quot; data-filename=&quot;Java thumnail.webp&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. 자바 기본 문법&lt;/b&gt;&lt;/h2&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;자바의 주요 특징&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;플랫폼 독립성&lt;/b&gt;: JVM(Java Virtual Machine) 덕분에 다양한 운영체제에서 실행 가능&lt;/li&gt;
&lt;li&gt;&lt;b&gt;객체 지향 언어&lt;/b&gt;: 코드의 재사용성과 유지보수성이 뛰어남&lt;/li&gt;
&lt;li&gt;&lt;b&gt;강타입 언어&lt;/b&gt;: 데이터 타입을 엄격히 준수&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1.1 기본 문법&lt;/b&gt;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;변수와 데이터 타입&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;변수는 데이터를 저장하기 위해 메모리에 이름을 붙이는 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바는 기본적으로 두 가지 타입의 데이터를 사용합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;기본형(Primitive types)&lt;/b&gt;: int, double, boolean, char 등&lt;/li&gt;
&lt;li&gt;&lt;b&gt;참조형(Reference types)&lt;/b&gt;: 클래스, 배열, 인터페이스 등&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;arduino&quot;&gt;&lt;code&gt;public class BasicSyntax {
    public static void main(String[] args) {
        // 기본형 변수 선언 및 초기화
        int age = 30;
        double height = 175.5;
        boolean isAdult = true;
        char grade = 'A';

        // 출력
        System.out.println(&quot;Age: &quot; + age);
        System.out.println(&quot;Height: &quot; + height);
        System.out.println(&quot;Is Adult: &quot; + isAdult);
        System.out.println(&quot;Grade: &quot; + grade);
    }
}

&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;제어문&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바는 if, for, while, switch 같은 제어문으로 코드의 흐름을 제어합니다.&lt;/p&gt;
&lt;pre class=&quot;gradle&quot;&gt;&lt;code&gt;public class ControlStatements {
    public static void main(String[] args) {
        int score = 85;

        // if-else 조건문
        if (score &amp;gt;= 90) {
            System.out.println(&quot;Grade: A&quot;);
        } else if (score &amp;gt;= 80) {
            System.out.println(&quot;Grade: B&quot;);
        } else {
            System.out.println(&quot;Grade: C&quot;);
        }

        // for 반복문
        for (int i = 0; i &amp;lt; 5; i++) {
            System.out.println(&quot;Iteration: &quot; + i);
        }

        // while 반복문
        int count = 0;
        while (count &amp;lt; 3) {
            System.out.println(&quot;Count: &quot; + count);
            count++;
        }
    }
}

&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. 객체 지향 프로그래밍 (OOP)&lt;/b&gt;&lt;/h2&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;OOP의 주요 특징&lt;/b&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;캡슐화(Encapsulation)&lt;/b&gt;: 데이터를 외부로부터 보호하고, 메서드를 통해 접근&lt;/li&gt;
&lt;li&gt;&lt;b&gt;상속(Inheritance)&lt;/b&gt;: 기존 클래스의 기능을 확장&lt;/li&gt;
&lt;li&gt;&lt;b&gt;다형성(Polymorphism)&lt;/b&gt;: 하나의 메서드나 객체가 여러 형태를 가질 수 있음&lt;/li&gt;
&lt;li&gt;&lt;b&gt;추상화(Abstraction)&lt;/b&gt;: 불필요한 세부 사항을 숨기고 중요한 것에 집중&lt;/li&gt;
&lt;/ol&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2.1 클래스와 객체&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클래스는 객체를 생성하기 위한 설계도입니다. 객체는 클래스에서 생성된 실체입니다.&lt;/p&gt;
&lt;pre class=&quot;arduino&quot;&gt;&lt;code&gt;public class Person {
    // 필드
    String name;
    int age;

    // 생성자
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // 메서드
    public void introduce() {
        System.out.println(&quot;Hello, my name is &quot; + name + &quot; and I am &quot; + age + &quot; years old.&quot;);
    }

    // 메인 메서드
    public static void main(String[] args) {
        // 객체 생성
        Person person = new Person(&quot;Alice&quot;, 25);
        person.introduce();
    }
}

&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2.2 상속과 다형성&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;상속은 코드 재사용성을 높여주고, 다형성은 유연한 코드 작성을 가능하게 합니다.&lt;/p&gt;
&lt;pre class=&quot;arduino&quot;&gt;&lt;code&gt;// 부모 클래스
class Animal {
    public void makeSound() {
        System.out.println(&quot;Some generic sound&quot;);
    }
}

// 자식 클래스
class Dog extends Animal {
    @Override
    public void makeSound() {
        System.out.println(&quot;Woof woof&quot;);
    }
}

public class PolymorphismExample {
    public static void main(String[] args) {
        Animal myAnimal = new Animal();
        Animal myDog = new Dog();

        myAnimal.makeSound(); // Some generic sound
        myDog.makeSound();    // Woof woof
    }
}

&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. 실무 적용 예제: 주문 관리 시스템&lt;/b&gt;&lt;/h2&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간단한 주문 관리를 위한 객체 지향 설계 예제입니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;요구사항&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;고객은 상품을 주문할 수 있다.&lt;/li&gt;
&lt;li&gt;주문 정보에는 고객 정보와 상품 정보가 포함된다.&lt;/li&gt;
&lt;li&gt;주문 정보를 출력하는 기능이 필요하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;코드 구현&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;arduino&quot;&gt;&lt;code&gt;// 상품 클래스
class Product {
    String name;
    double price;

    public Product(String name, double price) {
        this.name = name;
        this.price = price;
    }
}

// 고객 클래스
class Customer {
    String name;
    String email;

    public Customer(String name, String email) {
        this.name = name;
        this.email = email;
    }
}

// 주문 클래스
class Order {
    Customer customer;
    Product product;

    public Order(Customer customer, Product product) {
        this.customer = customer;
        this.product = product;
    }

    public void printOrderDetails() {
        System.out.println(&quot;Customer: &quot; + customer.name + &quot;, Email: &quot; + customer.email);
        System.out.println(&quot;Product: &quot; + product.name + &quot;, Price: &quot; + product.price);
    }
}

// 메인 클래스
public class OrderManagement {
    public static void main(String[] args) {
        // 객체 생성
        Customer customer = new Customer(&quot;Bob&quot;, &quot;bob@example.com&quot;);
        Product product = new Product(&quot;Laptop&quot;, 1200.99);

        // 주문 생성 및 출력
        Order order = new Order(customer, product);
        order.printOrderDetails();
    }
}

&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>ChatGPT로 공부하기/Java</category>
      <author>주토마</author>
      <guid isPermaLink="true">https://jhjoo.tistory.com/65</guid>
      <comments>https://jhjoo.tistory.com/65#entry65comment</comments>
      <pubDate>Tue, 19 Nov 2024 17:23:34 +0900</pubDate>
    </item>
    <item>
      <title>ChatGPT로 데이터 분석 공부하기 #16 퍼널 분석</title>
      <link>https://jhjoo.tistory.com/64</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;DALL&amp;amp;middot;E 2024-11-03 21.18.20.webp&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cWfI7E/btsKNwfyVdQ/R8KWZAtAcFlg8L1LCdbfE0/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cWfI7E/btsKNwfyVdQ/R8KWZAtAcFlg8L1LCdbfE0/img.webp&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cWfI7E/btsKNwfyVdQ/R8KWZAtAcFlg8L1LCdbfE0/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcWfI7E%2FbtsKNwfyVdQ%2FR8KWZAtAcFlg8L1LCdbfE0%2Fimg.webp&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1024&quot; height=&quot;1024&quot; data-filename=&quot;DALL&amp;middot;E 2024-11-03 21.18.20.webp&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;퍼널 분석(Funnel Analysis)란?&lt;/b&gt;&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;퍼널 분석은 사용자가 특정 목표(예: 구매, 회원가입)를 달성하기까지의 &lt;b&gt;단계별 행동&lt;/b&gt;을 분석하는 방법입니다. 사용자가 각 단계에서 얼마나 이탈하는지(전환율)를 파악하여 &lt;b&gt;개선이 필요한 지점&lt;/b&gt;을 식별하는 데 유용합니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. 퍼널 분석의 개념&lt;/b&gt;&lt;/h2&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;퍼널(Funnel) 구조&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;퍼널은 &lt;b&gt;깔때기&lt;/b&gt;처럼 사용자가 단계를 진행할수록 점점 줄어드는 구조를 나타냅니다.&lt;/li&gt;
&lt;li&gt;각 단계에서 사용자 수를 측정하여 이탈률과 전환율을 계산합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;예제: 이커머스 사이트&lt;/b&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;방문(Visit)&lt;/b&gt;: 사용자가 웹사이트에 방문.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;상품 보기(View Product)&lt;/b&gt;: 상품 페이지를 열람.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;장바구니 담기(Add to Cart)&lt;/b&gt;: 상품을 장바구니에 추가.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;결제 시작(Begin Checkout)&lt;/b&gt;: 결제 프로세스 시작.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;구매 완료(Purchase)&lt;/b&gt;: 결제 완료.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. 퍼널 분석의 목적&lt;/b&gt;&lt;/h2&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;이탈 분석&lt;/b&gt;: 사용자가 어느 단계에서 이탈하는지 파악.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;전환율 최적화&lt;/b&gt;: 단계별 전환율을 높여 목표 달성률을 개선.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;UX 개선&lt;/b&gt;: 특정 단계에서의 사용자 경험을 개선.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. 퍼널 분석의 주요 지표&lt;/b&gt;&lt;/h2&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;이탈률(Drop-off Rate)&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;특정 단계에서 이탈한 사용자 비율.&lt;/li&gt;
&lt;li&gt;$\text{이탈률} = \frac{\text{이전 단계 사용자 수} - \text{현재 단계 사용자 수}}{\text{이전 단계 사용자 수}} \times 100$&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;전환율(Conversion Rate)&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;특정 단계를 완료한 사용자 비율.&lt;/li&gt;
&lt;li&gt;$\text{전환율} = \frac{\text{현재 단계 사용자 수}}{\text{이전 단계 사용자 수}} \times 100$&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;전체 전환율(Total Conversion Rate)&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;첫 단계부터 마지막 단계까지의 전환율.&lt;/li&gt;
&lt;li&gt;$\text{전체 전환율} = \frac{\text{최종 단계 사용자 수}}{\text{첫 단계 사용자 수}} \times 100$&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4. 퍼널 분석 과정&lt;/b&gt;&lt;/h2&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;(1) 목표 설정&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;분석 목표를 정의.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;예: &quot;구매 전환율을 분석하고 개선점을 찾는다.&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;(2) 단계 정의&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;사용자가 목표를 달성하기까지의 주요 단계를 식별.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;예: 방문 &amp;rarr; 상품 보기 &amp;rarr; 장바구니 담기 &amp;rarr; 결제 시작 &amp;rarr; 구매 완료.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;(3) 데이터 수집&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;웹 로그, 애널리틱스 도구(GA4, Amplitude 등)에서 사용자 행동 데이터를 수집.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;예: 이벤트 데이터(페이지뷰, 버튼 클릭 등).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;(4) 데이터 처리&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;단계별 사용자 수 집계 및 전환율/이탈률 계산.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;5. Python을 활용한 퍼널 분석&lt;/b&gt;&lt;/h2&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;(1) 샘플 데이터&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;haskell&quot;&gt;&lt;code&gt;import pandas as pd

# 가상의 퍼널 단계 데이터
data = {
    &quot;Stage&quot;: [&quot;Visit&quot;, &quot;View Product&quot;, &quot;Add to Cart&quot;, &quot;Begin Checkout&quot;, &quot;Purchase&quot;],
    &quot;Users&quot;: [1000, 800, 500, 300, 200]
}

df = pd.DataFrame(data)
print(df)
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출력:&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;           Stage  Users
0          Visit   1000
1   View Product    800
2    Add to Cart    500
3  Begin Checkout    300
4       Purchase    200
&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;(2) 이탈률 및 전환율 계산&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;lsl&quot;&gt;&lt;code&gt;# 단계별 이탈률 계산
df[&quot;Drop-off Rate (%)&quot;] = df[&quot;Users&quot;].diff(-1).fillna(0) / df[&quot;Users&quot;] * 100

# 단계별 전환율 계산
df[&quot;Conversion Rate (%)&quot;] = df[&quot;Users&quot;].pct_change(-1).fillna(0) * 100

# 전체 전환율 계산
total_conversion_rate = df[&quot;Users&quot;].iloc[-1] / df[&quot;Users&quot;].iloc[0] * 100

print(df)
print(f&quot;전체 전환율: {total_conversion_rate:.2f}%&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출력:&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;           Stage  Users  Drop-off Rate (%)  Conversion Rate (%)
0          Visit   1000              20.00               20.00
1   View Product    800              37.50               37.50
2    Add to Cart    500              40.00               40.00
3  Begin Checkout    300              33.33               33.33
4       Purchase    200               0.00                0.00

전체 전환율: 20.00%
&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;(3) 시각화&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;import matplotlib.pyplot as plt

# 퍼널 시각화
plt.figure(figsize=(8, 6))
plt.bar(df[&quot;Stage&quot;], df[&quot;Users&quot;], color='skyblue')
plt.title(&quot;Funnel Analysis&quot;, fontsize=16)
plt.xlabel(&quot;Stage&quot;, fontsize=12)
plt.ylabel(&quot;Number of Users&quot;, fontsize=12)
plt.show()
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;6. 퍼널 분석 결과 활용&lt;/b&gt;&lt;/h2&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;(1) 이탈률이 높은 단계&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;문제 식별&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;특정 단계에서 이탈률이 높다면, 해당 단계의 UX, 프로세스를 개선.&lt;/li&gt;
&lt;li&gt;예: &quot;장바구니에 담기 &amp;rarr; 결제 시작&quot; 단계에서 이탈률이 높다면 결제 과정 간소화 필요.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;(2) 전환율 최적화&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;전환율 증가 전략&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;단계별 사용자 경험 최적화.&lt;/li&gt;
&lt;li&gt;A/B 테스트를 통해 최적의 옵션 선택.&lt;/li&gt;
&lt;li&gt;마케팅 메시지, 할인 코드 제공 등.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;7. 퍼널 분석 도구&lt;/b&gt;&lt;/h2&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;Google Analytics(GA4)&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;사용자 행동 추적, 전환율 분석.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Amplitude&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;세분화된 사용자 행동 분석 및 퍼널 추적.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Mixpanel&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;실시간 퍼널 분석 및 사용자 세그먼트 기능 제공.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Tableau/Power BI&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;시각화를 통한 퍼널 분석 데이터 표현.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;8. 퍼널 분석의 장단점&lt;/b&gt;&lt;/h2&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;장점&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;이탈 원인 파악&lt;/b&gt;: 사용자 흐름을 시각적으로 이해.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;전환율 최적화&lt;/b&gt;: 단계별 데이터를 기반으로 최적의 개선안 도출.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;데이터 기반 의사결정&lt;/b&gt;: 데이터에 기반한 명확한 개선 방향 제공.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;단점&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;복잡한 데이터 처리&lt;/b&gt;: 로그 데이터 수집, 처리 과정에서 기술적 요구 사항 발생.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;단계 정의 문제&lt;/b&gt;: 잘못 정의된 단계는 분석의 신뢰성을 떨어뜨릴 수 있음.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;정확한 추적 필요&lt;/b&gt;: 사용자 이벤트를 정확히 추적해야 분석 결과가 유효.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;퍼널 분석은 사용자의 행동 흐름을 파악하고, 각 단계에서의 문제를 개선함으로써 비즈니스 목표를 달성하는 데 핵심적인 도구입니다. 정확한 데이터 수집과 분석을 통해 사용자 경험과 전환율을 최적화할 수 있습니다.&lt;/p&gt;</description>
      <category>ChatGPT로 공부하기/데이터 분석</category>
      <author>주토마</author>
      <guid isPermaLink="true">https://jhjoo.tistory.com/64</guid>
      <comments>https://jhjoo.tistory.com/64#entry64comment</comments>
      <pubDate>Mon, 18 Nov 2024 22:16:55 +0900</pubDate>
    </item>
    <item>
      <title>ChatGPT로 데이터 분석 공부하기 #15 A/B 테스트</title>
      <link>https://jhjoo.tistory.com/63</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;DALL&amp;amp;middot;E 2024-11-03 21.18.20.webp&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ba4ZXz/btsKN5uXIeO/KDVKijml7aKsL5ljrIRftK/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ba4ZXz/btsKN5uXIeO/KDVKijml7aKsL5ljrIRftK/img.webp&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ba4ZXz/btsKN5uXIeO/KDVKijml7aKsL5ljrIRftK/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fba4ZXz%2FbtsKN5uXIeO%2FKDVKijml7aKsL5ljrIRftK%2Fimg.webp&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1024&quot; height=&quot;1024&quot; data-filename=&quot;DALL&amp;middot;E 2024-11-03 21.18.20.webp&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;A/B 테스트란?&lt;/b&gt;&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;A/B 테스트는 두 가지 이상의 옵션(A와 B)을 비교하여 &lt;b&gt;어느 것이 더 효과적인지 실험적으로 확인하는 방법&lt;/b&gt;입니다. 이는 비즈니스 전략, 사용자 경험(UX), 마케팅 캠페인 등에서 데이터 기반 의사결정을 지원합니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. A/B 테스트의 기본 개념&lt;/b&gt;&lt;/h2&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;실험군(A)&lt;/b&gt;: 기존의 옵션(기준 또는 Control Group).&lt;/li&gt;
&lt;li&gt;&lt;b&gt;대조군(B)&lt;/b&gt;: 새로운 옵션(변경된 옵션 또는 Test Group).&lt;/li&gt;
&lt;li&gt;&lt;b&gt;목표 지표&lt;/b&gt;: 성공 여부를 측정하는 기준(KPI, Key Performance Indicator). 예: 전환율, 클릭률, 매출 등.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;가설&lt;/b&gt;: &quot;새로운 옵션(B)이 기존 옵션(A)보다 더 나은 결과를 낼 것이다.&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;A/B 테스트의 기본 원리&lt;/b&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;사용자 그룹을 &lt;b&gt;랜덤&lt;/b&gt;하게 나눕니다.&lt;/li&gt;
&lt;li&gt;각 그룹에 서로 다른 옵션을 노출합니다.&lt;/li&gt;
&lt;li&gt;특정 기간 동안 데이터를 수집합니다.&lt;/li&gt;
&lt;li&gt;통계 분석을 통해 결과를 평가하고, 선택한 옵션이 유의미한 차이를 만드는지 확인합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. A/B 테스트 과정&lt;/b&gt;&lt;/h2&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;(1) 목표 설정&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;문제 정의&lt;/b&gt;: 어떤 지표를 개선하고 싶은지 정의합니다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;예: &quot;구매 전환율을 높이고 싶다.&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;KPI 정의&lt;/b&gt;: 성공 여부를 판단할 수 있는 정량적 지표.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;예: &quot;전환율 = 구매 사용자 수 / 전체 방문자 수&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;(2) 가설 설정&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;기존 옵션(A)과 새 옵션(B)에 대해 가설을 세웁니다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;예: &quot;버튼 색상을 파란색에서 빨간색으로 바꾸면 클릭률이 증가할 것이다.&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;(3) 사용자 그룹 나누기&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;사용자 그룹을 &lt;b&gt;랜덤&lt;/b&gt;하게 나누어 외부 요인으로 인한 편향을 최소화합니다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;A 그룹: 기존 버튼(파란색).&lt;/li&gt;
&lt;li&gt;B 그룹: 변경된 버튼(빨간색).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;(4) 테스트 실행&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;각 사용자 그룹에 해당 옵션을 제공하며 데이터를 수집합니다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;기간 설정&lt;/b&gt;: 테스트는 충분한 데이터가 수집될 때까지 지속되어야 합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;샘플 크기&lt;/b&gt;: 통계적으로 유의미한 결과를 도출할 수 있는 충분한 사용자 수 확보.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;(5) 데이터 분석&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;수집된 데이터를 바탕으로 두 그룹 간의 성과 차이를 비교합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;통계적 검정&lt;/b&gt;: A/B 테스트의 결과가 우연이 아닌 유의미한 차이인지 검정합니다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;예: t-test, 카이제곱 검정.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;(6) 결론 도출&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;결과를 바탕으로 더 나은 옵션을 채택하거나, 추가 테스트를 계획합니다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;예: &quot;B 옵션(빨간색 버튼)이 A 옵션(파란색 버튼)보다 클릭률을 20% 개선했다.&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. A/B 테스트 예제&lt;/b&gt;&lt;/h2&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;(1) 문제 정의&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;목표&lt;/b&gt;: 전자상거래 사이트의 구매 전환율 증가.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;가설&lt;/b&gt;: &quot;결제 버튼의 텍스트를 '구매하기'에서 '지금 구매'로 변경하면 전환율이 증가할 것이다.&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;(2) 데이터 시뮬레이션&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Python을 사용해 간단한 A/B 테스트 데이터를 생성하고 분석합니다.&lt;/p&gt;
&lt;pre class=&quot;python&quot;&gt;&lt;code&gt;import numpy as np
import pandas as pd
from scipy.stats import ttest_ind

# 가상의 데이터 생성
np.random.seed(42)
group_A = np.random.binomial(1, 0.10, 1000)  # 전환율 10%
group_B = np.random.binomial(1, 0.12, 1000)  # 전환율 12%

# 데이터프레임 생성
data = pd.DataFrame({
    &quot;Group&quot;: [&quot;A&quot;] * 1000 + [&quot;B&quot;] * 1000,
    &quot;Conversion&quot;: np.concatenate([group_A, group_B])
})

# 그룹별 전환율 계산
conversion_rates = data.groupby(&quot;Group&quot;)[&quot;Conversion&quot;].mean()
print(conversion_rates)

# t-test로 그룹 간 차이 분석
t_stat, p_value = ttest_ind(group_A, group_B)
print(f&quot;t-statistic: {t_stat}, p-value: {p_value}&quot;)

&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;(3) 결과 해석&lt;/b&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;전환율 계산&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;A 그룹 전환율: 10%&lt;/li&gt;
&lt;li&gt;B 그룹 전환율: 12%&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;t-test 결과&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;p-value &amp;lt; 0.05: 두 그룹 간의 차이가 통계적으로 유의미함.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결론: &quot;B 옵션이 A 옵션보다 전환율이 높으므로 B 옵션을 선택합니다.&quot;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4. A/B 테스트의 장단점&lt;/b&gt;&lt;/h2&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;장점&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;객관적 데이터 기반 의사결정&lt;/b&gt;: 감각이 아닌 데이터로 결과를 평가.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;비용 효율적&lt;/b&gt;: 전체 시스템 변경 없이 소규모 실험으로 효과를 검증.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;빠른 피드백&lt;/b&gt;: 특정 옵션이 효과가 없는 경우 즉시 수정 가능.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;단점&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;샘플 크기 의존성&lt;/b&gt;: 샘플이 충분하지 않으면 결과가 왜곡될 수 있음.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;시간 소요&lt;/b&gt;: 테스트 기간 동안 충분한 데이터를 수집해야 함.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;단일 변수 실험&lt;/b&gt;: 여러 변수를 동시에 테스트하면 혼란이 발생.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;5. A/B 테스트 활용 사례&lt;/b&gt;&lt;/h2&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;이커머스&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;결제 페이지 디자인 변경 전환율 비교.&lt;/li&gt;
&lt;li&gt;할인 쿠폰 표시 방식 실험.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;마케팅&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이메일 제목(A/B) 클릭률 비교.&lt;/li&gt;
&lt;li&gt;광고 캠페인의 이미지/카피 효과 측정.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;제품 개발&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;신규 기능이 사용자 참여도를 증가시키는지 테스트.&lt;/li&gt;
&lt;li&gt;UI 변경 후 사용자 행동 비교.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;웹사이트 개선&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;페이지 로드 속도 변화가 사용자 이탈률에 미치는 영향 분석.&lt;/li&gt;
&lt;li&gt;버튼 색상/위치 변경 효과 테스트.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;6. A/B 테스트 성공 팁&lt;/b&gt;&lt;/h2&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;명확한 목표 설정&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;개선하고자 하는 KPI를 명확히 정의.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;샘플 크기 계산&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;사전에 필요한 샘플 크기를 계산하여 통계적으로 신뢰할 수 있는 결과를 확보.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;랜덤화&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;사용자 그룹을 무작위로 나눠 외부 요인의 영향을 최소화.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;단일 변수 변경&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;한 번에 하나의 요소만 테스트하여 결과를 명확히 해석.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;통계적 유의성 확인&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;결과가 우연이 아닌지를 검증(p-value, 신뢰구간 등).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;A/B 테스트는 데이터 기반의 의사결정을 가능하게 하는 강력한 도구입니다. 정교하게 설계하고 분석하면 제품 개선, 마케팅 전략 최적화, 사용자 경험 향상 등 다양한 비즈니스 문제를 해결할 수 있습니다.&lt;/p&gt;</description>
      <category>ChatGPT로 공부하기/데이터 분석</category>
      <author>주토마</author>
      <guid isPermaLink="true">https://jhjoo.tistory.com/63</guid>
      <comments>https://jhjoo.tistory.com/63#entry63comment</comments>
      <pubDate>Mon, 18 Nov 2024 22:15:36 +0900</pubDate>
    </item>
    <item>
      <title>ChatGPT로 데이터 분석 공부하기 #14 DW/DM 설계 및 구축</title>
      <link>https://jhjoo.tistory.com/62</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;DALL&amp;amp;middot;E 2024-11-03 21.18.20.webp&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5dbgG/btsKMl6ZY1F/HPdVpSG6UntiiPfYec9Qt0/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5dbgG/btsKMl6ZY1F/HPdVpSG6UntiiPfYec9Qt0/img.webp&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5dbgG/btsKMl6ZY1F/HPdVpSG6UntiiPfYec9Qt0/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5dbgG%2FbtsKMl6ZY1F%2FHPdVpSG6UntiiPfYec9Qt0%2Fimg.webp&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1024&quot; height=&quot;1024&quot; data-filename=&quot;DALL&amp;middot;E 2024-11-03 21.18.20.webp&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #666666; text-align: start;&quot;&gt;데이터 웨어하우스(DW)&lt;/span&gt;&lt;/b&gt;와 &lt;b&gt;데이터 마트(DM)&lt;/b&gt;는 데이터 분석과 비즈니스 인텔리전스(BI)를 위한 데이터 저장소 설계 및 구축에서 핵심적인 역할을 합니다. 이 두 개념은 데이터의 효율적인 관리, 분석, 보고를 지원하기 위해 설계됩니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. DW와 DM의 기본 개념&lt;/b&gt;&lt;/h2&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;(1) 데이터 웨어하우스(DW, Data Warehouse)&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;정의&lt;/b&gt;: 기업의 다양한 소스에서 데이터를 통합하여 저장하는 중앙 집중식 저장소.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;목적&lt;/b&gt;: 대규모 데이터 통합 및 장기적인 데이터 저장, 분석 지원.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;특징&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;통합적&lt;/b&gt;: 여러 시스템에서 데이터를 가져와 통합.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;주제 중심적&lt;/b&gt;: 주요 비즈니스 주제(예: 매출, 고객, 제품) 중심으로 설계.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;시간 변화 가능&lt;/b&gt;: 데이터의 시계열 정보를 유지.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;비휘발성&lt;/b&gt;: 데이터를 변경하지 않고 추가만 함.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;(2) 데이터 마트(DM, Data Mart)&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;정의&lt;/b&gt;: 데이터 웨어하우스에서 특정 주제나 부서에 맞게 데이터를 추출하여 저장한 소규모 저장소.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;목적&lt;/b&gt;: 특정 부서나 팀의 요구에 맞춘 데이터 제공.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;특징&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;DW보다 작고 단순&lt;/b&gt;.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;주제 특화&lt;/b&gt;: 특정 주제(예: 마케팅, 영업)에 맞춤화.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. DW와 DM의 차이&lt;/b&gt;&lt;/h2&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style8&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;특징&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;DW&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;DM&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;규모&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;대규모 저장소&lt;/td&gt;
&lt;td&gt;소규모 저장소&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;범위&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;전사적 데이터 통합&lt;/td&gt;
&lt;td&gt;특정 부서/팀 데이터&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;구조&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;복잡 (다양한 소스와 통합)&lt;/td&gt;
&lt;td&gt;단순 (특정 주제에 집중)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;구축 시간&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;장기적 프로젝트&lt;/td&gt;
&lt;td&gt;단기적 프로젝트&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. DW/DM 설계 과정&lt;/b&gt;&lt;/h2&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;(1) 요구 사항 분석&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;비즈니스 요구사항 수집&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;주요 KPI 정의 (예: 매출, 고객 유지율).&lt;/li&gt;
&lt;li&gt;분석 보고서 요구사항 정의.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;데이터 소스 파악&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;ERP, CRM, POS 시스템 등 다양한 소스에서 데이터를 수집.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;(2) 데이터 모델링&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DW/DM 설계의 핵심은 &lt;b&gt;데이터 모델링&lt;/b&gt;입니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;개념 모델&lt;/b&gt;: 비즈니스 개념 정의.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;예: 고객, 제품, 매출.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;논리 모델&lt;/b&gt;: 데이터베이스 관점에서 데이터 관계 정의.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;스타 스키마(Star Schema)&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;하나의 중심 테이블(Fact table)과 이를 참조하는 다수의 차원 테이블(Dimension table)로 구성.&lt;/li&gt;
&lt;li&gt;간단하고 직관적.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;스노우플레이크 스키마(Snowflake Schema)&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;차원 테이블을 정규화하여 더 세분화.&lt;/li&gt;
&lt;li&gt;데이터 중복 감소, 성능은 다소 낮음.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;물리 모델&lt;/b&gt;: 실제 데이터베이스에 데이터 구조 구현.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;예: SQL 테이블 생성.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;스타 스키마 예제&lt;/b&gt;:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;팩트 테이블&lt;/b&gt;: 매출 (Sales)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;매출ID, 제품ID, 고객ID, 매출액, 판매일&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;차원 테이블&lt;/b&gt;: 제품 (Product), 고객 (Customer), 날짜 (Date)&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;(3) 데이터 추출, 변환, 적재 (ETL)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ETL은 DW/DM 구축에서 데이터를 준비하는 단계입니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;추출(Extract)&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;다양한 소스(예: CSV, 데이터베이스, API)에서 데이터를 수집.&lt;/li&gt;
&lt;li&gt;예: SQL로 데이터 가져오기.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;변환(Transform)&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;데이터 정제: 결측값 처리, 중복 제거.&lt;/li&gt;
&lt;li&gt;데이터 변환: 날짜 포맷 변경, 코드 통합.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;적재(Load)&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;변환된 데이터를 DW 또는 DM에 적재.&lt;/li&gt;
&lt;li&gt;예: SQL INSERT INTO 문을 사용하거나, 데이터 적재 도구 활용(AWS Redshift, Snowflake 등).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;(4) 데이터 분석 및 시각화&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DW/DM에서 데이터를 활용하여 비즈니스 인사이트를 제공합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;쿼리 작성&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;SQL을 사용하여 데이터 추출 및 분석.&lt;/li&gt;
&lt;li&gt;예:&lt;/li&gt;
&lt;li&gt;SELECT ProductName, SUM(SalesAmount) AS TotalSales FROM Sales INNER JOIN Product ON Sales.ProductID = Product.ProductID GROUP BY ProductName;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;BI 도구 활용&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Tableau, Power BI, Looker 등을 사용해 시각화.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4. DW/DM 설계 시 고려 사항&lt;/b&gt;&lt;/h2&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;성능 최적화&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;인덱스 설정, 데이터 파티셔닝 활용.&lt;/li&gt;
&lt;li&gt;쿼리 성능 테스트 및 최적화.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;확장성&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;데이터가 증가하더라도 시스템이 확장 가능하도록 설계.&lt;/li&gt;
&lt;li&gt;클라우드 기반 데이터 웨어하우스(AWS Redshift, Google BigQuery) 활용.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;데이터 품질&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;데이터 정합성 유지.&lt;/li&gt;
&lt;li&gt;데이터 품질 관리 프로세스 구축.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;보안 및 권한 관리&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;민감 데이터 암호화.&lt;/li&gt;
&lt;li&gt;사용자 권한 설정.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;5. DW/DM 구축 실무 예제&lt;/b&gt;&lt;/h2&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;(1) 데이터 모델링&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;sql&quot;&gt;&lt;code&gt;-- 팩트 테이블 생성
CREATE TABLE Sales (
    SalesID INT PRIMARY KEY,
    ProductID INT,
    CustomerID INT,
    SalesAmount DECIMAL(10, 2),
    SalesDate DATE
);

-- 차원 테이블 생성
CREATE TABLE Product (
    ProductID INT PRIMARY KEY,
    ProductName VARCHAR(100),
    Category VARCHAR(50)
);

CREATE TABLE Customer (
    CustomerID INT PRIMARY KEY,
    CustomerName VARCHAR(100),
    Region VARCHAR(50)
);
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;(2) 데이터 적재&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;sql&quot;&gt;&lt;code&gt;-- 제품 데이터 삽입
INSERT INTO Product (ProductID, ProductName, Category)
VALUES (1, 'Laptop', 'Electronics'), (2, 'Chair', 'Furniture');

-- 매출 데이터 삽입
INSERT INTO Sales (SalesID, ProductID, CustomerID, SalesAmount, SalesDate)
VALUES (1, 1, 101, 1200.50, '2024-01-01'), (2, 2, 102, 150.75, '2024-01-02');
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;(3) 데이터 분석&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;-- 카테고리별 매출 합계
SELECT p.Category, SUM(s.SalesAmount) AS TotalSales
FROM Sales s
JOIN Product p ON s.ProductID = p.ProductID
GROUP BY p.Category;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;6. DW/DM 도구&lt;/b&gt;&lt;/h2&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;데이터 웨어하우스&lt;/b&gt;: AWS Redshift, Google BigQuery, Snowflake&lt;/li&gt;
&lt;li&gt;&lt;b&gt;ETL 도구&lt;/b&gt;: Apache Airflow, dbt, Talend&lt;/li&gt;
&lt;li&gt;&lt;b&gt;BI 도구&lt;/b&gt;: Tableau, Power BI, Looker&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DW/DM 설계 및 구축은 데이터를 효율적으로 관리하고 분석 가능한 상태로 만드는 데 필수적인 과정입니다. 데이터를 적절히 설계하고 관리하면, 비즈니스 의사결정에 강력한 기반을 제공할 수 있습니다.&lt;/p&gt;</description>
      <category>ChatGPT로 공부하기/데이터 분석</category>
      <author>주토마</author>
      <guid isPermaLink="true">https://jhjoo.tistory.com/62</guid>
      <comments>https://jhjoo.tistory.com/62#entry62comment</comments>
      <pubDate>Mon, 18 Nov 2024 22:13:35 +0900</pubDate>
    </item>
    <item>
      <title>ChatGPT로 데이터 분석 공부하기 #13 Pandas</title>
      <link>https://jhjoo.tistory.com/61</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;DALL&amp;amp;middot;E 2024-11-03 21.18.20.webp&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sCiVD/btsKKH9Uhlz/LaGmeNEAg7L4Cvk4sxHRgk/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sCiVD/btsKKH9Uhlz/LaGmeNEAg7L4Cvk4sxHRgk/img.webp&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sCiVD/btsKKH9Uhlz/LaGmeNEAg7L4Cvk4sxHRgk/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsCiVD%2FbtsKKH9Uhlz%2FLaGmeNEAg7L4Cvk4sxHRgk%2Fimg.webp&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1024&quot; height=&quot;1024&quot; data-filename=&quot;DALL&amp;middot;E 2024-11-03 21.18.20.webp&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&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;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Pandas&lt;/b&gt;는 Python에서 데이터 분석과 조작에 널리 사용되는 라이브러리로, &lt;b&gt;표 형태의 데이터&lt;/b&gt;(DataFrame)를 처리하는 데 매우 유용합니다. 데이터를 읽고 쓰는 기능부터, 필터링, 집계, 시각화까지 다양한 기능을 제공합니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. Pandas의 주요 데이터 구조&lt;/b&gt;&lt;/h2&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Pandas는 두 가지 주요 데이터 구조를 사용합니다:&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;Series&lt;/b&gt;: 1차원 데이터 구조 (1개의 열 또는 배열)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;DataFrame&lt;/b&gt;: 2차원 데이터 구조 (표 형태)&lt;/li&gt;
&lt;/ol&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;(1) Series&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Series&lt;/b&gt;는 데이터와 인덱스를 가진 1차원 데이터입니다.&lt;/p&gt;
&lt;pre class=&quot;makefile&quot;&gt;&lt;code&gt;import pandas as pd

# Series 생성
data = [10, 20, 30, 40]
series = pd.Series(data, index=[&quot;a&quot;, &quot;b&quot;, &quot;c&quot;, &quot;d&quot;])
print(series)

&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출력:&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;a    10
b    20
c    30
d    40
dtype: int64

&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;(2) DataFrame&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;DataFrame&lt;/b&gt;은 행과 열로 구성된 2차원 데이터입니다.&lt;/p&gt;
&lt;pre class=&quot;haskell&quot;&gt;&lt;code&gt;# DataFrame 생성
data = {
    &quot;Name&quot;: [&quot;Alice&quot;, &quot;Bob&quot;, &quot;Carol&quot;],
    &quot;Age&quot;: [25, 30, 27],
    &quot;City&quot;: [&quot;New York&quot;, &quot;Los Angeles&quot;, &quot;Chicago&quot;]
}
df = pd.DataFrame(data)
print(df)

&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출력:&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;     Name  Age         City
0   Alice   25     New York
1     Bob   30  Los Angeles
2   Carol   27      Chicago

&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. 데이터 읽기 및 쓰기&lt;/b&gt;&lt;/h2&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;(1) 파일 읽기&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Pandas는 다양한 파일 형식을 읽어올 수 있습니다.&lt;/p&gt;
&lt;pre class=&quot;ini&quot;&gt;&lt;code&gt;# CSV 파일 읽기
df = pd.read_csv(&quot;data.csv&quot;)

# Excel 파일 읽기
df = pd.read_excel(&quot;data.xlsx&quot;)

&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;(2) 파일 쓰기&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;분석 결과를 저장할 때 사용합니다.&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;# CSV 파일로 저장
df.to_csv(&quot;output.csv&quot;, index=False)

# Excel 파일로 저장
df.to_excel(&quot;output.xlsx&quot;, index=False)

&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. 데이터 확인 및 요약&lt;/b&gt;&lt;/h2&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;(1) 데이터 구조 확인&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;gauss&quot;&gt;&lt;code&gt;print(df.head())       # 상위 5개 행 출력
print(df.tail())       # 하위 5개 행 출력
print(df.info())       # 데이터 요약 정보
print(df.describe())   # 통계 요약
print(df.shape)        # 행, 열 개수
print(df.columns)      # 열 이름

&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4. 데이터 선택&lt;/b&gt;&lt;/h2&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;(1) 열 선택&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;lua&quot;&gt;&lt;code&gt;print(df[&quot;Name&quot;])       # 단일 열 선택
print(df[[&quot;Name&quot;, &quot;Age&quot;]])  # 여러 열 선택

&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;(2) 행 선택&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;gauss&quot;&gt;&lt;code&gt;print(df.loc[0])        # 행 번호로 선택 (라벨 기반)
print(df.iloc[0])       # 행 위치로 선택 (정수 기반)

&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;5. 데이터 필터링&lt;/b&gt;&lt;/h2&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;조건에 맞는 데이터만 선택합니다.&lt;/p&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;# 조건을 이용한 필터링
print(df[df[&quot;Age&quot;] &amp;gt; 25])  # Age가 25보다 큰 행 선택

&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;6. 데이터 추가 및 삭제&lt;/b&gt;&lt;/h2&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;(1) 열 추가&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;lsl&quot;&gt;&lt;code&gt;df[&quot;Salary&quot;] = [50000, 60000, 70000]  # 새 열 추가

&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;(2) 열 삭제&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;df.drop(&quot;Salary&quot;, axis=1, inplace=True)  # Salary 열 삭제

&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;(3) 행 삭제&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;df.drop(0, axis=0, inplace=True)  # 첫 번째 행 삭제

&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;7. 데이터 정렬&lt;/b&gt;&lt;/h2&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;(1) 행 정렬&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;df.sort_values(by=&quot;Age&quot;, ascending=False, inplace=True)  # Age 기준 내림차순 정렬

&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;(2) 열 정렬&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;df.sort_index(axis=1, inplace=True)  # 열 이름 기준 정렬

&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;8. 데이터 집계 및 그룹화&lt;/b&gt;&lt;/h2&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;(1) 데이터 요약&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;monkey&quot;&gt;&lt;code&gt;print(df[&quot;Age&quot;].mean())  # 평균 계산
print(df[&quot;Age&quot;].sum())   # 합계 계산
print(df[&quot;Age&quot;].max())   # 최대값

&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;(2) 그룹화&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;stylus&quot;&gt;&lt;code&gt;grouped = df.groupby(&quot;City&quot;)[&quot;Age&quot;].mean()
print(grouped)

&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;City별로 Age의 평균을 계산합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;9. 결측치 처리&lt;/b&gt;&lt;/h2&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;(1) 결측치 확인&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;gauss&quot;&gt;&lt;code&gt;print(df.isnull().sum())  # 결측치 개수 확인

&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;(2) 결측치 처리&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;df.fillna(0, inplace=True)  # 결측치를 0으로 채움
df.dropna(inplace=True)     # 결측치가 있는 행 삭제

&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;10. 데이터 변환&lt;/b&gt;&lt;/h2&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;(1) 데이터 타입 변환&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;prolog&quot;&gt;&lt;code&gt;df[&quot;Age&quot;] = df[&quot;Age&quot;].astype(&quot;float&quot;)  # Age를 실수형으로 변환

&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;(2) 데이터 값 변환&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;gcode&quot;&gt;&lt;code&gt;df[&quot;Age&quot;] = df[&quot;Age&quot;].apply(lambda x: x * 2)  # Age 값을 2배로 변환

&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;11. 데이터 병합&lt;/b&gt;&lt;/h2&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;(1) 두 DataFrame 합치기&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;ini&quot;&gt;&lt;code&gt;df1 = pd.DataFrame({&quot;A&quot;: [1, 2], &quot;B&quot;: [3, 4]})
df2 = pd.DataFrame({&quot;A&quot;: [5, 6], &quot;B&quot;: [7, 8]})
result = pd.concat([df1, df2])

&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;(2) 조인(merge)&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;ini&quot;&gt;&lt;code&gt;df1 = pd.DataFrame({&quot;ID&quot;: [1, 2], &quot;Name&quot;: [&quot;Alice&quot;, &quot;Bob&quot;]})
df2 = pd.DataFrame({&quot;ID&quot;: [1, 2], &quot;Salary&quot;: [50000, 60000]})
merged = pd.merge(df1, df2, on=&quot;ID&quot;)

&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;12. 실무에서 Pandas의 활용 예제&lt;/b&gt;&lt;/h2&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;(1) 매출 데이터 분석&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;makefile&quot;&gt;&lt;code&gt;sales = pd.DataFrame({
    &quot;Month&quot;: [&quot;Jan&quot;, &quot;Feb&quot;, &quot;Mar&quot;],
    &quot;Revenue&quot;: [10000, 15000, 20000]
})
print(&quot;총 매출:&quot;, sales[&quot;Revenue&quot;].sum())  # 매출 합계

&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;(2) 고객 데이터 필터링&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;prolog&quot;&gt;&lt;code&gt;customers = pd.DataFrame({
    &quot;Name&quot;: [&quot;Alice&quot;, &quot;Bob&quot;, &quot;Carol&quot;],
    &quot;Age&quot;: [25, 35, 45]
})
print(customers[customers[&quot;Age&quot;] &amp;gt; 30])  # 30세 이상 고객

&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Pandas는 데이터를 효율적으로 다루기 위한 강력한 도구입니다. 데이터를 정리하고 분석하며, 다양한 포맷으로 저장하는 작업에서 필수적으로 사용됩니다. Pandas의 기본을 잘 익히면 데이터 분석의 기초를 탄탄히 다질 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>ChatGPT로 공부하기/데이터 분석</category>
      <author>주토마</author>
      <guid isPermaLink="true">https://jhjoo.tistory.com/61</guid>
      <comments>https://jhjoo.tistory.com/61#entry61comment</comments>
      <pubDate>Fri, 15 Nov 2024 21:20:33 +0900</pubDate>
    </item>
  </channel>
</rss>