<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>coco</title>
    <link>https://jaemi-gotong.tistory.com/</link>
    <description>완전 대박 조짐~아니 그냥 조짐</description>
    <language>ko</language>
    <pubDate>Mon, 17 Aug 2026 18:03:43 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>_채채_</managingEditor>
    <image>
      <title>coco</title>
      <url>https://tistory1.daumcdn.net/tistory/8039369/attach/6804d2e3aad14860b8d273da087b8810</url>
      <link>https://jaemi-gotong.tistory.com</link>
    </image>
    <item>
      <title>[Infra] &amp;quot;제 컴퓨터에서는 되는데요?&amp;quot; 금지 - Docker 란?</title>
      <link>https://jaemi-gotong.tistory.com/91</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;개발을 하다보면 한 번쯤 이런 상황을 겪게 된다. 내 로컬에서는 분명 잘 돌아가던 코드가 팀원의 컴퓨터나 서버에 올리는 순간 갑자기 오류가 난다거나.. 아마 이유는 단순하고 다양할 것이다. Java 버전이 다르거나, 환경변수가 빠져있다거나, OS가 다르거나. 이러한 문제를 해결하기 위해 등장한 것이 Docekr이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/3kMJy/dJMcaiRGRrS/RP6dwZBYtqp3Da86pSpzcK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/3kMJy/dJMcaiRGRrS/RP6dwZBYtqp3Da86pSpzcK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/3kMJy/dJMcaiRGRrS/RP6dwZBYtqp3Da86pSpzcK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F3kMJy%2FdJMcaiRGRrS%2FRP6dwZBYtqp3Da86pSpzcK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;443&quot; height=&quot;443&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1080&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;  Docker 란?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Docker는 애플리케이션을 컨테이너화하여 가볍고 이식성 있는 패키지로 실행할 수 있게 해주는 소프트웨어 플랫폼이다.&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;/li&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;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: circle;&quot; data-ke-list-type=&quot;circle&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: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;개발 환경과 동일한 모든 구성 요소가 포함된 이미지를 빌드하고 실행하므로 별도의 설치 과정 없이 바로 실행할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;MSA 도입 시&lt;/b&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;도커에 대한 설명을 간략하게만 들어봐도 MSA 도입 시 유용할 것이라는 생각이 든다. 각 서비스가 독립적으로 배포되고 실행될 수 있는 특성 상 여러 개의 컨테이너를 통해 서비스들을 쉽게 관리할 수 있다.&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: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;도커는 필요한 만큼 컨테이너를 추가하거나 수평 확장이 가능한데, 오케스트레이션 도구와 결합하여 자동 확장도 가능하다. 대표적으로 쿠버네티스와 함께 사용하기 좋은데, 이는 쿠버네티스가 다수의 컨테이너를 관리하고 자동 배포, 운영 등을 지원하기 때문이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 외에도 CI/CD 환경을 구축할 때나 스케일링하고자 할 때 등 여러 가지 목적과 상황에 맞게 사용할 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;✳️ 관련 용어&lt;/b&gt;&lt;/h3&gt;
&lt;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;이미지&lt;/b&gt;: 도커 컨테이너를 생성하기 위한 청사진이다. 위에서 설명했듯이 애플리케이션과 실행에 필요한 것들을 포함한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;컨테이너&lt;/b&gt;: 컨테이너는 도커 이미지를 실행한 상태 그자체이다. 이미지는 정적 템플릿, 컨테이너는 동적 환경이라고 할 수 있다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Dockerfile&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;: 컨테이너 간의 통신을 관리하는 방식이다. 기본적으로는 브리지 네트워크를 통해 동일 네트워크에 연결된 컨테이너들끼리는 통신할 수 있다.&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Programming/Cloud,Infra</category>
      <category>Docker</category>
      <category>도커</category>
      <category>이미지</category>
      <category>인프라</category>
      <category>컨테이너</category>
      <author>_채채_</author>
      <guid isPermaLink="true">https://jaemi-gotong.tistory.com/91</guid>
      <comments>https://jaemi-gotong.tistory.com/91#entry91comment</comments>
      <pubDate>Tue, 21 Jul 2026 23:39:03 +0900</pubDate>
    </item>
    <item>
      <title>[코드트리] 약점 분석 및 학습하기(2차원 배열)</title>
      <link>https://jaemi-gotong.tistory.com/89</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;약점 지식 학습하기&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이전에 업로드한 코드트리 갭체크 이후.. &lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://jaemi-gotong.tistory.com/86&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;2026.05.25 - [분류 전체보기] - [코드트리] 코딩테스트 기본부터 준비하기 / 갭체크 후기&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1780281321365&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[코드트리] 코딩테스트 기본부터 준비하기 / 갭체크 후기&quot; data-og-description=&quot;본격적으로 코딩테스트를 준비하려고 했더니..백준이 사라져 곤란하던 차에 SNS에 떠서 알게 된 코드트리..마침 청약통장 챌린지를 진행하길래 참여해봤다.이미 1회차 기간이 지난 시점이었고, 2&quot; data-og-host=&quot;jaemi-gotong.tistory.com&quot; data-og-source-url=&quot;https://jaemi-gotong.tistory.com/86&quot; data-og-url=&quot;https://jaemi-gotong.tistory.com/86&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/caOzmW/dJMb8QetfYv/U66KARZd0Pb2ht1JmV47S0/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/bG6Egc/dJMb9frMqUn/K1Qb8amu1J9uBwIPpuRwfK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/bETXZM/dJMb9efk0Wz/Ur6yx4g7tZikpkmgaCeixk/img.jpg?width=676&amp;amp;height=708&amp;amp;face=0_0_676_708&quot;&gt;&lt;a href=&quot;https://jaemi-gotong.tistory.com/86&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://jaemi-gotong.tistory.com/86&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/caOzmW/dJMb8QetfYv/U66KARZd0Pb2ht1JmV47S0/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/bG6Egc/dJMb9frMqUn/K1Qb8amu1J9uBwIPpuRwfK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/bETXZM/dJMb9efk0Wz/Ur6yx4g7tZikpkmgaCeixk/img.jpg?width=676&amp;amp;height=708&amp;amp;face=0_0_676_708');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[코드트리] 코딩테스트 기본부터 준비하기 / 갭체크 후기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;본격적으로 코딩테스트를 준비하려고 했더니..백준이 사라져 곤란하던 차에 SNS에 떠서 알게 된 코드트리..마침 청약통장 챌린지를 진행하길래 참여해봤다.이미 1회차 기간이 지난 시점이었고, 2&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;jaemi-gotong.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;부족한 지식에 대한 학습을 위해서 추천챕터를 공부해봤다. 개발공부를 좀 했어도 코딩테스트 자체는 입문자 수준이었나보다..1,2차원 배열에 대해서 모두 부족하다는 결과가 나왔었다. 솔직히 이렇게까지 코테 실력이 부족할 줄은 몰랐는데, 갭체크를 통해서 객관적인 나의 지식적 위치를 파악할 수 있어서 다행이었던 거 같다. 좌절하지 말고 빨리 부족한 지식을 채워야겠다고 생각했다. &lt;/p&gt;
&lt;p&gt;&lt;img style=&quot;text-align: center; caret-color: transparent; letter-spacing: 0px;&quot; src=&quot;https://blog.kakaocdn.net/dna/cdg1CZ/dJMcaaMe8BD/AAAAAAAAAAAAAAAAAAAAAKfxWYMZnZ4zzBiDULmXmIUU2-0bT2AcHZi_2o34-bat/img.png?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&amp;amp;expires=1782831599&amp;amp;allow_ip=&amp;amp;allow_referer=&amp;amp;signature=i4ORzkU5iLY0Yf68t48HTWkfFaU%3D&quot; data-origin-width=&quot;1285&quot; data-origin-height=&quot;659&quot; data-is-animation=&quot;false&quot; /&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;나는 2차원 배열에 대한 학습을 진행했고, 학습 후 실전 문제가 더 필요할 경우 프로그래머스를 활용하였다. 아래 사진을 보면 챕터 별로 레슨이 꽤 많고 레슨 안에 단계도 꽤 세세하게 나뉘어 있다! 나는 2차원 배열의 레슨 2개를 학습했다. 앞선 포스팅에서도 말했듯이 코드트리의 장점은 기초부터 차근차근 학습할 수 있는 커리큘럼이다. 또한 기본 개념의 경우 문제 풀이 전에 예시코드들을 참고하면서 공부해볼 수 있다. 나는 개념을 이해하고 풀이를 들어가야하는 편이라서 굉장히 좋았다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ezq7IY/dJMcaarY2JY/Ue8KWMgJIuFbWczlkvFjn1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ezq7IY/dJMcaarY2JY/Ue8KWMgJIuFbWczlkvFjn1/img.png&quot; data-origin-width=&quot;842&quot; data-origin-height=&quot;1342&quot; data-is-animation=&quot;false&quot; style=&quot;width: 27.5199%; margin-right: 10px;&quot; data-widthpercent=&quot;27.84&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ezq7IY/dJMcaarY2JY/Ue8KWMgJIuFbWczlkvFjn1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fezq7IY%2FdJMcaarY2JY%2FUe8KWMgJIuFbWczlkvFjn1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;842&quot; height=&quot;1342&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/WGUhm/dJMcajoN6As/1BGlMuh4j2QvIx4Wa2QYlk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/WGUhm/dJMcajoN6As/1BGlMuh4j2QvIx4Wa2QYlk/img.png&quot; data-origin-width=&quot;3195&quot; data-origin-height=&quot;1965&quot; data-is-animation=&quot;false&quot; style=&quot;width: 71.3173%;&quot; data-widthpercent=&quot;72.16&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/WGUhm/dJMcajoN6As/1BGlMuh4j2QvIx4Wa2QYlk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWGUhm%2FdJMcajoN6As%2F1BGlMuh4j2QvIx4Wa2QYlk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3195&quot; height=&quot;1965&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 아직 진행하지 않은 단계에 대해서는 화면 상단 아이콘이 씨앗이고 학습을 완료하면 새싹이 되는데 깨알 포인트로 귀여웠다ㅋㅋㅋ&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;나의 학습 방법&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코테공부 초반이라서 이렇다할 학습 방법을 소개하기 좀 머슥하긴 하다. 그래도 배열 문제부터 열심히 공부하면서 '어, 좀 공부가 된다?!'싶었던 방법은 일단 코드트리에서 기본 개념을 싹 훑고 프로그래머스로 관련 문제들을 풀어보는 거다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 중요한 건 아주아주 기본 문제인 경우를 제외하고 반드시 다른 사람의 풀이도 공부해보는 것이다. 이 부분은 코드트리에서도 동일하게 가능했다. 내 풀이 코드에 대한 결과와 다른 사람들의 결과를 같이 볼 수 있는데 내 코드 보다 빠른 사람의 코드도 확인해볼 수 있어서 좋았다! &lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;754&quot; data-origin-height=&quot;676&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FAoOE/dJMb99Ni1ek/TeInElPCsBXnIpYdcgZbU1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FAoOE/dJMb99Ni1ek/TeInElPCsBXnIpYdcgZbU1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FAoOE/dJMb99Ni1ek/TeInElPCsBXnIpYdcgZbU1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFAoOE%2FdJMb99Ni1ek%2FTeInElPCsBXnIpYdcgZbU1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;754&quot; height=&quot;676&quot; data-origin-width=&quot;754&quot; data-origin-height=&quot;676&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 제출 목록 화면에서 같은 언어를 사용한 사람들의 결과들만 필터링해서 볼 수 있는 화면도 추가되면 좋을 것 같다...!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞으로도 꾸준히 꾸준히 코테 공부를 진행할 텐데 코드트리를 잘 활용해서 알고리즘 지식까지 탄탄한 베이스를 만들어야겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.codetree.ai/ko&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.codetree.ai/ko&lt;/a&gt;&lt;/p&gt;</description>
      <category>2차원배열</category>
      <category>알고리즘기초</category>
      <category>코드트리</category>
      <category>코딩테스트</category>
      <category>코테공부</category>
      <author>_채채_</author>
      <guid isPermaLink="true">https://jaemi-gotong.tistory.com/89</guid>
      <comments>https://jaemi-gotong.tistory.com/89#entry89comment</comments>
      <pubDate>Mon, 1 Jun 2026 12:20:59 +0900</pubDate>
    </item>
    <item>
      <title>[코드트리] 코딩테스트 기본부터 준비하기 / 갭체크 후기</title>
      <link>https://jaemi-gotong.tistory.com/86</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;본격적으로 코딩테스트를 준비하려고 했더니..백준이 사라져 곤란하던 차에 SNS에 떠서 알게 된 코드트리..마침 청약통장 챌린지를 진행하길래 참여해봤다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이미 1회차 기간이 지난 시점이었고, 2회차 인증 때는 갭체크만 한세월하다가 (하다말다 하다말다 함)3회차 때 드디어 갭쳌을 끝내서 인증을 진행했다..ㅜ 어차피 이용권을 못 받을 거 같긴한데 마지막 회차 인증 진행할 때까지만이라도 코드트리를 열심히 이용해보자는 생각으로 킵고잉ㅋㅋㅋ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;갭체크&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코테를 풀다보면 내가 지금 뭘 알고 뭘 모르는지를 잘 모르게되는 즉 메타인지가 흐려지는 순간이 있는데, 코드트리에서는 갭체크라는 것을 통해 지금 내 수준을 비교적 확실하게 체크해볼 수 있었다. 먼저 현재 내 코딩 목표를 설정하고 몇가지 문제를 풀면, 풀이 방식이나 시간 등을 분석하여 현재 나의 알고리즘 지식에서 어떤 부분이 약하고 어떤 부분은 잘 배운 상태인지 결과 화면을 보여준다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;593&quot; data-origin-height=&quot;438&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nuGqR/dJMcabqOwHH/KcQHB2TExqVba7RNkZ8ch0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nuGqR/dJMcabqOwHH/KcQHB2TExqVba7RNkZ8ch0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nuGqR/dJMcabqOwHH/KcQHB2TExqVba7RNkZ8ch0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnuGqR%2FdJMcabqOwHH%2FKcQHB2TExqVba7RNkZ8ch0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;593&quot; height=&quot;438&quot; data-origin-width=&quot;593&quot; data-origin-height=&quot;438&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 아직 알고리즘 응애 수준이라서 그런지 내가 부족한 지식은 비교적 기본기 위주였는데 자신없어서 결과 화면은 스킵합니다...&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;추천 학습 경로 따라가기&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;갭체크 후 내가 보완해야 하는 수준을 위한 학습을 '추천 챕터' 카테고리에서 확인하고 공부해볼 수 있다. 추천 학습 경로를 따라가면서 좋았던 점은 아주아주아주아주 기본적인 구현부터 하나하나 학습할 수 있도록 각 챕터가 구성되어 있다는 점이다. 나같은 코테초보, 그리고 실전부터 들어가기보다 기초부터 스텝&amp;nbsp; 바이 스텝으로 쌓아가는 방법이 맞는 사람들은 잘 활용하면 굉장히 좋을 것 같다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;561&quot; data-origin-height=&quot;424&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dBNw1B/dJMcafUhIm9/ilw3TfJq00nQxTgcRPnfJk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dBNw1B/dJMcafUhIm9/ilw3TfJq00nQxTgcRPnfJk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dBNw1B/dJMcafUhIm9/ilw3TfJq00nQxTgcRPnfJk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdBNw1B%2FdJMcafUhIm9%2Filw3TfJq00nQxTgcRPnfJk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;561&quot; height=&quot;424&quot; data-origin-width=&quot;561&quot; data-origin-height=&quot;424&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런식으로 기본문제-연습문제-테스트 로 구성되어 실전 코테풀이에 접근하는 방법을 자세하게 익히고 이해할 수 있었다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 기본기가 부족하다보니 빠르게 기본 챕터들을 100%로 완료하는 것을 목표로 해야겠다는 생각이다...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메타인지가 정말 중요한 필드이다보니..갭체크만 진행해봐도 코테 공부에 큰 도움이 될 거 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.codetree.ai/ko&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.codetree.ai/ko&lt;/a&gt;&lt;/p&gt;</description>
      <category>갭체크</category>
      <category>알고리즘공부</category>
      <category>코드트리</category>
      <category>코딩테스트</category>
      <category>코테공부</category>
      <category>코테준비</category>
      <author>_채채_</author>
      <guid isPermaLink="true">https://jaemi-gotong.tistory.com/86</guid>
      <comments>https://jaemi-gotong.tistory.com/86#entry86comment</comments>
      <pubDate>Mon, 25 May 2026 23:41:04 +0900</pubDate>
    </item>
    <item>
      <title>[코테/java] 10진수를 2진수로 변환하기</title>
      <link>https://jaemi-gotong.tistory.com/79</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #f3c000;&quot;&gt;문제&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;10진수를 입력받아 2진수로 변환해 반환하는 solution()함수를 구현하세요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[제약조건]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;decimal은 1이상 10억 미만의 자연수&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #f3c000;&quot;&gt;&lt;b&gt;풀이 과정&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 10진수 N을 2로 나누고 몫은 홀드하고 나머지는 저장한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 앞에서 나눈 결과값인 목이 0이 아니라면 1번을 다시 반복한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 몫이 0이 될 때까지 나눴다면 1번에서 저장한 수를 최근 계산한 것부터 순서대로 나열한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #f3c000;&quot;&gt;&lt;b&gt;정답 코드&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1769965530109&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.util.Stack;

public class Solution {
    public static String solution(int N) {
        Stack&amp;lt;Integer&amp;gt; stack = new Stack&amp;lt;&amp;gt;();
        while (N &amp;gt; 0) {
            stack.push(N % 2);
            N /= 2;
        }

        StringBuilder sb = new StringBuilder();
        while (!stack.isEmpty()) {
            sb.append(stack.pop());
        }
        return sb.toString();
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 왜 StringBuilder를 사용하는 이유는...사실 String + 연산을 사용해도 풀이가 가능하지만 그렇게 풀이한다면&lt;/p&gt;
&lt;pre id=&quot;code_1769965777840&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;String s =&quot;&quot;;
s += &quot;1&quot;;
s += &quot;0&quot;;
s += &quot;1&quot;;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런식으로 매번 새로운 String 객체를 생성해야 한다. 따라서 성능적인 측면에서 반복문에서는 StringBuilder를 사용한 코드가 더 효율적이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[문제 출처]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://product.kyobobook.co.kr/detail/S000212576322&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://product.kyobobook.co.kr/detail/S000212576322&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1769966196152&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;코딩 테스트 합격자 되기: 자바 편 | 김희성 - 교보문고&quot; data-og-description=&quot;코딩 테스트 합격자 되기: 자바 편 | ★ 코딩 테스트 합격자가 되는 가장 확실한 방법! ★ 프로그래머스 제공, 전문가가 모여 엄선한 빈출 97문제로 철저하게 대비하세요! 신입 사원 코딩 테스트&quot; data-og-host=&quot;product.kyobobook.co.kr&quot; data-og-source-url=&quot;https://product.kyobobook.co.kr/detail/S000212576322&quot; data-og-url=&quot;https://product.kyobobook.co.kr/detail/S000212576322&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/9blyb/dJMb9dHi4oR/RnaMkAMluIKRmaQmzhW8I1/img.jpg?width=458&amp;amp;height=589&amp;amp;face=0_0_458_589,https://scrap.kakaocdn.net/dn/kyZTh/dJMb9g46aXR/MGr1j0kF4MXDIEyyAlzWz0/img.jpg?width=458&amp;amp;height=589&amp;amp;face=0_0_458_589,https://scrap.kakaocdn.net/dn/bqDKKA/dJMb9b3M8bc/FgJxYgexCIhg0nWX68XOEk/img.jpg?width=599&amp;amp;height=608&amp;amp;face=0_0_599_608&quot;&gt;&lt;a href=&quot;https://product.kyobobook.co.kr/detail/S000212576322&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://product.kyobobook.co.kr/detail/S000212576322&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/9blyb/dJMb9dHi4oR/RnaMkAMluIKRmaQmzhW8I1/img.jpg?width=458&amp;amp;height=589&amp;amp;face=0_0_458_589,https://scrap.kakaocdn.net/dn/kyZTh/dJMb9g46aXR/MGr1j0kF4MXDIEyyAlzWz0/img.jpg?width=458&amp;amp;height=589&amp;amp;face=0_0_458_589,https://scrap.kakaocdn.net/dn/bqDKKA/dJMb9b3M8bc/FgJxYgexCIhg0nWX68XOEk/img.jpg?width=599&amp;amp;height=608&amp;amp;face=0_0_599_608');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;코딩 테스트 합격자 되기: 자바 편 | 김희성 - 교보문고&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;코딩 테스트 합격자 되기: 자바 편 | ★ 코딩 테스트 합격자가 되는 가장 확실한 방법! ★ 프로그래머스 제공, 전문가가 모여 엄선한 빈출 97문제로 철저하게 대비하세요! 신입 사원 코딩 테스트&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;product.kyobobook.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>코딩테스트</category>
      <category>코테풀이</category>
      <author>_채채_</author>
      <guid isPermaLink="true">https://jaemi-gotong.tistory.com/79</guid>
      <comments>https://jaemi-gotong.tistory.com/79#entry79comment</comments>
      <pubDate>Mon, 2 Feb 2026 01:45:55 +0900</pubDate>
    </item>
    <item>
      <title>코드를 깔끔하고 직관적이게(1) - 디자인 패턴(Design Pattern)이란?</title>
      <link>https://jaemi-gotong.tistory.com/49</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;코드를 작성하다보면 으레 고민해야 하는 문제들이 있다. 객체를 어떻게 어디에서 생성할지, 객체 간 소통을 어떻게 하도록 설계해야 할지, 반복되는 코드들을 어디에서 관리할지 등... 개발을 공부하고 나서 초반에는 그냥 되는대로 작성했었다. 그렇다보니 즉흥적이고 규칙없이 직관성없는 스파게티 코드가 되기 일쑤였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;디자인패턴은 이러한 문제들에 대해 &lt;b&gt;검증된 해결책&lt;/b&gt;을 정리해놓은 설계 템플릿이라고 할 수 있다. 1994년 GoF(Gang of Four)라고 불리는 네명의 개발자가(그래서 four구나..) 디자인 패턴 23개를 정리하면서 알려지게 되었다고 한다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;디자인패턴, 왜 사용해야 할까?&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;b&gt;커뮤니케이션&lt;/b&gt;이 수월해진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;b&gt;검증된 구조를 재사용&lt;/b&gt;할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;b&gt;유지보수&lt;/b&gt;하기 좋다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;디자인 패턴을 3가지로 분류하면&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;1. 생성 패턴&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;말 그대로 객체를 어떻게 만들것인가에 관한 패턴이다. 객체 생성 방식을 유연하게 만들어준다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;패턴&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;내용&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Singleton&lt;/td&gt;
&lt;td&gt;인스턴스를 딱 하나만 생성&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Factory Method&lt;/td&gt;
&lt;td&gt;객체 생성을 서브클래스에 위임&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Abstract Factory&lt;/td&gt;
&lt;td&gt;관련 객체들을 묶어서 생성&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Builder&lt;/td&gt;
&lt;td&gt;복잡한 객체를 단계적으로 생성&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Prototype&lt;/td&gt;
&lt;td&gt;기존 객체를 복사해서 생성&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;2. 구조 패턴&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클래스나 객체를 어떻게 조합할 것인가에 대한 패턴이다. 유연하고 재사용가능한 코드를 짜기 위해 알아두면 좋은 패턴이다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 37.6744%;&quot;&gt;패턴&lt;/td&gt;
&lt;td style=&quot;width: 62.3256%;&quot;&gt;내용&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 37.6744%;&quot;&gt;Adapter&lt;/td&gt;
&lt;td style=&quot;width: 62.3256%;&quot;&gt;호환되지 않는 인터페이스를 연결&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 37.6744%;&quot;&gt;Decorator&lt;/td&gt;
&lt;td style=&quot;width: 62.3256%;&quot;&gt;기능을 동적으로 추가&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 37.6744%;&quot;&gt;Composite&lt;/td&gt;
&lt;td style=&quot;width: 62.3256%;&quot;&gt;트리 구조로 객체 구성&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 37.6744%;&quot;&gt;Facade&lt;/td&gt;
&lt;td style=&quot;width: 62.3256%;&quot;&gt;복잡한 서브시스템을 단순한 인터페이스로&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 37.6744%;&quot;&gt;Bridge&lt;/td&gt;
&lt;td style=&quot;width: 62.3256%;&quot;&gt;구현과 추상화를 분리&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 37.6744%;&quot;&gt;Flyweight&lt;/td&gt;
&lt;td style=&quot;width: 62.3256%;&quot;&gt;공유로 메모리 절약&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 37.6744%;&quot;&gt;Proxy&lt;/td&gt;
&lt;td style=&quot;width: 62.3256%;&quot;&gt;대리 객체로 접근 제어&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;3. 행위 패턴&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;객체 간 어떻게 소통하고 책임을 가져갈 것인가에 대한 패턴이다. 간단하게 역할 분담에 대한 패턴이라고 할 수 있다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;&lt;b&gt;패턴&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;&lt;b&gt;내용&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;Observer&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;상태 변화를 구독자에게 알림&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;Strategy&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;알고리즘을 캡슐화해서 교체 가능하게&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;Template Method&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;알고리즘 골격을 정의하고 세부는 서브클래스에&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;Command&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;요청을 객체로 캡슐화&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;Iterator&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;컬렉션 순회 방법을 표준화&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;Chain of Responsibility&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;요청을 체인으로 전달&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;State&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;상태에 따라 행동 변경&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;Mediator&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;객체 간 통신을 중재자가 담당&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;Memento&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;상태를 저장하고 복원&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;Visitor&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;구조와 동작을 분리&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;Interpreter&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;언어의 문법을 정의&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;디자인 패턴은 뭐 CS 지식처럼 무조건 외워야 하는 공식은 아니라고 생각한다. 단지 상황에 맞게 꺼내서 쓰는 도구이고, 도구는 많을수록 좋은 법이니까 기억해뒀다가 써먹으면 좋다! 실제로 나도 멘토에게 코드 리뷰를 받으면서 디자인패턴을 패턴을 적용해 보면 어떻겠냐는 피드백을 받아서 알게 된 부분이기도 하다.&lt;/p&gt;</description>
      <category>Programming/Java</category>
      <category>구조패턴</category>
      <category>디자인 패턴</category>
      <category>디자인패턴</category>
      <category>생성패턴</category>
      <category>행위패턴</category>
      <author>_채채_</author>
      <guid isPermaLink="true">https://jaemi-gotong.tistory.com/49</guid>
      <comments>https://jaemi-gotong.tistory.com/49#entry49comment</comments>
      <pubDate>Tue, 25 Nov 2025 13:46:27 +0900</pubDate>
    </item>
    <item>
      <title>[Spring] Batch작업이란?</title>
      <link>https://jaemi-gotong.tistory.com/46</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Spring Batch란?&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cEZNT4/dJMcajgKjUS/iKJ3oBBBa3bP1mRB5F86XK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cEZNT4/dJMcajgKjUS/iKJ3oBBBa3bP1mRB5F86XK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cEZNT4/dJMcajgKjUS/iKJ3oBBBa3bP1mRB5F86XK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcEZNT4%2FdJMcajgKjUS%2FiKJ3oBBBa3bP1mRB5F86XK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;720&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&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;배치 처리는 주기적으로 대량의 반복적인 데이터 작업을 수행하기 위해 사용하는 방식이다. 예를 들어 백업, 삭제나 필터링 같은 특정 데이터를 처리하는 일을 개별 트랜잭션에서 진행해야 하는데 이런 작업들은 지금 당장 결과가 필요하지 않은 경우가 많다. 이러한 작업들을 모아서 자동으로 처리하는 것이 Batch이다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Batch가 필요한 이유?&lt;/b&gt;&lt;/h2&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;/li&gt;
&lt;li&gt;월별 통계 계산&lt;/li&gt;
&lt;li&gt;로그 분석&lt;/li&gt;
&lt;li&gt;대량의 알림 발송&lt;/li&gt;
&lt;li&gt;데이터 백업 / 정리&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 작업을 리소스 사용량이 많은 시간대에 처리하면&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;응답 지연 &lt;/li&gt;
&lt;li&gt;서버 부하 폭증 &lt;/li&gt;
&lt;li&gt;서비스 장애 가능성 증가 &lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;등의 우려가 있다. 따라서 Batch는 서비스 운영의 부담을 덜어주는 역할을 한다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Batch의 특징&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 비실시간성&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: 즉각적인 응답 필요하지 않은 작업을 수행하며 정해진 시점에 실행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 대량의 데이터 처리&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: 수천 ~ 수백만 건 단위를 처리할 수 있으며 성능과 안정성이 중요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 자동화&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: 사람의 개입을 최소화하고 자동화를 통해 반복적인 태스크를 효율적으로 처리한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 트랜잭션 관리&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: 대량 처리 중 일부가 실패할 경우 전체가 롤백되는 것이 아니라 일정 단위로 나눠서 처리한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. 멱등성 보장&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: 같은 배치를 두 번 실행해도 결과값은 같아야 한다. 따라서 중복 처리 방지 로직을 붙여줘야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6. 실행 이력 관리&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: 언제 실행되었으며 성공인지 실패했는지, 몇 건이나 처리했는지를 기록한다. 이는 운영 환경에서는 필수적인 부분이다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[참고 자료]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;a href=&quot;https://aws.amazon.com/ko/what-is/batch-processing/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://aws.amazon.com/ko/what-is/batch-processing/&lt;/a&gt;&lt;/b&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1770107525938&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;배치 처리란 무엇인가요? 배치 처리 시스템 설명 - AWS&quot; data-og-description=&quot;배치 처리의 정의, 중요한 이유, 배치 처리의 작동 방식을 알아봅니다.&quot; data-og-host=&quot;aws.amazon.com&quot; data-og-source-url=&quot;https://aws.amazon.com/ko/what-is/batch-processing/&quot; data-og-url=&quot;https://aws.amazon.com/ko/what-is/batch-processing/&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://aws.amazon.com/ko/what-is/batch-processing/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://aws.amazon.com/ko/what-is/batch-processing/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;배치 처리란 무엇인가요? 배치 처리 시스템 설명 - AWS&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;배치 처리의 정의, 중요한 이유, 배치 처리의 작동 방식을 알아봅니다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;aws.amazon.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Programming/Spring</category>
      <category>batch</category>
      <category>Spring Batch</category>
      <category>배치작업</category>
      <category>배치처리</category>
      <author>_채채_</author>
      <guid isPermaLink="true">https://jaemi-gotong.tistory.com/46</guid>
      <comments>https://jaemi-gotong.tistory.com/46#entry46comment</comments>
      <pubDate>Wed, 19 Nov 2025 14:40:19 +0900</pubDate>
    </item>
    <item>
      <title>[DB] DDL, DML, DCL</title>
      <link>https://jaemi-gotong.tistory.com/38</link>
      <description>&lt;blockquote data-ke-style=&quot;style2&quot;&gt;SQL 명령어는 목적에 따라 크게 DDL, DML, DCL 이렇게 세 가지로 분류된다. 개인적으로 글자도 비슷비슷해서 공부하면서 헷갈렸다...그래서 정리하기 위한 글을 작성해보기로 했다! 각각의 역할과 차이를 명확하게 이해해보자.&lt;/blockquote&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;DDL(Data Definition Language) - 데이터 정의어&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DDL은 데이터베이스의 구조를 정의하고 변경하는 명령어이다. 즉 테이블을 만들고 수정하고 삭제하는 작업이라고 생각하면 된다.&lt;/p&gt;
&lt;pre id=&quot;code_1781013459729&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-- 테이블 생성
CREATE TABLE users (
    id    INT PRIMARY KEY,
    email VARCHAR(100) NOT NULL,
    role  VARCHAR(20)
);

-- 컬럼 추가
ALTER TABLE users ADD COLUMN created_at TIMESTAMP;

-- 테이블 삭제 (구조 + 데이터 모두)
DROP TABLE users;

-- 데이터만 전체 삭제 (구조 유지)
TRUNCATE TABLE users;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;핵심 명령어&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래와 같은 명령어들이 포함된다.&lt;/p&gt;
&lt;pre id=&quot;code_1781013492513&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;CREATE   &amp;rarr; 생성
ALTER    &amp;rarr; 구조 변경
DROP     &amp;rarr; 삭제 (구조 + 데이터)
TRUNCATE &amp;rarr; 데이터만 전체 삭제
RENAME   &amp;rarr; 이름 변경&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이것들 중 CREATE, ALTER,DROP은 프로젝트에서 정말 많이 사용했던 거 같다.&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;DDL은 Auto Commit 이므로 실행 즉시 반영되며 &lt;b&gt;ROLLBACK이 불가능&lt;/b&gt; 하다는 것이다.&lt;/li&gt;
&lt;li&gt;따라서 운영 DB에서 사용할 때 실수로 DROP하면 되돌릴수 없으니 주의가 필요하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;DML(Data Manipulation Language) - 데이터 조작어&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DML은 테이블 내의 데이터를 조회, 조작하는 명령어다. 실제로 데이터를 다룰 때 가장 자주 쓰이는 분류이기도 하다.&lt;/p&gt;
&lt;pre id=&quot;code_1781013743937&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-- 조회
SELECT * FROM users WHERE role = 'ADMIN';

-- 삽입
INSERT INTO users (email, role)
VALUES ('test@test.com', 'USER');

-- 수정
UPDATE users
SET role = 'ADMIN'
WHERE id = 1;

-- 삭제
DELETE FROM users WHERE id = 1;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;핵심 명령어&lt;/h4&gt;
&lt;pre id=&quot;code_1781013766810&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT &amp;rarr; 조회
INSERT &amp;rarr; 삽입
UPDATE &amp;rarr; 수정
DELETE &amp;rarr; 삭제&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DDL과의 차이는&lt;b&gt; 트랜잭션 제어&lt;/b&gt;가 가능하다는 것이다. commit 전까지는 ROLLBACK으로 되돌릴 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;DCL( Data Control Language) - 데이터 제어어&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DCL은 데이터 베이스 접근 권한을 제어하는 명령어다. 누가 어떤 데이터에 접근할 수 있는지를 관리한다.&lt;/p&gt;
&lt;pre id=&quot;code_1781013952617&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-- 권한 부여
GRANT SELECT, INSERT ON users TO 'hong';

-- 권한 취소
REVOKE INSERT ON users FROM 'hong';&lt;/code&gt;&lt;/pre&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;핵심 명령어&lt;/h4&gt;
&lt;pre id=&quot;code_1781013973321&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;GRANT  &amp;rarr; 권한 부여
REVOKE &amp;rarr; 권한 취소&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실무에서는CS 담당자에게 조회를 위한 SELECT권한만 부여하거나 개발자에게 운영 DB의 쓰기 권한을 제한하는 식으로 활용한다고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Programming/Database</category>
      <category>DCL</category>
      <category>ddl</category>
      <category>dml</category>
      <author>_채채_</author>
      <guid isPermaLink="true">https://jaemi-gotong.tistory.com/38</guid>
      <comments>https://jaemi-gotong.tistory.com/38#entry38comment</comments>
      <pubDate>Wed, 29 Oct 2025 09:20:41 +0900</pubDate>
    </item>
    <item>
      <title>[Server] 캐시의 정의와 캐시 유형</title>
      <link>https://jaemi-gotong.tistory.com/35</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;캐시(Cache)&lt;/b&gt;&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;캐시란 자주 접근하는 데이터를 빠르게 가져오기 위해 임시로 저장해두는 저장소라고 할 수 있다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 온라인 쇼핑몰의 메인 페이지에서 보이는 데이터(인기 상품, 신상품 등)는 사용자 수가 많아질 수록 조회 횟수가 늘어나는데 이때 한 번 불러온 데이터를 일정 기간 캐시에 저장해두고, 다음의 동일한 요청부터 DB에서 불러오지 않고 캐시에서 바로 가져와서 빠르게 응답하도록 하는 상황을 생각해볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;캐시의 필요성&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1. 자주 접근하는 데이터를 빠르게 조회&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2. 원본 데이터 소스의 부하를 감소 시킴&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 캐시가 없는 요처으이 경우, 데이터베이스로 직접 전달되어 자원을 소모시키게 되는데 캐시를 사용할 경우 동일 데이터를 여러 번 요청해도 데이터베이스에서는 한 번만 조회하면 되므로 DB 연결 수가 급격히 증가하는 것을 방지할 수 있다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3. 네트워크 지연시간을 최소화함&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 사용자와 가까운 위치(브라우저나 서버 메모리 등)에 데이터를 저장하여 지연을 최소화한다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;캐시의 유형&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1️⃣ CUP캐시&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- CPU 내부에 위치하고 메모리 접근 속도를 개선할 목적으로 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- L1, L2, L3 캐시가 해당된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 매우빠르고 용량이 작으며 개발자가 직접 제어하지 않는다는 특징이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2️⃣ 웹 캐시&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 브라우저, 프록시, CDN에 위치하며 서버에서 직접 데이터베이스에 접근할 필요하 없어져 웹사이트 로딩 속도를 높여준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 웹 클라이언트 캐시, 웹 서버 캐시가 해당된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 네트워크 비용을 감소시키며 프론트, 백엔드 모두에게 중요한 부분이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3️⃣ CDN 캐시&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 콘텐츠 자체(이미지, JS, CSS, 영상 등)를 사용자와 가까운 서버에 저장해두는 캐시로 지리적으로 분산된 프록시 서버 네트워크라고 할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 사용자가 웹 페이지를 요청하면 가장 가까운 서버가 응답을 시도하는데 이때 캐시에 있으면 바로 응답, 없으면 원본 서버에서 가져와서 전달한다. 전달함과 동시에 CDN에 저장한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4️⃣ DNS 캐시&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 도메인 이름을 IP 주소로 변환하여&amp;nbsp; 결과를 저장해두는 캐시&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 예를 들어 브라우저가 exampl.com을 요청할 때 DNS 캐시 유무를 브라우저 -&amp;gt; 운영체제 -&amp;gt; DNS 서버 순으로 확인하고 캐시가 없는 경우 DNS 서버를 통해 요청이 들어가며 이 응답은 TTL동안 각 단계에서 캐싱한다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;  참고 문서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.upguard.com/blog/cache&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.upguard.com/blog/cache&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1768241569178&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;What is a Cache? | UpGuard&quot; data-og-description=&quot;A cache is a temporary data storage location that stores copies of frequently accessed data or files. Learn more about its types and uses.&quot; data-og-host=&quot;www.upguard.com&quot; data-og-source-url=&quot;https://www.upguard.com/blog/cache&quot; data-og-url=&quot;https://www.upguard.com/blog/cache&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/83swv/hyZQMUNptV/Qt4DGHVxGnKbzgpUiXQX41/img.jpg?width=1200&amp;amp;height=628&amp;amp;face=0_0_1200_628,https://scrap.kakaocdn.net/dn/bBpExn/hyZRtuIF0G/QctMWGtwYVGajyybF9b0fk/img.jpg?width=1200&amp;amp;height=628&amp;amp;face=0_0_1200_628,https://scrap.kakaocdn.net/dn/bxNi98/hyZRmPPQY7/OJYpnwvagkD47nQ0lSST7k/img.png?width=2881&amp;amp;height=1620&amp;amp;face=0_0_2881_1620&quot;&gt;&lt;a href=&quot;https://www.upguard.com/blog/cache&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.upguard.com/blog/cache&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/83swv/hyZQMUNptV/Qt4DGHVxGnKbzgpUiXQX41/img.jpg?width=1200&amp;amp;height=628&amp;amp;face=0_0_1200_628,https://scrap.kakaocdn.net/dn/bBpExn/hyZRtuIF0G/QctMWGtwYVGajyybF9b0fk/img.jpg?width=1200&amp;amp;height=628&amp;amp;face=0_0_1200_628,https://scrap.kakaocdn.net/dn/bxNi98/hyZRmPPQY7/OJYpnwvagkD47nQ0lSST7k/img.png?width=2881&amp;amp;height=1620&amp;amp;face=0_0_2881_1620');&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;What is a Cache? | UpGuard&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;A cache is a temporary data storage location that stores copies of frequently accessed data or files. Learn more about its types and uses.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.upguard.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Programming/Server</category>
      <category>Cache</category>
      <category>캐시</category>
      <author>_채채_</author>
      <guid isPermaLink="true">https://jaemi-gotong.tistory.com/35</guid>
      <comments>https://jaemi-gotong.tistory.com/35#entry35comment</comments>
      <pubDate>Wed, 22 Oct 2025 18:38:29 +0900</pubDate>
    </item>
    <item>
      <title>[Server] 로컬 캐시와 분산 캐시</title>
      <link>https://jaemi-gotong.tistory.com/34</link>
      <description>&lt;blockquote data-ke-style=&quot;style2&quot;&gt;로컬 캐시와 분산 캐시는 캐시 데이터가 저장되는 위치와 공유되는 범위에서 근본적인 차이가 있다.&lt;/blockquote&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1️⃣&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;로컬 캐시 (Local Cache)&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: 로컬 캐시는 애플리케이션 내부 메모리(RAM, JVM 힙메모리 등)에 데이터를 저장하는 캐시 구조이다. 각 서버 인스턴스는 자신만의 독립적인 캐시 저장소를 가지며 이는 각자가 책상 위에 개인용 메모 노트를 두는 것과 같다고 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로컬 캐시는 서버 자체에 존재하므로 외부 네트워크 요청 없이 &lt;b&gt;가장 빠르게 데이터에 접근&lt;/b&gt;할 수 있다.&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;style4&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 20.6977%; text-align: center;&quot; rowspan=&quot;2&quot;&gt;장점&lt;/td&gt;
&lt;td style=&quot;width: 79.3023%; text-align: center;&quot;&gt;네트워크 호출이 없고 자신의 메모리에서 바로 데이터를 읽어오므로 &lt;b&gt;응답 속도가 가장 빠르다&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 79.3023%; text-align: center;&quot;&gt;별도 캐시 서버를 구축하거나 관리할 필요 없이&lt;b&gt; 단순 구현&lt;/b&gt;이 가능하다(HashMap, Caffeine 등)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 20.6977%; text-align: center;&quot; rowspan=&quot;3&quot;&gt;단점&lt;/td&gt;
&lt;td style=&quot;width: 79.3023%; text-align: center;&quot;&gt;서버마다 캐시가 달라서 데이터 불일치 가능성이 있다&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 79.3023%; text-align: center;&quot;&gt;네트워크 지연이 존재하며 운영 복잡도가 상대적으로 크다&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 79.3023%; text-align: center;&quot;&gt;Redis 장애 시 모든 요청이 DB로 몰릴 수 있다&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2️⃣&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;분산 캐시 (Distributed Cache)&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: 분산 캐시는 여러 애플리케이션 서버 외부의 독립된 공간(별도 서버 또는 클러스터)에 데이터를 저장하고, 여러 애플리케이션 인스턴스가 이를 공유한다. 일반적으로 Redis, Memchached 같은 인메모리 서버를 사용한다. &lt;b&gt;데이터 일관성 유지에 용이&lt;/b&gt;하고 확장성에 유리하다. 비유하자면, 사무실 중앙에 있는 공용 화이트보드와 같다고 할 수 있다.&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;style4&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 20.814%; text-align: center;&quot; rowspan=&quot;3&quot;&gt;장점&lt;/td&gt;
&lt;td style=&quot;width: 79.186%; text-align: center;&quot;&gt;모든 서버가 동일한 캐시 데이터를 바라보므로 데이터 정합성을 유지하기 용이하다&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 79.186%; text-align: center;&quot;&gt;애플리케이션 서버 메모리와 무관하게 캐시 서버만 증설할 수 있다(수평 확장)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 79.186%; text-align: center;&quot;&gt;애플리케이션 서버가 꺼졌다가 켜져도 캐시 데이터가 그대로 유지된다(데이터 영속화)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 20.814%; text-align: center;&quot; rowspan=&quot;3&quot;&gt;단점&lt;/td&gt;
&lt;td style=&quot;width: 79.186%; text-align: center;&quot;&gt;네트워크 지연이 존재한다(로컬 캐시보다 상대적으로 느리며 DB보다는 빠르다)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 79.186%; text-align: center;&quot;&gt;운영 복잡성 및 모니터링에 드는 노력과 비용이 상대적으로 높다&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 79.186%; text-align: center;&quot;&gt;Redis 장애 시에 모든 요청이 DB로 몰릴 수 있다&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;❓&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;실무에서는 언제 무엇을 사용해야 할까?&lt;/b&gt;&lt;/h4&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;실무에서는 정답이 없고, 상황에 맞게 선택하거나 두 가지(L1/L2)를 조합하기도 한다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;로컬 캐시가 적합한 경우&lt;/b&gt;&lt;/p&gt;
&lt;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;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;분산 캐시가 적합한 경우&lt;/b&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;애플리케이션이 2대 이상의 서버로 운영될 때&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;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;☑️ 보통은 성능을 극대화하기 위해 로컬 캐시(L1)와 분산 캐시(L2)를 함께 사용하기도 한다. 먼저 가장 빠른 로컬 캐시를 확인하고, 없으면 분산 캐시를 확인하고, 거기에도 없으면 DB를 조회하는 순서이다.&lt;/p&gt;</description>
      <category>Programming/Server</category>
      <category>로컬 캐시</category>
      <category>분산 캐시</category>
      <author>_채채_</author>
      <guid isPermaLink="true">https://jaemi-gotong.tistory.com/34</guid>
      <comments>https://jaemi-gotong.tistory.com/34#entry34comment</comments>
      <pubDate>Tue, 21 Oct 2025 09:18:58 +0900</pubDate>
    </item>
    <item>
      <title>[Spring]@Cacheable, @CachePut, @CacheEvict</title>
      <link>https://jaemi-gotong.tistory.com/33</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;1️⃣&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;@Cacheable&lt;/b&gt;&lt;/h4&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;Spring Cache의 가장 기본적이자 핵심적인 어노테이션이다. 캐시가 있으면 메서드를 실행하지 않고, 캐시가 없으면 메서드를 실행하고 결과를 캐시에 저장한다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;동작 방식&lt;/b&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;메서드 호출 시, 지정된 캐시(Key)가 이미 존재하는지 확인.&lt;/li&gt;
&lt;li&gt;&lt;span&gt;존재하면 &lt;/span&gt;&lt;b&gt;DB나 외부 호출 없이 캐시의 결과를 바로 반환&lt;/b&gt;&lt;span&gt;.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;존재하지 않으면 메서드를 실행하고, 반환값을 캐시에 저장.&lt;/li&gt;
&lt;/ol&gt;
&lt;pre id=&quot;code_1761007107082&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// &quot;users&quot; 캐시 저장소에 userId를 키로 사용
@Cacheable(value = &quot;users&quot;, key = &quot;#userId&quot;)
public User findUserById(Long userId) {
    // 캐시에 없으면 이 로그가 찍히고 DB 조회가 발생한다.
    log.info(&quot;Fetching user from DB: {}&quot;, userId);
    return userRepository.findById(userId)
            .orElseThrow(() -&amp;gt; new EntityNotFoundException());
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;*value: 사용할 캐시 저장소의 이름&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;**key: 캐시를 식별하는 키(SpEL 사용 가능)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;언제 사용할까?&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;조회성(read-only)&lt;/b&gt;&lt;/span&gt; 데이터가 자주 호출될 때&lt;/li&gt;
&lt;li&gt;&lt;b&gt;변경 빈도가 낮은 데이터&lt;/b&gt;&lt;span&gt;를 캐싱할 때 (&lt;/span&gt;예: 유저 프로필, 코드 목록, 상품 카테고리 등)&lt;/li&gt;
&lt;li&gt;외부 API 호출 결과를 캐싱할 때&lt;/li&gt;
&lt;li&gt;비용이 많이 드는 DB 조회(e.g., findById)&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2️⃣&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;@CachePut&lt;/b&gt;&lt;/h4&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;@Cacheable과 자주 혼동되지만 결정적인 차이가 있는데 @CachePut은 캐시를 확인하지 않고 메서드를 항상 실행하며 그 결과를 캐시에 덮어쓴다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;동작 방식&lt;/b&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;메서드를 &lt;span&gt;&lt;b&gt;항상 실행&lt;/b&gt;&lt;/span&gt;한다.&lt;/li&gt;
&lt;li&gt;&lt;span&gt;실행 결과를 &lt;/span&gt;&lt;b&gt;캐시에 무조건 반영(업데이트)&lt;/b&gt;&lt;span&gt; 한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;메서드의 반환값을 그대로 반환한다.&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;pre id=&quot;code_1761007853267&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// &quot;users&quot; 캐시 저장소의 #user.id 키에 해당하는 캐시를 갱신
@CachePut(value = &quot;users&quot;, key = &quot;#user.id&quot;)
public User updateUser(User user) {
    // 이 메서드는 항상 실행되어 DB에 update 쿼리를 날린다.
    log.info(&quot;Updating user in DB: {}&quot;, user.getId());
    User updatedUser = userRepository.save(user); // DB 저장 (수정)
    return updatedUser; // 반환된 updatedUser가 캐시에 저장됨
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;언제 사용할까?&lt;/b&gt;&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;기존 데이터를 DB에서 수정한 후, 캐시에 저장된 값도 최신 값으로 동기화해야 할 때 사용(예: 사용자 정보 수정, 게시글 수정 등)&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;3️⃣&lt;/h4&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;@CacheEvict&lt;/b&gt;&lt;/h4&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;@CacheEvict는 이름 그대로 캐시에 저장된 데이터를 제거(Evict)하는 역할을 한다. 캐시를 비워 다음 요청 시 다시 로드되도록 한다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;동작 방식&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;메서드 본체를 실행한다. (기본값)&lt;/li&gt;
&lt;li&gt;메서드 실행이 성공적으로 완료되면, 지정된 key에 해당하는 캐시 항목을 삭제한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;pre id=&quot;code_1761051179919&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// &quot;users&quot; 캐시 저장소에서 userId 키에 해당하는 캐시 삭제
@CacheEvict(value = &quot;users&quot;, key = &quot;#userId&quot;)
public void deleteUser(Long userId) {
    // 이 메서드는 항상 실행되어 DB에서 delete 쿼리를 날린다.
    log.info(&quot;Deleting user from DB: {}&quot;, userId);
    userRepository.deleteById(userId);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1761051193965&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// &quot;users&quot; 캐시 저장소의 모든 데이터를 삭제
@CacheEvict(value = &quot;users&quot;, allEntries = true)
public void refreshAllUsersCache() {
    log.info(&quot;All user caches cleared.&quot;);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;* allEntries = true: key와 상관없이 해당 value(캐시 저장소)의 모든 항목을 삭제한다. (e.g., 캐시 전체 초기화 시 유용)&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;언제 사용할까?&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;DB에서 특정 데이터가 삭제되어 더 이상 캐시에 남아있으면 안 될 때.&lt;/li&gt;
&lt;li&gt;관련된 데이터가 너무 많이 변경되어 캐시 전체를 리셋해야 할 때&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt; ️ 표로 비교하기: @Cacheable vs @CachePut vs @CacheEvict&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;style4&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;background-color: #f3c000;&quot;&gt;&lt;b&gt;어노테이션&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;background-color: #f3c000;&quot;&gt;&lt;b&gt;메서드 실행 여부&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;background-color: #f3c000;&quot;&gt;&lt;b&gt;캐시 동작&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;background-color: #f3c000;&quot;&gt;&lt;b&gt;주요 사용 시점 (CRUD)&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;@Cacheable&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;캐시가 &lt;b&gt;없을 때만&lt;/b&gt; 실행&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;캐시 &lt;b&gt;조회&lt;/b&gt; 및 &lt;b&gt;저장&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;Read&lt;/b&gt; (조회)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;@CachePut&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;항상&lt;/b&gt; 실행&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;캐시 &lt;b&gt;갱신&lt;/b&gt; (덮어쓰기)&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;Update&lt;/b&gt; (수정)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;@CacheEvict&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;항상&lt;/b&gt; 실행&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;캐시 &lt;b&gt;삭제&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;b&gt;Delete&lt;/b&gt; (삭제)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Programming/Spring</category>
      <author>_채채_</author>
      <guid isPermaLink="true">https://jaemi-gotong.tistory.com/33</guid>
      <comments>https://jaemi-gotong.tistory.com/33#entry33comment</comments>
      <pubDate>Mon, 20 Oct 2025 09:31:31 +0900</pubDate>
    </item>
  </channel>
</rss>