<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>개발스토리지 </title>
    <link>https://believekim.tistory.com/</link>
    <description>초보 개발자의 개발블로그 </description>
    <language>ko</language>
    <pubDate>Tue, 7 Apr 2026 12:26:45 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>believekim</managingEditor>
    <image>
      <title>개발스토리지 </title>
      <url>https://tistory1.daumcdn.net/tistory/7485727/attach/0550423c4e1c45be8ee4dab38656cc37</url>
      <link>https://believekim.tistory.com</link>
    </image>
    <item>
      <title>[깃허브] Gist로 깃허브 꾸미기</title>
      <link>https://believekim.tistory.com/entry/%EA%B9%83%ED%97%88%EB%B8%8C-Gist%EB%A1%9C-%EA%B9%83%ED%97%88%EB%B8%8C-%EA%BE%B8%EB%AF%B8%EA%B8%B0</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;깃허브를 꾸미다 보니 gist라는 기능을 알게 되어&lt;br /&gt;&lt;/span&gt;적용방법을 정리해보았다&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. Github Gist란?&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;짧은 코드 조각, 메모, 또는 간단한 텍스트 파일을 공유하기 위한 서비스&lt;/li&gt;
&lt;li&gt;별도의 저장소(Repository)를 만들지 않고도 파일 하나만 뚝딱 생성할 수 있는 것이 특징&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1277&quot; data-origin-height=&quot;607&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b6tSqB/dJMcag5fSKt/o0XrCg7ndxEGLyCDpUKnZk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b6tSqB/dJMcag5fSKt/o0XrCg7ndxEGLyCDpUKnZk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b6tSqB/dJMcag5fSKt/o0XrCg7ndxEGLyCDpUKnZk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb6tSqB%2FdJMcag5fSKt%2Fo0XrCg7ndxEGLyCDpUKnZk%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;1277&quot; height=&quot;607&quot; data-origin-width=&quot;1277&quot; data-origin-height=&quot;607&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. Gist 생성&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://gist.github.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Gist&lt;/a&gt;에 접속&lt;/li&gt;
&lt;li&gt;아래의 번호 순서대로 Gist 생성&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1820&quot; data-origin-height=&quot;752&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d3pwbi/dJMcahQCtbW/ueEFWKRnCu4rxr1ZsUlZlk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d3pwbi/dJMcahQCtbW/ueEFWKRnCu4rxr1ZsUlZlk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d3pwbi/dJMcahQCtbW/ueEFWKRnCu4rxr1ZsUlZlk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd3pwbi%2FdJMcahQCtbW%2FueEFWKRnCu4rxr1ZsUlZlk%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;1820&quot; height=&quot;752&quot; data-origin-width=&quot;1820&quot; data-origin-height=&quot;752&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;게시글 경로 url을 복사&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1797&quot; data-origin-height=&quot;679&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bbNG44/dJMcabJD7m5/r9d3KMXELoUUTDXKKEEj4k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bbNG44/dJMcabJD7m5/r9d3KMXELoUUTDXKKEEj4k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bbNG44/dJMcabJD7m5/r9d3KMXELoUUTDXKKEEj4k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbbNG44%2FdJMcabJD7m5%2Fr9d3KMXELoUUTDXKKEEj4k%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;1797&quot; height=&quot;679&quot; data-origin-width=&quot;1797&quot; data-origin-height=&quot;679&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. Github 환경변수 등록&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;GH_TOKEN 발급&lt;/li&gt;
&lt;li&gt;프로필 클릭 -&amp;gt; settings&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock floatLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-01-03 오후 7.33.15.png&quot; data-origin-width=&quot;284&quot; data-origin-height=&quot;431&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FZTvH/dJMcad1Hc6v/r1QCS5frlLafHR7FyGPVkk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FZTvH/dJMcad1Hc6v/r1QCS5frlLafHR7FyGPVkk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FZTvH/dJMcad1Hc6v/r1QCS5frlLafHR7FyGPVkk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFZTvH%2FdJMcad1Hc6v%2Fr1QCS5frlLafHR7FyGPVkk%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;284&quot; height=&quot;431&quot; data-filename=&quot;스크린샷 2026-01-03 오후 7.33.15.png&quot; data-origin-width=&quot;284&quot; data-origin-height=&quot;431&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&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;
&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;
&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;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Developer settings 클릭&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-01-03 오후 7.34.16.png&quot; data-origin-width=&quot;325&quot; data-origin-height=&quot;492&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dVHMjy/dJMcahb0pjb/6DNeanreSRBPeB5kVxt40k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dVHMjy/dJMcahb0pjb/6DNeanreSRBPeB5kVxt40k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dVHMjy/dJMcahb0pjb/6DNeanreSRBPeB5kVxt40k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdVHMjy%2FdJMcahb0pjb%2F6DNeanreSRBPeB5kVxt40k%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;325&quot; height=&quot;492&quot; data-filename=&quot;스크린샷 2026-01-03 오후 7.34.16.png&quot; data-origin-width=&quot;325&quot; data-origin-height=&quot;492&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Personal access tokens -&amp;gt; Token(classic) 클릭 -&amp;gt; Generate new token을 클릭하여&amp;nbsp; 발급&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-01-03 오후 7.36.29.png&quot; data-origin-width=&quot;409&quot; data-origin-height=&quot;213&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JnaGs/dJMcafrJzXY/MWZhYORo4ltskkT1c4jXLk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JnaGs/dJMcafrJzXY/MWZhYORo4ltskkT1c4jXLk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JnaGs/dJMcafrJzXY/MWZhYORo4ltskkT1c4jXLk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJnaGs%2FdJMcafrJzXY%2FMWZhYORo4ltskkT1c4jXLk%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;409&quot; height=&quot;213&quot; data-filename=&quot;스크린샷 2026-01-03 오후 7.36.29.png&quot; data-origin-width=&quot;409&quot; data-origin-height=&quot;213&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;자신의 레포지토리로 돌아와 아래의 이미지대로 환경변수 값을 적용&lt;/li&gt;
&lt;li&gt;GIST_ID_*는 위에서 복사해두었던 게시글url값 적용&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1177&quot; data-origin-height=&quot;778&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/6bDhE/dJMcafZyKx2/FiBY054SnLg845KIgqq8FK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/6bDhE/dJMcafZyKx2/FiBY054SnLg845KIgqq8FK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/6bDhE/dJMcafZyKx2/FiBY054SnLg845KIgqq8FK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6bDhE%2FdJMcafZyKx2%2FFiBY054SnLg845KIgqq8FK%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;1177&quot; height=&quot;778&quot; data-origin-width=&quot;1177&quot; data-origin-height=&quot;778&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4. Git Action 파일 생성&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;필자는 .github/workflows/gist.yml 로 생성&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1767436792702&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;name: Update All Gists (Routine &amp;amp; Stats)

on:
  schedule:
    - cron: &quot;0 0 * * *&quot; # 매일 자정 자동 실행
  workflow_dispatch: # 수동 실행 버튼 활성화
  push:
    branches:
      - main
      - master

jobs:
  update-gists:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      # 1. Routine Gist 업데이트 (I'm a night  )
      - name: Update Routine Gist
        uses: maxam2017/productive-box@master
        env:
          GH_TOKEN: ${{ secrets.GH_TOKEN }}
          GIST_ID: ${{ secrets.GIST_ID_ROUTINE }}
          TIMEZONE: Asia/Seoul

      # 2. Statistics Gist 업데이트 (GitHub Stats Box)
      - name: Update Statistics Gist
        run: npx github-stats-box@1
        env:
          GH_TOKEN: ${{ secrets.GH_TOKEN }}
          GIST_ID: ${{ secrets.GIST_ID_STATISTICS }}
          ALL_COMMITS: true
          K_FORMAT: false&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style3&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;5. 결과 확인&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Action으로 들어가 정상작동했는지 확인&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;738&quot; data-origin-height=&quot;505&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c7wSr4/dJMcajni21q/LcJxLxb9MKE0V1w5BPCJi0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c7wSr4/dJMcajni21q/LcJxLxb9MKE0V1w5BPCJi0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c7wSr4/dJMcajni21q/LcJxLxb9MKE0V1w5BPCJi0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc7wSr4%2FdJMcajni21q%2FLcJxLxb9MKE0V1w5BPCJi0%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;738&quot; height=&quot;505&quot; data-origin-width=&quot;738&quot; data-origin-height=&quot;505&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;메인페이지에서 Customize your pins 클릭&lt;/li&gt;
&lt;li&gt;Show: 항목에서 Gists를 클릭하면 생성된 Gist가 노출(public으로 만들어야 노출됨)&lt;/li&gt;
&lt;li&gt;원하는 Gist를 선택하면 적용완료!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;936&quot; data-origin-height=&quot;624&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dEnKdQ/dJMcajni212/yFkK6p1LNNKaYjz4A7OI2k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dEnKdQ/dJMcajni212/yFkK6p1LNNKaYjz4A7OI2k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dEnKdQ/dJMcajni212/yFkK6p1LNNKaYjz4A7OI2k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdEnKdQ%2FdJMcajni212%2FyFkK6p1LNNKaYjz4A7OI2k%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;936&quot; height=&quot;624&quot; data-origin-width=&quot;936&quot; data-origin-height=&quot;624&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/pleasebelieveme&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/pleasebelieveme&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1767437085433&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;profile&quot; data-og-title=&quot;pleasebelieveme - Overview&quot; data-og-description=&quot;pleasebelieveme has 69 repositories available. Follow their code on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/pleasebelieveme&quot; data-og-url=&quot;https://github.com/pleasebelieveme&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bBVnYg/hyZQWh8la8/l6glnbRUfhNfLSqSP1XAc0/img.jpg?width=460&amp;amp;height=460&amp;amp;face=0_0_460_460,https://scrap.kakaocdn.net/dn/sJtMP/hyZPHtnann/tK2iK4yngdaTODC1uBmEAk/img.jpg?width=460&amp;amp;height=460&amp;amp;face=0_0_460_460&quot;&gt;&lt;a href=&quot;https://github.com/pleasebelieveme&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/pleasebelieveme&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bBVnYg/hyZQWh8la8/l6glnbRUfhNfLSqSP1XAc0/img.jpg?width=460&amp;amp;height=460&amp;amp;face=0_0_460_460,https://scrap.kakaocdn.net/dn/sJtMP/hyZPHtnann/tK2iK4yngdaTODC1uBmEAk/img.jpg?width=460&amp;amp;height=460&amp;amp;face=0_0_460_460');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;pleasebelieveme - Overview&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;pleasebelieveme has 69 repositories available. Follow their code on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>툴/깃허브</category>
      <category>gist</category>
      <category>Git Action</category>
      <category>github gist</category>
      <category>깃허브꾸미기</category>
      <author>believekim</author>
      <guid isPermaLink="true">https://believekim.tistory.com/122</guid>
      <comments>https://believekim.tistory.com/entry/%EA%B9%83%ED%97%88%EB%B8%8C-Gist%EB%A1%9C-%EA%B9%83%ED%97%88%EB%B8%8C-%EA%BE%B8%EB%AF%B8%EA%B8%B0#entry122comment</comments>
      <pubDate>Sat, 3 Jan 2026 19:45:19 +0900</pubDate>
    </item>
    <item>
      <title>[깃허브] 깃허브 README 애니메이션 꾸미기 (pecman, snake)</title>
      <link>https://believekim.tistory.com/entry/%EA%B9%83%ED%97%88%EB%B8%8C-%EA%B9%83%ED%97%88%EB%B8%8C-README-%EC%95%A0%EB%8B%88%EB%A9%94%EC%9D%B4%EC%85%98-%EA%BE%B8%EB%AF%B8%EA%B8%B0-pecman-snake</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;취업을 준비하기에 앞서 깃허브의 README를 꾸며보았다&lt;br /&gt;쓸데없이 애니메이션만 적용했는데 재밌다..&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. 들어가며&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;내 잔디 위에서 팩맨이 돌아다니고, 스네이크가 먹이를 먹는 재미있는 애니메이션을 GitHub 프로필에 적용하는 방법을 소개&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-01-02 오후 3.04.35.png&quot; data-origin-width=&quot;1754&quot; data-origin-height=&quot;1518&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d4iDnr/dJMcahXoFnm/c5g36CGh7dkmhgji5Th5pK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d4iDnr/dJMcahXoFnm/c5g36CGh7dkmhgji5Th5pK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d4iDnr/dJMcahXoFnm/c5g36CGh7dkmhgji5Th5pK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd4iDnr%2FdJMcahXoFnm%2Fc5g36CGh7dkmhgji5Th5pK%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;1754&quot; height=&quot;1518&quot; data-filename=&quot;스크린샷 2026-01-02 오후 3.04.35.png&quot; data-origin-width=&quot;1754&quot; data-origin-height=&quot;1518&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&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;a style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot; href=&quot;https://profile-readme-generator.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://profile-readme-generator.com/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;figure id=&quot;og_1767334090327&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;Profile Readme Generator&quot; data-og-description=&quot;Beautify your github profile with this amazing tool, creating the readme your way in a simple and fast way! The best profile readme generator you will find!&quot; data-og-host=&quot;profile-readme-generator.com&quot; data-og-source-url=&quot;https://profile-readme-generator.com/&quot; data-og-url=&quot;https://profile-readme-generator.com&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/sOhH5/hyZQ0yklvI/5WqVgqZvgATuOfbpVLSh6k/img.png?width=1879&amp;amp;height=932&amp;amp;face=0_0_1879_932,https://scrap.kakaocdn.net/dn/eWuIK/hyZQqZH2xD/sxg6Pm2I7hBvFtPdbkYdE0/img.png?width=1879&amp;amp;height=932&amp;amp;face=0_0_1879_932,https://scrap.kakaocdn.net/dn/ouMQn/hyZQzh1l4J/8PxgPsWc6OlbFg44unZCk1/img.jpg?width=383&amp;amp;height=500&amp;amp;face=0_0_383_500&quot;&gt;&lt;a href=&quot;https://profile-readme-generator.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://profile-readme-generator.com/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/sOhH5/hyZQ0yklvI/5WqVgqZvgATuOfbpVLSh6k/img.png?width=1879&amp;amp;height=932&amp;amp;face=0_0_1879_932,https://scrap.kakaocdn.net/dn/eWuIK/hyZQqZH2xD/sxg6Pm2I7hBvFtPdbkYdE0/img.png?width=1879&amp;amp;height=932&amp;amp;face=0_0_1879_932,https://scrap.kakaocdn.net/dn/ouMQn/hyZQzh1l4J/8PxgPsWc6OlbFg44unZCk1/img.jpg?width=383&amp;amp;height=500&amp;amp;face=0_0_383_500');&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;Profile Readme Generator&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Beautify your github profile with this amazing tool, creating the readme your way in a simple and fast way! The best profile readme generator you will find!&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;profile-readme-generator.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://www.gitanimals.org/en_US?utm_medium=image&amp;amp;utm_source=pleasebelieveme&amp;amp;utm_content=line&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.gitanimals.org/en_US?utm_medium=image&amp;amp;utm_source=pleasebelieveme&amp;amp;utm_content=line&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;figure id=&quot;og_1767334148211&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;GitAnimals&quot; data-og-description=&quot;깃허브 활동으로 펫을 키우세요!&quot; data-og-host=&quot;www.gitanimals.org&quot; data-og-source-url=&quot;https://www.gitanimals.org/en_US?utm_medium=image&amp;amp;utm_source=pleasebelieveme&amp;amp;utm_content=line&quot; data-og-url=&quot;https://www.gitanimals.org&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/ba8JLX/hyZPOzaREf/HDoHTTwXg9BKdOkjDjrd31/img.png?width=1600&amp;amp;height=800&amp;amp;face=0_0_1600_800,https://scrap.kakaocdn.net/dn/gxyqx/hyZQ3V61Jd/r9AiVkiQsfavTM5yh4PE71/img.png?width=1600&amp;amp;height=800&amp;amp;face=0_0_1600_800&quot;&gt;&lt;a href=&quot;https://www.gitanimals.org/en_US?utm_medium=image&amp;amp;utm_source=pleasebelieveme&amp;amp;utm_content=line&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.gitanimals.org/en_US?utm_medium=image&amp;amp;utm_source=pleasebelieveme&amp;amp;utm_content=line&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/ba8JLX/hyZPOzaREf/HDoHTTwXg9BKdOkjDjrd31/img.png?width=1600&amp;amp;height=800&amp;amp;face=0_0_1600_800,https://scrap.kakaocdn.net/dn/gxyqx/hyZQ3V61Jd/r9AiVkiQsfavTM5yh4PE71/img.png?width=1600&amp;amp;height=800&amp;amp;face=0_0_1600_800');&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;GitAnimals&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;www.gitanimals.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. pecman 적용&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;./github/workflows/pecma.yml 파일 생성&lt;/li&gt;
&lt;li&gt;매일 자정(UTC)에 실행되어 팩맨이 잔디를 먹는 .svg 파일을 생성&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1767334458969&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;name: Generate pacman animation

on:
  schedule:
    - cron: &quot;0 0 * * *&quot;
  workflow_dispatch:

jobs:
  generate:
    permissions:
      contents: write
    runs-on: ubuntu-latest
    timeout-minutes: 5

    steps:
      - name: Generate pacman-contribution-graph.svg
        uses: abozanona/pacman-contribution-graph@main
        with:
          github_user_name: ${{ github.repository_owner }}
          theme: dark
          output: dist/pacman-contribution-graph.svg

      - name: Push pacman-contribution-graph.svg to the output branch
        uses: crazy-max/ghaction-github-pages@v3.1.0
        with:
          target_branch: output
          build_dir: dist
          keep_history: true
          commit_message: &quot;update pacman ${{ github.run_id }}&quot;
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;README.md 파일에 적용&lt;/li&gt;
&lt;li&gt;pleasebelieveme에 본인의 아이디/레포지토리이름으로 변경&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1767334579153&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;h3&amp;gt;  Pacman eats my daily GitHub contributions&amp;lt;/h3&amp;gt;

&amp;lt;img
  src=&quot;https://raw.githubusercontent.com/pleasebelieveme/pleasebelieveme/output/pacman-contribution-graph-dark.svg?v=1&quot;
/&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. snake 적용&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;./github/workflows/snake.yml 파일 생성&lt;/li&gt;
&lt;li&gt;매일 자정(UTC)에 실행되어 뱀이 잔디를 먹는 .svg 파일을 생성&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1767334740002&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;name: Generate snake animation

on:
  schedule:
    - cron: &quot;0 0 * * *&quot;
  workflow_dispatch:

jobs:
  generate:
    permissions:
      contents: write
    runs-on: ubuntu-latest
    steps:
      - name: generate snake.svg
        uses: Platane/snk/svg-only@v3
        with:
          github_user_name: ${{ github.repository_owner }}
          outputs: dist/snake.svg?palette=github-dark

      - name: push snake.svg to the output branch
        uses: crazy-max/ghaction-github-pages@v3.1.0
        with:
          target_branch: output
          build_dir: dist
          commit_message: &quot;update snake ${{ github.run_id }}&quot;
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;README.md 파일에 적용&lt;/li&gt;
&lt;li&gt;pleasebelieveme에 본인의 아이디/레포지토리이름으로 변경&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1767334665136&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;h3&amp;gt;  Snake Contribution Animation&amp;lt;/h3&amp;gt;
&amp;lt;img
  src=&quot;https://raw.githubusercontent.com/pleasebelieveme/pleasebelieveme/output/snake.svg?cache=1&quot;
  alt=&quot;Snake animation&quot;
/&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4. Git Animals&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;회원가입 후 commit포인트를 모아 캐릭터를 모으로 농장을 꾸민다&lt;/li&gt;
&lt;li&gt;&lt;a style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot; href=&quot;https://www.gitanimals.org/en_US?utm_medium=image&amp;amp;utm_source=pleasebelieveme&amp;amp;utm_content=line&quot;&gt;https://www.gitanimals.org/en_US?utm_medium=image&amp;amp;utm_source=pleasebelieveme&amp;amp;utm_content=line&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;figure id=&quot;og_1767335383159&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;GitAnimals&quot; data-og-description=&quot;깃허브 활동으로 펫을 키우세요!&quot; data-og-host=&quot;www.gitanimals.org&quot; data-og-source-url=&quot;https://www.gitanimals.org/en_US?utm_medium=image&amp;amp;utm_source=pleasebelieveme&amp;amp;utm_content=line&quot; data-og-url=&quot;https://www.gitanimals.org&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/ba8JLX/hyZPOzaREf/HDoHTTwXg9BKdOkjDjrd31/img.png?width=1600&amp;amp;height=800&amp;amp;face=0_0_1600_800,https://scrap.kakaocdn.net/dn/gxyqx/hyZQ3V61Jd/r9AiVkiQsfavTM5yh4PE71/img.png?width=1600&amp;amp;height=800&amp;amp;face=0_0_1600_800&quot;&gt;&lt;a href=&quot;https://www.gitanimals.org/en_US?utm_medium=image&amp;amp;utm_source=pleasebelieveme&amp;amp;utm_content=line&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.gitanimals.org/en_US?utm_medium=image&amp;amp;utm_source=pleasebelieveme&amp;amp;utm_content=line&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/ba8JLX/hyZPOzaREf/HDoHTTwXg9BKdOkjDjrd31/img.png?width=1600&amp;amp;height=800&amp;amp;face=0_0_1600_800,https://scrap.kakaocdn.net/dn/gxyqx/hyZQ3V61Jd/r9AiVkiQsfavTM5yh4PE71/img.png?width=1600&amp;amp;height=800&amp;amp;face=0_0_1600_800');&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;GitAnimals&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;www.gitanimals.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;아래의 사이트에서 html코드를 복사해서 내 README.md 파일에 붙여넣기&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/git-goods/gitanimals&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/git-goods/gitanimals&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1767335632950&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - git-goods/gitanimals:   깃허브 활동으로 펫을 키우세요 / Have pet in your github&quot; data-og-description=&quot;  깃허브 활동으로 펫을 키우세요 / Have pet in your github . Contribute to git-goods/gitanimals development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/git-goods/gitanimals&quot; data-og-url=&quot;https://github.com/git-goods/gitanimals&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/boVL4v/hyZQTezCb9/NamYiP8plOi3Ikp8Xd8TVk/img.png?width=1280&amp;amp;height=640&amp;amp;face=0_0_1280_640,https://scrap.kakaocdn.net/dn/knnzM/hyZQX9qBp1/6iKqqNVbPDQpGrXJKyzyuk/img.png?width=1280&amp;amp;height=640&amp;amp;face=0_0_1280_640&quot;&gt;&lt;a href=&quot;https://github.com/git-goods/gitanimals&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/git-goods/gitanimals&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/boVL4v/hyZQTezCb9/NamYiP8plOi3Ikp8Xd8TVk/img.png?width=1280&amp;amp;height=640&amp;amp;face=0_0_1280_640,https://scrap.kakaocdn.net/dn/knnzM/hyZQX9qBp1/6iKqqNVbPDQpGrXJKyzyuk/img.png?width=1280&amp;amp;height=640&amp;amp;face=0_0_1280_640');&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;GitHub - git-goods/gitanimals:   깃허브 활동으로 펫을 키우세요 / Have pet in your github&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;  깃허브 활동으로 펫을 키우세요 / Have pet in your github . Contribute to git-goods/gitanimals development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-01-02 오후 3.34.52.png&quot; data-origin-width=&quot;1756&quot; data-origin-height=&quot;810&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bD1xk5/dJMb99Sz0JV/95IUPWBfTzSglrvXQfaBbK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bD1xk5/dJMb99Sz0JV/95IUPWBfTzSglrvXQfaBbK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bD1xk5/dJMb99Sz0JV/95IUPWBfTzSglrvXQfaBbK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbD1xk5%2FdJMb99Sz0JV%2F95IUPWBfTzSglrvXQfaBbK%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;1756&quot; height=&quot;810&quot; data-filename=&quot;스크린샷 2026-01-02 오후 3.34.52.png&quot; data-origin-width=&quot;1756&quot; data-origin-height=&quot;810&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;5. 트러블슈팅&lt;/b&gt;&lt;/h2&gt;
&lt;p data-path-to-node=&quot;5&quot; data-ke-size=&quot;size16&quot;&gt;일반적으로 main 브랜치에 코드를 올리지만,&lt;/p&gt;
&lt;p data-path-to-node=&quot;5&quot; data-ke-size=&quot;size16&quot;&gt;애니메이션 액션들은 생성된 .svg 이미지 파일들을 관리하기 쉽게 별도의&lt;/p&gt;
&lt;p data-path-to-node=&quot;5&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b data-index-in-node=&quot;71&quot; data-path-to-node=&quot;5&quot;&gt;output 브랜치&lt;/b&gt;에 따로 저장하도록 설정되어 브랜치가 자동적으로 생성&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-01-02 오후 3.22.18.png&quot; data-origin-width=&quot;2670&quot; data-origin-height=&quot;914&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bUIKOG/dJMcahbZZpc/Sr4Bb3iK2yXZCQRYTkhCn1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bUIKOG/dJMcahbZZpc/Sr4Bb3iK2yXZCQRYTkhCn1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bUIKOG/dJMcahbZZpc/Sr4Bb3iK2yXZCQRYTkhCn1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbUIKOG%2FdJMcahbZZpc%2FSr4Bb3iK2yXZCQRYTkhCn1%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;2670&quot; height=&quot;914&quot; data-filename=&quot;스크린샷 2026-01-02 오후 3.22.18.png&quot; data-origin-width=&quot;2670&quot; data-origin-height=&quot;914&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&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;GitHub Actions가 내 레포지토리에 파일을 생성하고 커밋(Push)하려면 쓰기 권한이 필요&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;해당 GitHub 레포지토리의 Settings 탭으로 들어갑니다.&lt;/li&gt;
&lt;li&gt;왼쪽 사이드바에서 Actions &amp;gt; General을 클릭합니다.&lt;/li&gt;
&lt;li&gt;페이지 하단부의 Workflow permissions 항목을 찾습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2332&quot; data-origin-height=&quot;956&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/75oFe/dJMcai9LPPa/IEjcnfN1gPJ8A0LP0jKWs0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/75oFe/dJMcai9LPPa/IEjcnfN1gPJ8A0LP0jKWs0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/75oFe/dJMcai9LPPa/IEjcnfN1gPJ8A0LP0jKWs0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F75oFe%2FdJMcai9LPPa%2FIEjcnfN1gPJ8A0LP0jKWs0%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;2332&quot; height=&quot;956&quot; data-origin-width=&quot;2332&quot; data-origin-height=&quot;956&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Read and write permissions를 체크하고&lt;span&gt;&amp;nbsp;&lt;/span&gt;Save 클릭&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2026-01-02 오후 3.26.31.png&quot; data-origin-width=&quot;1606&quot; data-origin-height=&quot;698&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HsC8H/dJMcab3VvpL/v0mT5w0jeLsXPnyzG8KT00/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HsC8H/dJMcab3VvpL/v0mT5w0jeLsXPnyzG8KT00/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HsC8H/dJMcab3VvpL/v0mT5w0jeLsXPnyzG8KT00/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHsC8H%2FdJMcab3VvpL%2Fv0mT5w0jeLsXPnyzG8KT00%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;1606&quot; height=&quot;698&quot; data-filename=&quot;스크린샷 2026-01-02 오후 3.26.31.png&quot; data-origin-width=&quot;1606&quot; data-origin-height=&quot;698&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/pleasebelieveme&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/pleasebelieveme&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1767335925595&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;profile&quot; data-og-title=&quot;pleasebelieveme - Overview&quot; data-og-description=&quot;pleasebelieveme has 69 repositories available. Follow their code on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/pleasebelieveme&quot; data-og-url=&quot;https://github.com/pleasebelieveme&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cFeFm0/hyZQwS9duE/SKnjIc6Kd3S1hY52ttHWoK/img.jpg?width=460&amp;amp;height=460&amp;amp;face=0_0_460_460,https://scrap.kakaocdn.net/dn/bpXGtK/hyZQZlSxph/bLxTepYNsHwLA6OPB67YRk/img.jpg?width=460&amp;amp;height=460&amp;amp;face=0_0_460_460&quot;&gt;&lt;a href=&quot;https://github.com/pleasebelieveme&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/pleasebelieveme&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cFeFm0/hyZQwS9duE/SKnjIc6Kd3S1hY52ttHWoK/img.jpg?width=460&amp;amp;height=460&amp;amp;face=0_0_460_460,https://scrap.kakaocdn.net/dn/bpXGtK/hyZQZlSxph/bLxTepYNsHwLA6OPB67YRk/img.jpg?width=460&amp;amp;height=460&amp;amp;face=0_0_460_460');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;pleasebelieveme - Overview&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;pleasebelieveme has 69 repositories available. Follow their code on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;text-align: center;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;역시 코딩보다 재밌다&lt;/b&gt;&lt;/h3&gt;
&lt;figure contenteditable=&quot;false&quot; data-ke-type=&quot;emoticon&quot; data-ke-align=&quot;alignCenter&quot; data-emoticon-type=&quot;challenge&quot; data-emoticon-name=&quot;020&quot; data-emoticon-isanimation=&quot;false&quot; data-emoticon-src=&quot;https://t1.daumcdn.net/keditor/emoticon/challenge/large/020.png&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/keditor/emoticon/challenge/large/020.png&quot; width=&quot;150&quot; /&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>툴/깃허브</category>
      <category>github</category>
      <category>readme</category>
      <category>readme꾸미기</category>
      <author>believekim</author>
      <guid isPermaLink="true">https://believekim.tistory.com/121</guid>
      <comments>https://believekim.tistory.com/entry/%EA%B9%83%ED%97%88%EB%B8%8C-%EA%B9%83%ED%97%88%EB%B8%8C-README-%EC%95%A0%EB%8B%88%EB%A9%94%EC%9D%B4%EC%85%98-%EA%BE%B8%EB%AF%B8%EA%B8%B0-pecman-snake#entry121comment</comments>
      <pubDate>Fri, 2 Jan 2026 15:37:51 +0900</pubDate>
    </item>
    <item>
      <title>[쉘스크립트] MSA 개발 환경에서 여러 서버 포트 종료 자동화스크립트 For MacOS</title>
      <link>https://believekim.tistory.com/entry/%EC%89%98%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-MSA-%EA%B0%9C%EB%B0%9C-%ED%99%98%EA%B2%BD%EC%97%90%EC%84%9C-%EC%97%AC%EB%9F%AC-%EC%84%9C%EB%B2%84-%ED%8F%AC%ED%8A%B8-%EC%A2%85%EB%A3%8C-%EC%9E%90%EB%8F%99%ED%99%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-For-MacOS</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;MSA로 개발을 하다가 인텔리제이가 멈춰 강제종료하였다. &lt;br /&gt;다시 실행하려고 하니 총 12개의 서버의 포트가 충돌이 나서 쉘스크립트를 만들어 보았다.&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. kill_duplicate_servers.sh 작성&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;띄어쓰기는 _를 사용&lt;/li&gt;
&lt;li&gt;servers=(&amp;lt;서버이름&amp;gt;:&amp;lt;포트번호&amp;gt;)의 내용을 자신의 상황에 맞게 수정&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1763296766782&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#!/bin/bash

# ===========================
# 서버 포트 점검 및 종료 스크립트 (Bash 3.x 호환)
# ===========================

# 서버명과 포트를 &quot;서버명:포트&quot; 형태로 배열에 저장
servers=(
  &quot;AI_Server:20010&quot;
  &quot;Company_Server:20020&quot;
  &quot;Delivery_Server:20030&quot;
  &quot;Hub_Server:20040&quot;
  &quot;Hub_Route_Server:20050&quot;
  &quot;Order_Server:20060&quot;
  &quot;Product_Server:20070&quot;
  &quot;User_Server:20080&quot;
  &quot;Slack_Server:20090&quot;
  &quot;Eureka_Server:8761&quot;
  &quot;Config_Server:8888&quot;
  &quot;Gateway:8080&quot;
)

echo &quot;====== 서버 포트 점검 및 종료 ======&quot;

for entry in &quot;${servers[@]}&quot;; do
  name=$(echo $entry | cut -d':' -f1)
  port=$(echo $entry | cut -d':' -f2)

  pid=$(lsof -ti tcp:$port)

  if [ -n &quot;$pid&quot; ]; then
    echo &quot;$name (포트 $port) 실행중 PID=$pid -&amp;gt; 종료&quot;
    kill -9 $pid
  else
    echo &quot;$name (포트 $port) 실행중 아님&quot;
  fi
done

echo &quot;====== 완료 ======&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. 실행방법&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;파일 생성&lt;/li&gt;
&lt;li&gt;나는 vi를 사용했지만 nano, cat 등등 본인이 편한대로 생성하면 된다&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1763296876696&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;vi kill_duplicate_servers.sh&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; 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;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1763296939962&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;chmod +x kill_duplicate_servers.sh&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; 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;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1763296956561&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;./kill_duplicate_servers.sh&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. 결과화면&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-11-16 오후 9.42.59.png&quot; data-origin-width=&quot;1386&quot; data-origin-height=&quot;628&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vibOP/dJMcafEYo09/QJVo2wSwUdyQRrjWpgaK11/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vibOP/dJMcafEYo09/QJVo2wSwUdyQRrjWpgaK11/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vibOP/dJMcafEYo09/QJVo2wSwUdyQRrjWpgaK11/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvibOP%2FdJMcafEYo09%2FQJVo2wSwUdyQRrjWpgaK11%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;1386&quot; height=&quot;628&quot; data-filename=&quot;스크린샷 2025-11-16 오후 9.42.59.png&quot; data-origin-width=&quot;1386&quot; data-origin-height=&quot;628&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>운영체제/리눅스</category>
      <category>멀티서버종료자동화</category>
      <category>쉘스크립트</category>
      <author>believekim</author>
      <guid isPermaLink="true">https://believekim.tistory.com/120</guid>
      <comments>https://believekim.tistory.com/entry/%EC%89%98%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-MSA-%EA%B0%9C%EB%B0%9C-%ED%99%98%EA%B2%BD%EC%97%90%EC%84%9C-%EC%97%AC%EB%9F%AC-%EC%84%9C%EB%B2%84-%ED%8F%AC%ED%8A%B8-%EC%A2%85%EB%A3%8C-%EC%9E%90%EB%8F%99%ED%99%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-For-MacOS#entry120comment</comments>
      <pubDate>Sun, 16 Nov 2025 21:43:38 +0900</pubDate>
    </item>
    <item>
      <title>[RestFul API] PUT vs PATCH vs POST, 언제 어떤 메서드를 써야 할까?</title>
      <link>https://believekim.tistory.com/entry/RestFul-API-PUT-vs-PATCH-vs-POST-%EC%96%B8%EC%A0%9C-%EC%96%B4%EB%96%A4-%EB%A9%94%EC%84%9C%EB%93%9C%EB%A5%BC-%EC%8D%A8%EC%95%BC-%ED%95%A0%EA%B9%8C</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;API 명세서를 작성하다가 PUT, PATCH, POST을 어떻게 사용해야 할지 혼란스러웠다.&amp;nbsp;&lt;br /&gt;멱등성이 있으면 PUT, 없으면 PATCH라는 원칙도 배우지만 그 기준만으로는 혼란을 해결하지 못했다.&lt;br /&gt;그래서 설계원칙을 정리해보았다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&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. RESTful API 설계의 기본 원칙&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;REST 설계의 핵심은 리소스(Resource) 중심이기에&lt;/li&gt;
&lt;li&gt;URL에는 명사(thing)만 들어가야 하고, 행동(action)은 HTTP 메서드로 표현&lt;/li&gt;
&lt;li&gt;&quot;무엇을 조작할 것인가&quot;를 URL로&lt;/li&gt;
&lt;li&gt;&quot;어떻게 조작할 것인가&quot;를 HTTP 메서드로 구분&lt;/li&gt;
&lt;/ul&gt;
&lt;table style=&quot;height: 76px;&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style5&quot;&gt;
&lt;thead&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;th style=&quot;height: 19px;&quot;&gt;&amp;nbsp;&lt;/th&gt;
&lt;th style=&quot;height: 19px;&quot;&gt;&amp;nbsp;&lt;/th&gt;
&lt;th style=&quot;height: 19px;&quot;&gt;&amp;nbsp;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;&lt;b&gt;구분&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;&lt;b&gt;예시&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;&lt;b&gt;설명&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;✅ 좋은 예&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;&lt;code&gt;GET /products/1&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;상품 1번 조회&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;  나쁜 예&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;&lt;code&gt;GET /getProductById/1&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;행동이 URL에 들어감&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. PUT vs PATCH vs POST의 개념 비교&lt;/b&gt;&lt;/h2&gt;
&lt;table data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style5&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&amp;nbsp;&lt;/th&gt;
&lt;th&gt;&amp;nbsp;&lt;/th&gt;
&lt;th&gt;&amp;nbsp;&lt;/th&gt;
&lt;th&gt;&amp;nbsp;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&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;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;&lt;code&gt;PUT&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;리소스를 &lt;b&gt;전체 교체 (replace)&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;code&gt;PATCH&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;리소스를 &lt;b&gt;부분 수정 (partial update)&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;code&gt;POST&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;리소스를 &lt;b&gt;생성(create)&lt;/b&gt; 또는 &lt;b&gt;행동(action)&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;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;  멱등성(Idempotency)이란?&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;같은&amp;nbsp;요청을&amp;nbsp;여러&amp;nbsp;번&amp;nbsp;보내도&amp;nbsp;결과가&amp;nbsp;변하지&amp;nbsp;않는&amp;nbsp;성질.&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;예시:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; color: #333333; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;PUT /product/1&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;rarr;&lt;span&gt;&amp;nbsp;&lt;/span&gt;{ &quot;name&quot;: &quot;콜라&quot;, &quot;price&quot;: 1000 }
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;여러 번 보내도&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;상품 정보가 동일하게 유지됨&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;rarr; ✅ 멱등&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;PATCH /product/1&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;rarr;&lt;span&gt;&amp;nbsp;&lt;/span&gt;{ &quot;price&quot;: 1000 }
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;여러 번 보내면 결과는 같지만, 로직에 따라 다를 수 있음 &amp;rarr; ⚠️ 조건부 멱등&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;POST /product/1/increase
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;매번 수량이 1씩 증가 &amp;rarr; ❌ 비멱등&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;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;code&gt;PUT&lt;/code&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;누락된 필드는 삭제로 간주(null 값으로 설정)&lt;/li&gt;
&lt;li&gt;멱등성 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;groovy&quot;&gt;&lt;code&gt;PUT /products/1
Content-Type: application/json

{
  &quot;name&quot;: &quot;콜라&quot;,
  &quot;category&quot;: &quot;DRINK&quot;,
  &quot;price&quot;: 1000,
  &quot;quantity&quot;: 10
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;  대부분의 도메인에서는 전체 교체가 어렵다.&lt;br /&gt;예: id, createdAt, companyId 같은 필드는 바뀌면 안되기 때문에&lt;br /&gt;실무에서는 PUT이 거의 사용되지 않음.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;1817&quot; data-start=&quot;1796&quot; data-ke-size=&quot;size23&quot;&gt;✅ PATCH (부분 수정)&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1877&quot; data-start=&quot;1818&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1835&quot; data-start=&quot;1818&quot;&gt;일부 필드만 수정할 때 사용&lt;/li&gt;
&lt;li data-end=&quot;1860&quot; data-start=&quot;1836&quot;&gt;null이 전달되지 않은 필드만 반영&lt;/li&gt;
&lt;li data-end=&quot;1877&quot; data-start=&quot;1861&quot;&gt;부분 변경 시 주로 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1762650812704&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;PATCH /products/1
Content-Type: application/json

{
  &quot;quantity&quot;: 20
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;  여러 필드를 한 번에 바꾸더라도 전체 교체 의도가 아니라면 PATCH 사용&lt;br /&gt;예시: 이름과 가격을 동시에 수정 &amp;rarr; 여전히 부분 수정이므로 PATCH.&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;2093&quot; data-start=&quot;2070&quot; data-ke-size=&quot;size23&quot;&gt;✅ POST (행동 또는 생성)&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2169&quot; data-start=&quot;2094&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2107&quot; data-start=&quot;2094&quot;&gt;리소스를 생성하거나,&lt;/li&gt;
&lt;li data-end=&quot;2169&quot; data-start=&quot;2108&quot;&gt;특정 행동(Action)을 수행할 때 사용 (즉, 단순 데이터 변경이 아닌 비즈니스 이벤트)&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1762650960054&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;POST /products/1/increase
POST /users/{id}/follow
POST /auth/login&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;blockquote data-end=&quot;2362&quot; data-start=&quot;2240&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;2362&quot; data-start=&quot;2242&quot; data-ke-size=&quot;size16&quot;&gt;  POST는 REST 관점에서는 행동을 표현할 때 유일하게 허용되는 메서드로&amp;nbsp;&lt;br /&gt;부분수정을 하더라고 URL에 행동이 들어가면 POST로 작성&lt;br /&gt;참고: 로그인은 &quot;유저 리소스 수정&quot;이 아니라 &quot;세션을 생성&quot;하는 행동임으로 POST&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/microsoft/api-guidelines/blob/vNext/azure/Guidelines.md&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/microsoft/api-guidelines/blob/vNext/azure/Guidelines.md&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1762651229423&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;api-guidelines/azure/Guidelines.md at vNext &amp;middot; microsoft/api-guidelines&quot; data-og-description=&quot;Microsoft REST API Guidelines. Contribute to microsoft/api-guidelines development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/microsoft/api-guidelines/blob/vNext/azure/Guidelines.md&quot; data-og-url=&quot;https://github.com/microsoft/api-guidelines/blob/vNext/azure/Guidelines.md&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/b8vtkp/hyZNfcEaKd/GOKlJo2kRZvPWkNGeLx0D0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/AoTdT/hyZMFvgq8v/CCNA1JkeScAkcLPCLTkMdK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/microsoft/api-guidelines/blob/vNext/azure/Guidelines.md&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/microsoft/api-guidelines/blob/vNext/azure/Guidelines.md&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/b8vtkp/hyZNfcEaKd/GOKlJo2kRZvPWkNGeLx0D0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/AoTdT/hyZMFvgq8v/CCNA1JkeScAkcLPCLTkMdK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&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;api-guidelines/azure/Guidelines.md at vNext &amp;middot; microsoft/api-guidelines&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Microsoft REST API Guidelines. Contribute to microsoft/api-guidelines development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>API</category>
      <category>patch</category>
      <category>POST</category>
      <category>Put</category>
      <category>RESTful</category>
      <author>believekim</author>
      <guid isPermaLink="true">https://believekim.tistory.com/119</guid>
      <comments>https://believekim.tistory.com/entry/RestFul-API-PUT-vs-PATCH-vs-POST-%EC%96%B8%EC%A0%9C-%EC%96%B4%EB%96%A4-%EB%A9%94%EC%84%9C%EB%93%9C%EB%A5%BC-%EC%8D%A8%EC%95%BC-%ED%95%A0%EA%B9%8C#entry119comment</comments>
      <pubDate>Mon, 10 Nov 2025 11:28:25 +0900</pubDate>
    </item>
    <item>
      <title>[자바] 왜 if-else를 쓰지 말라고 할까? - 클린 코드와 테스트 관점에서</title>
      <link>https://believekim.tistory.com/entry/%EC%9E%90%EB%B0%94-%EC%99%9C-if-else%EB%A5%BC-%EC%93%B0%EC%A7%80-%EB%A7%90%EB%9D%BC%EA%B3%A0-%ED%95%A0%EA%B9%8C-%ED%81%B4%EB%A6%B0-%EC%BD%94%EB%93%9C%EC%99%80-%ED%85%8C%EC%8A%A4%ED%8A%B8-%EA%B4%80%EC%A0%90%EC%97%90%EC%84%9C</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;요구사항 중에 if-else문을 사용하지 말라는 문구를 보았다&lt;br /&gt;단순히 &amp;ldquo;코드가 더러워진다&amp;rdquo; 정도로만 생각했는데&lt;br /&gt;&lt;/span&gt;테스트 복잡도와 유지보수성 측면에서 중요한 이유가 있었다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. 문제 코드 &amp;mdash; if-else가 많은 코드&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;아래는 로또문제를 예로 가지고 왔다.&lt;/li&gt;
&lt;li&gt;번호 6개를 맞추면 1등, 5개를 맞추고 보너스 번호를 맞추면 2등이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1762647045523&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public String getRank(int match, boolean bonus) {
    if (match == 6) {
        return &quot;1등&quot;;
    } else if (match == 5) {
        if (bonus) {
            return &quot;2등&quot;;
        } else {
            return &quot;3등&quot;;
        }
    } else if (match == 4) {
        return &quot;4등&quot;;
    } else if (match == 3) {
        return &quot;5등&quot;;
    } else {
        return &quot;꽝&quot;;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;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;match=6 &amp;rarr; &quot;1등&quot; ✅&lt;/li&gt;
&lt;li&gt;match=5, bonus=true &amp;rarr; &quot;2등&quot; ✅&lt;/li&gt;
&lt;li&gt;match=5, bonus=false &amp;rarr; &quot;3등&quot; ✅&lt;/li&gt;
&lt;li&gt;match=4 &amp;rarr; &quot;4등&quot; ✅&lt;/li&gt;
&lt;li&gt;match=3 &amp;rarr; &quot;5등&quot; ✅&lt;/li&gt;
&lt;li&gt;match=2 &amp;rarr; &quot;꽝&quot; ✅&lt;/li&gt;
&lt;li&gt;match=1 &amp;rarr; &quot;꽝&quot; ✅&lt;/li&gt;
&lt;li&gt;match=0 &amp;rarr; &quot;꽝&quot; ✅&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;총 8개 테스트!로 조합폭발(Combinatorial Explosion)&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테스트 케이스 수는 &amp;ldquo;if 조건 개수&amp;rdquo;에 따라 2ⁿ (지수적으로) 증가한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 테스트 효율성 향상을 위해 MC/DC(테스트 갯수 n+1)를 사용한다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. Early Return으로 개선&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;테스트 케이스는 같지만 조건문 중첩이 사라졌고 가독성이 좋아졌으며 각 조건이 단일 책임을 가지도록 구현&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1762647370256&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public String getRank(int match, boolean bonus) {
    if (match == 6) {
        return &quot;1등&quot;;
    }
    if (match == 5 &amp;amp;&amp;amp; bonus) {
        return &quot;2등&quot;;
    }
    if (match == 5) {
        return &quot;3등&quot;;
    }
    if (match == 4) {
        return &quot;4등&quot;;
    }
    if (match == 3) {
        return &quot;5등&quot;;
    }
    return &quot;꽝&quot;;
}&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. Map으로 개선&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;match와 bonus 조합을 Key, 등수를 Value로 맵핑&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1762647723705&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;private static final Map&amp;lt;String, String&amp;gt; RANK_MAP = Map.ofEntries(
    Map.entry(&quot;6:false&quot;, &quot;1등&quot;),
    Map.entry(&quot;5:true&quot;, &quot;2등&quot;),
    Map.entry(&quot;5:false&quot;, &quot;3등&quot;),
    Map.entry(&quot;4:false&quot;, &quot;4등&quot;),
    Map.entry(&quot;3:false&quot;, &quot;5등&quot;)
);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;결과 찾기&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1762647912486&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public String getRank(int match, boolean bonus) {
    String key = match + &quot;:&quot; + bonus;
    return RANK_MAP.getOrDefault(key, &quot;꽝&quot;);
}&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&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;4. Enum으로 개선&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;조건문이 사라지고 테스트 대상이 &amp;ldquo;로직&amp;rdquo;에서 데이터 구조로 변환&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1762647658291&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public enum Rank {
    FIRST(6, false, &quot;1등&quot;),
    SECOND(5, true, &quot;2등&quot;),
    THIRD(5, false, &quot;3등&quot;),
    FOURTH(4, false, &quot;4등&quot;),
    FIFTH(3, false, &quot;5등&quot;),
    FAIL(0, false, &quot;꽝&quot;);

    private final int match;
    private final boolean bonus;
    private final String label;

    Rank(int match, boolean bonus, String label) {
        this.match = match;
        this.bonus = bonus;
        this.label = label;
    }

    public static String find(int match, boolean bonus) {
        return Arrays.stream(values())
                .filter(r -&amp;gt; r.match == match &amp;amp;&amp;amp; (!r.bonus || bonus))
                .findFirst()
                .map(r -&amp;gt; r.label)
                .orElse(&quot;꽝&quot;);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;사용 예시&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1762647676006&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;String rank = Rank.find(5, true); // &quot;2등&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;5. 비교&lt;/b&gt;&lt;/h2&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;style13&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;방식&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;장점&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;단점&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;if-else&lt;/td&gt;
&lt;td&gt;단순, 직관적&lt;/td&gt;
&lt;td&gt;조건 늘면 가독성 &amp;darr;, 테스트 폭발&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Map&lt;/td&gt;
&lt;td&gt;깔끔, 데이터 관리 쉬움&lt;/td&gt;
&lt;td&gt;Key 구성 주의 필요&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Enum + Stream&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;ldquo;조건문은 줄이는 게 목적이 아니라, 의도를 명확히 표현하는 것이 목적입니다.&amp;rdquo;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>언어/자바</category>
      <category>early-return</category>
      <category>if-else</category>
      <author>believekim</author>
      <guid isPermaLink="true">https://believekim.tistory.com/118</guid>
      <comments>https://believekim.tistory.com/entry/%EC%9E%90%EB%B0%94-%EC%99%9C-if-else%EB%A5%BC-%EC%93%B0%EC%A7%80-%EB%A7%90%EB%9D%BC%EA%B3%A0-%ED%95%A0%EA%B9%8C-%ED%81%B4%EB%A6%B0-%EC%BD%94%EB%93%9C%EC%99%80-%ED%85%8C%EC%8A%A4%ED%8A%B8-%EA%B4%80%EC%A0%90%EC%97%90%EC%84%9C#entry118comment</comments>
      <pubDate>Sun, 9 Nov 2025 09:29:04 +0900</pubDate>
    </item>
    <item>
      <title>[IntelliJ] Spring Cloud 기반 MSA 프로젝트 여러 서버를 관리하는 gradle 초기설정</title>
      <link>https://believekim.tistory.com/entry/IntelliJ-Spring-Cloud-%EA%B8%B0%EB%B0%98-MSA-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EC%97%AC%EB%9F%AC-%EC%84%9C%EB%B2%84%EB%A5%BC-%EA%B4%80%EB%A6%AC%ED%95%98%EB%8A%94-gradle-%EC%B4%88%EA%B8%B0%EC%84%A4%EC%A0%95</link>
      <description>&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-end=&quot;355&quot; data-start=&quot;221&quot; data-ke-size=&quot;size16&quot;&gt;Spring Cloud를 사용해서 MSA 기반 서버를 구성하면서,&lt;br /&gt;모놀리식과는 다른 Gradle 프로젝트 구조와 빌드 관리 방식에서 헷갈리는 부분이 많았다.&lt;br /&gt;하나의 루트 폴더에서 여러 개의 서비스 모듈을 관리하는 방법과&lt;br /&gt;그 과정에서 겪은 시행착오를 정리해본다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1.&amp;nbsp;MSA 프로젝트 구조 개요&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;MSA 프로젝트를 구성할 때, 각 서비스(eureka, gateway, user, order 등)는 &lt;/span&gt;&lt;/li&gt;
&lt;li&gt;각각 독립적으로 실행 가능한 &lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;Spring Boot 애플리케이션이 된다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;예시&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1762352871807&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Cupeed/
 ├── com.sparta.cupeed.config/
 ├── com.sparta.cupeed.eureka/
 ├── com.sparta.cupeed.gateway/
 ├── com.sparta.cupeed.user/
 ├── com.sparta.cupeed.order/
 ├── com.sparta.cupeed.product/
 ├── com.sparta.cupeed.company/
 ├── com.sparta.cupeed.hub/
 ├── com.sparta.cupeed.hubroute/
 ├── com.sparta.cupeed.delivery/
 ├── com.sparta.cupeed.ai/
 ├── com.sparta.cupeed.slack/
 └── settings.gradle   &amp;larr; 모든 모듈을 관리하는 루트 설정&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. 루트 경로에 settings.gradle 설정&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;MSA의 각 서버를 연결하기 위해 루트 경로(Cupeed/)에 있는 settings.gradle 파일을 생성한다&lt;/li&gt;
&lt;li&gt;우리의 서비스 명은 'Cupeed'이다&lt;/li&gt;
&lt;li&gt;각 서버의 폴더명은 config가 아니라 'com.sparta.cupeed.config'이다&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1762352976331&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;rootProject.name = 'Cupeed'

include 'config', 'eureka', 'gateway', 'user', 'order', 'product', 'company', 'hub', 'hubroute', 'delivery', 'ai', 'slack'

project(':config').projectDir = file('com.sparta.cupeed.config')
project(':eureka').projectDir = file('com.sparta.cupeed.eureka')
project(':gateway').projectDir = file('com.sparta.cupeed.gateway')
project(':user').projectDir = file('com.sparta.cupeed.user')
project(':order').projectDir = file('com.sparta.cupeed.order')
project(':product').projectDir = file('com.sparta.cupeed.product')
project(':company').projectDir = file('com.sparta.cupeed.company')
project(':hub').projectDir = file('com.sparta.cupeed.hub')
project(':hubroute').projectDir = file('com.sparta.cupeed.hubroute')
project(':delivery').projectDir = file('com.sparta.cupeed.delivery')
project(':ai').projectDir = file('com.sparta.cupeed.ai')
project(':slack').projectDir = file('com.sparta.cupeed.slack')&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;이렇게 설정하면, 루트 하나로 모든 하위 서비스의 Gradle 빌드를 관리할 수 있다.&lt;/li&gt;
&lt;li&gt;각 서비스 내부에 존재하던 settings.gradle 파일은 &lt;b&gt;삭제&lt;/b&gt;해야 충돌이 나지 않는다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. 확인&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;위와 같이 설정하면 IntelliJ에서 아래와 같이 관리가 가능하다&lt;/li&gt;
&lt;li&gt;&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-11-05 오후 11.32.48.png&quot; data-origin-width=&quot;590&quot; data-origin-height=&quot;988&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/YLfxz/dJMcabP2Kx5/7WfqntJFGFTEkSQs0pZukK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/YLfxz/dJMcabP2Kx5/7WfqntJFGFTEkSQs0pZukK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/YLfxz/dJMcabP2Kx5/7WfqntJFGFTEkSQs0pZukK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FYLfxz%2FdJMcabP2Kx5%2F7WfqntJFGFTEkSQs0pZukK%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;241&quot; height=&quot;404&quot; data-filename=&quot;스크린샷 2025-11-05 오후 11.32.48.png&quot; data-origin-width=&quot;590&quot; data-origin-height=&quot;988&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;최상위 폴더에서 .gitignore을 추가해 프로젝트를 시작한다&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-11-05 오후 11.34.41.png&quot; data-origin-width=&quot;828&quot; data-origin-height=&quot;1058&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bgV2Z0/dJMcadmMY5Q/gTXZZUdKeyq1NGSGaNZNT0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bgV2Z0/dJMcadmMY5Q/gTXZZUdKeyq1NGSGaNZNT0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bgV2Z0/dJMcadmMY5Q/gTXZZUdKeyq1NGSGaNZNT0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbgV2Z0%2FdJMcadmMY5Q%2FgTXZZUdKeyq1NGSGaNZNT0%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;352&quot; height=&quot;1058&quot; data-filename=&quot;스크린샷 2025-11-05 오후 11.34.41.png&quot; data-origin-width=&quot;828&quot; data-origin-height=&quot;1058&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>IDE/IntelliJ</category>
      <category>settings.gradle</category>
      <category>인텔리제이여러서버관리</category>
      <author>believekim</author>
      <guid isPermaLink="true">https://believekim.tistory.com/117</guid>
      <comments>https://believekim.tistory.com/entry/IntelliJ-Spring-Cloud-%EA%B8%B0%EB%B0%98-MSA-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EC%97%AC%EB%9F%AC-%EC%84%9C%EB%B2%84%EB%A5%BC-%EA%B4%80%EB%A6%AC%ED%95%98%EB%8A%94-gradle-%EC%B4%88%EA%B8%B0%EC%84%A4%EC%A0%95#entry117comment</comments>
      <pubDate>Wed, 5 Nov 2025 23:35:38 +0900</pubDate>
    </item>
    <item>
      <title>[스프링] 왜 application.properties의 한글은 깨질까?</title>
      <link>https://believekim.tistory.com/entry/%EC%8A%A4%ED%94%84%EB%A7%81-%EC%99%9C-applicationproperties%EC%9D%98-%ED%95%9C%EA%B8%80%EC%9D%80-%EA%B9%A8%EC%A7%88%EA%B9%8C</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;스프링으로 개발을 하다보면 application.properties란 파일을 만난다.&lt;br /&gt;완성 후 깃허브에 코드를 올리고 나중에 확인해보면 주석이 모두 ??로 바뀌어 있다.&lt;br /&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. 인코딩&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;인코딩(Encoding)은 &amp;ldquo;문자&amp;rdquo;를 &amp;ldquo;숫자(바이트)&amp;rdquo;로 바꾸는 규칙이다.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://start.spring.io/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://start.spring.io/&lt;/a&gt;에서 프로젝트를 만든 후에 src/main/resources/application.properties를 IntelliJ로 열어보면 아래의 인토딩정보가 나온다. 기본값은 ISO-8859-1이다&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-10-31 오후 1.30.30.png&quot; data-origin-width=&quot;1094&quot; data-origin-height=&quot;534&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/6GOfr/dJMcaelFJMl/24mHCQks6nXEjXjemPaQ4k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/6GOfr/dJMcaelFJMl/24mHCQks6nXEjXjemPaQ4k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/6GOfr/dJMcaelFJMl/24mHCQks6nXEjXjemPaQ4k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6GOfr%2FdJMcaelFJMl%2F24mHCQks6nXEjXjemPaQ4k%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;428&quot; height=&quot;534&quot; data-filename=&quot;스크린샷 2025-10-31 오후 1.30.30.png&quot; data-origin-width=&quot;1094&quot; data-origin-height=&quot;534&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;UTF-8 = 국제 표준&lt;/li&gt;
&lt;li&gt;ISO-8859-1 = 구시대 유럽 문자 인코딩&lt;/li&gt;
&lt;/ul&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 95px;&quot; border=&quot;1&quot; data-end=&quot;1190&quot; data-start=&quot;987&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style13&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;인코딩&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;특징&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot; data-end=&quot;1061&quot; data-start=&quot;1019&quot;&gt;
&lt;td style=&quot;height: 19px;&quot; data-col-size=&quot;sm&quot; data-end=&quot;1031&quot; data-start=&quot;1019&quot;&gt;&lt;b&gt;UTF-8&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot; data-col-size=&quot;sm&quot; data-end=&quot;1061&quot; data-start=&quot;1031&quot;&gt;전 세계 문자 지원, ASCII 호환, 웹 표준&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot; data-end=&quot;1109&quot; data-start=&quot;1062&quot;&gt;
&lt;td style=&quot;height: 19px;&quot; data-col-size=&quot;sm&quot; data-end=&quot;1075&quot; data-start=&quot;1062&quot;&gt;&lt;b&gt;UTF-16&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot; data-col-size=&quot;sm&quot; data-end=&quot;1109&quot; data-start=&quot;1075&quot;&gt;2~4바이트로 문자 표현, Windows 시스템 친화적&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot; data-end=&quot;1138&quot; data-start=&quot;1110&quot;&gt;
&lt;td style=&quot;height: 19px;&quot; data-col-size=&quot;sm&quot; data-end=&quot;1125&quot; data-start=&quot;1110&quot;&gt;&lt;b&gt;US-ASCII&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot; data-col-size=&quot;sm&quot; data-end=&quot;1138&quot; data-start=&quot;1125&quot;&gt;영어만 표현 가능&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot; data-end=&quot;1190&quot; data-start=&quot;1139&quot;&gt;
&lt;td style=&quot;height: 19px;&quot; data-col-size=&quot;sm&quot; data-end=&quot;1166&quot; data-start=&quot;1139&quot;&gt;&lt;b&gt;ISO-8859-1 (Latin-1)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot; data-col-size=&quot;sm&quot; data-end=&quot;1190&quot; data-start=&quot;1166&quot;&gt;유럽 문자 지원, 한글&amp;middot;일본어 불가능&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;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. 왜 .properties는 ISO-8859-1을 기본으로 쓸까?&amp;nbsp;&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;.properties 파일은 원래 Java 초창기 (JDK 1.0 시대) 부터 있던 포맷으로&lt;/li&gt;
&lt;li&gt;그때는 국제화(i18n) 개념이 약해서, Java는 .properties를 ISO-8859-1로 강제 인코딩.&lt;/li&gt;
&lt;li&gt;Spring Boot 2.4+ 이후에는 다음 설정을 추가하면 UTF-8을 강제할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1761885327341&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;spring.config.encoding=UTF-8&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. 왜 .yml은 UTF-8이 기본일까?&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;YAML은 JSON과 마찬가지로 UTF-8을 기본 인코딩으로 설계했어요.&lt;/li&gt;
&lt;li&gt;.yaml과 .yml을 둘다 사용한다. 특히 윈도우에서는 3글자로 통합하기에 .yml을 사용한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://yaml.org/spec/1.2.2/#12-yaml-history&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://yaml.org/spec/1.2.2/#12-yaml-history&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1761885745022&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;YAML Ain&amp;rsquo;t Markup Language (YAML&amp;trade;) revision 1.2.2&quot; data-og-description=&quot;&quot; data-og-host=&quot;yaml.org&quot; data-og-source-url=&quot;https://yaml.org/spec/1.2.2/#12-yaml-history&quot; data-og-url=&quot;https://yaml.org/spec/1.2.2/#12-yaml-history&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://yaml.org/spec/1.2.2/#12-yaml-history&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://yaml.org/spec/1.2.2/#12-yaml-history&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;YAML Ain&amp;rsquo;t Markup Language (YAML&amp;trade;) revision 1.2.2&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;yaml.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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4. IntelliJ에서 설정방법&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Settings -&amp;gt; Editor -&amp;gt; File Encodings에서 인코딩을 설정할 수 있다.&lt;/li&gt;
&lt;li&gt;Global Encoding&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;rarr; UTF-8&lt;/li&gt;
&lt;li&gt;Project Encoding &amp;rarr; UTF-8&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2002&quot; data-origin-height=&quot;1456&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bzqIUA/dJMcaelFJUm/8VbFDJCdynjpZNpB4EbTW0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bzqIUA/dJMcaelFJUm/8VbFDJCdynjpZNpB4EbTW0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bzqIUA/dJMcaelFJUm/8VbFDJCdynjpZNpB4EbTW0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbzqIUA%2FdJMcaelFJUm%2F8VbFDJCdynjpZNpB4EbTW0%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;2002&quot; height=&quot;1456&quot; data-origin-width=&quot;2002&quot; data-origin-height=&quot;1456&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;5. 왜 UTF-8이 표준인가?&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;3132&quot; data-start=&quot;3098&quot;&gt;모든 문자(한글, 이모지, 아랍어 등) 표현 가능&lt;/li&gt;
&lt;li data-end=&quot;3155&quot; data-start=&quot;3133&quot;&gt;다른 인코딩과의 충돌 최소화&lt;/li&gt;
&lt;li data-end=&quot;3204&quot; data-start=&quot;3156&quot;&gt;JSON, YAML, HTML, Markdown 등 대부분 UTF-8 기반&lt;/li&gt;
&lt;li data-end=&quot;3240&quot; data-start=&quot;3205&quot;&gt;Spring Boot도 점점 UTF-8로 통일되는 방향&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>프레임워크/스프링</category>
      <category>application.properties</category>
      <category>application.yml</category>
      <category>인코딩</category>
      <author>believekim</author>
      <guid isPermaLink="true">https://believekim.tistory.com/116</guid>
      <comments>https://believekim.tistory.com/entry/%EC%8A%A4%ED%94%84%EB%A7%81-%EC%99%9C-applicationproperties%EC%9D%98-%ED%95%9C%EA%B8%80%EC%9D%80-%EA%B9%A8%EC%A7%88%EA%B9%8C#entry116comment</comments>
      <pubDate>Tue, 4 Nov 2025 15:03:32 +0900</pubDate>
    </item>
    <item>
      <title>[CS] Inside-Out vs Outside-In TDD의 두 가지 접근법</title>
      <link>https://believekim.tistory.com/entry/CS-Inside-Out-vs-Outside-In-TDD%EC%9D%98-%EB%91%90-%EA%B0%80%EC%A7%80-%EC%A0%91%EA%B7%BC%EB%B2%95</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;TDD개발방법론을 공부하다보니&lt;br /&gt;두가지의 접근법을 알게되어 정리해보았다.&lt;br /&gt;결론부터 말하면 무엇이 더 좋은 것은 없고 상황에 따라 모두 정답이다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. 들어가며&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;ldquo;TDD는 테스트 먼저 짜는 거&amp;rdquo; 정도로만 알고 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테스트를 먼저 짜는게 익숙하지 않았기에&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드를 구현하기 시작하면 User객체를 만들고 나서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테스트를 작성하여 확인하며 진행했었다.&lt;/p&gt;
&lt;pre id=&quot;code_1761759040255&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package com.example.tdd.domain;

public class User {
    private final String username;
    private int age;

    public User(String username, int age) {
        if (username == null || username.isBlank()) {
            throw new IllegalArgumentException(&quot;username은 비어있을 수 없습니다.&quot;);
        }
        if (age &amp;lt; 0) {
            throw new IllegalArgumentException(&quot;age는 음수일 수 없습니다.&quot;);
        }
        this.username = username;
        this.age = age;
    }

    public String getUsername() {
        return username;
    }

    public int getAge() {
        return age;
    }

    public void increaseAge() {
        this.age++;
    }

    public void updateAge(int age) {
        if (age &amp;lt; 0) throw new IllegalArgumentException(&quot;age는 음수일 수 없습니다.&quot;);
        this.age = age;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;테스트 코드&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1761759068520&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package com.example.tdd.domain;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;

class UserTest {

    @Test
    @DisplayName(&quot;생성자: 정상 입력 시 User 객체 생성&quot;)
    void createUser_success() {
        User user = new User(&quot;alice&quot;, 25);

        assertThat(user.getUsername()).isEqualTo(&quot;alice&quot;);
        assertThat(user.getAge()).isEqualTo(25);
    }

    @Test
    @DisplayName(&quot;생성자: username이 비어있으면 예외 발생&quot;)
    void createUser_invalidUsername() {
        assertThatThrownBy(() -&amp;gt; new User(&quot;&quot;, 25))
            .isInstanceOf(IllegalArgumentException.class)
            .hasMessageContaining(&quot;username&quot;);
    }

    @Test
    @DisplayName(&quot;생성자: age가 음수이면 예외 발생&quot;)
    void createUser_invalidAge() {
        assertThatThrownBy(() -&amp;gt; new User(&quot;alice&quot;, -1))
            .isInstanceOf(IllegalArgumentException.class)
            .hasMessageContaining(&quot;age&quot;);
    }

    @Test
    @DisplayName(&quot;나이 증가&quot;)
    void increaseAge() {
        User user = new User(&quot;bob&quot;, 30);
        user.increaseAge();
        assertThat(user.getAge()).isEqualTo(31);
    }

    @Test
    @DisplayName(&quot;나이 업데이트&quot;)
    void updateAge() {
        User user = new User(&quot;carol&quot;, 20);
        user.updateAge(35);
        assertThat(user.getAge()).isEqualTo(35);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아직 테스트부터 짜는것조차 익숙하지 않다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 어디서부터 테스트를 시작하느냐에 따라 전혀 다른 개발 방식이 된다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. Inside-Out 방식이란? (Bottom-Up TDD)&lt;/b&gt;&amp;nbsp;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;880&quot; data-start=&quot;831&quot;&gt;가장 작은 단위(클래스, 메서드)부터 테스트를 작성하는 전통적인 TDD 스타일&lt;/li&gt;
&lt;li data-end=&quot;960&quot; data-start=&quot;936&quot;&gt;빠른 피드백, 내부 설계에 집중 가능&lt;/li&gt;
&lt;li data-end=&quot;991&quot; data-start=&quot;961&quot;&gt;하지만 전체 흐름(사용자 시나리오)은 나중에 확인된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1761759307748&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Test
void increaseAge_whenCalled_incrementsAge() {
    User user = new User(&quot;alice&quot;, 25);
    user.increaseAge();
    assertThat(user.getAge()).isEqualTo(26);
}

@Test
void updateAge_whenValidAge_updatesAge() {
    User user = new User(&quot;bob&quot;, 30);
    user.updateAge(35);
    assertThat(user.getAge()).isEqualTo(35);
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-start=&quot;1232&quot; data-end=&quot;1238&quot; data-ke-size=&quot;size23&quot;&gt;장점&lt;b&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1206&quot; data-start=&quot;1175&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1189&quot; data-start=&quot;1175&quot;&gt;디버깅, 리팩토링 쉬움&lt;/li&gt;
&lt;li data-end=&quot;1206&quot; data-start=&quot;1190&quot;&gt;도메인 로직 테스트에 적합&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-start=&quot;1232&quot; data-end=&quot;1238&quot; data-ke-size=&quot;size23&quot;&gt;단점&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1251&quot; data-start=&quot;1215&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1230&quot; data-start=&quot;1215&quot;&gt;사용자 요구 반영이 늦음&lt;/li&gt;
&lt;li data-end=&quot;1251&quot; data-start=&quot;1231&quot;&gt;상위 레이어 변경 시 영향도가 큼&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. Outside-In 방식 (Top-Down TDD / London School)&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;사용자 또는 외부 시스템 관점에서 테스트를 먼저 작성&lt;/li&gt;
&lt;li&gt;전체 시나리오 테스트 후, 필요한 내부 컴포넌트를 Mock으로 대체하며 구현&lt;/li&gt;
&lt;li&gt;사용자 시나리오 &amp;rarr; 서비스 &amp;rarr; 도메인 &amp;rarr; 레포지토리 순으로 테스트와 구현을 점진적으로 확장하는 방식&lt;/li&gt;
&lt;/ul&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;이 기능이 최종적으로 이렇게 동작해야 한다&quot;를 먼저 정의하고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 기능을 만들기 위해 필요한 내부 클래스나 메서드는&lt;span&gt;&amp;nbsp;&lt;/span&gt;Mock을 사용해서 흉내만 내는 것&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1761759639408&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 사용자를 등록하면, UserRepository에 저장되고 기본 나이가 0이어야 한다
@Test
void registerUser_whenValidInput_createsUserWithDefaultAge() {
    UserRepository userRepository = mock(UserRepository.class); // 실제 DB 없이 흉내
    UserService userService = new UserService(userRepository);

    User user = userService.registerUser(&quot;carol&quot;);

    assertThat(user.getUsername()).isEqualTo(&quot;carol&quot;);
    assertThat(user.getAge()).isEqualTo(0); // 기본 나이
    verify(userRepository).save(user); // 실제 DB 호출 확인
}&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1058&quot; data-start=&quot;1003&quot;&gt;테스트를 작성한 후, 테스트가 통과하도록 실제 UserService와 User 클래스를 구현&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1761759773168&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class User {
    private String username;
    private int age;

    public User(String username) {
        this.username = username;
        this.age = 0; // 기본 나이
    }

    public String getUsername() { return username; }
    public int getAge() { return age; }
}

class UserService {
    private final UserRepository userRepository;

    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    public User registerUser(String username) {
        User user = new User(username);
        userRepository.save(user);
        return user;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;1238&quot; data-start=&quot;1232&quot; data-ke-size=&quot;size23&quot;&gt;장점&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1332&quot; data-start=&quot;1239&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1268&quot; data-start=&quot;1239&quot;&gt;사용자 시나리오 중심 &amp;rarr; 비즈니스 가치에 집중&lt;/li&gt;
&lt;li data-end=&quot;1308&quot; data-start=&quot;1269&quot;&gt;Hexagonal Architecture와 자연스럽게 연계 가능&lt;/li&gt;
&lt;li data-end=&quot;1332&quot; data-start=&quot;1309&quot;&gt;Mock 활용으로 빠른 피드백 유지&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-end=&quot;1340&quot; data-start=&quot;1334&quot; data-ke-size=&quot;size23&quot;&gt;단점&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1387&quot; data-start=&quot;1341&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1367&quot; data-start=&quot;1341&quot;&gt;Mock 과다 사용 시 테스트 깨짐 가능&lt;/li&gt;
&lt;li data-end=&quot;1387&quot; data-start=&quot;1368&quot;&gt;인터페이스 설계 부담이 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. 정리&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2456&quot; data-start=&quot;2420&quot;&gt;Inside-Out은 &lt;b&gt;&amp;ldquo;엔진부터 조립해서 자동차 완성&amp;rdquo;&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;2503&quot; data-start=&quot;2457&quot;&gt;Outside-In은 &lt;b&gt;&amp;ldquo;운전자가 원하는 경험부터 설계하고 엔진을 맞춰감&amp;rdquo;&lt;/b&gt;&lt;/li&gt;
&lt;/ul&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;style13&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;구분&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;Inside-Out (Bottom-Up)&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;Outside-In (Top-Down)&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;시작점&lt;/td&gt;
&lt;td&gt;도메인, 내부 로직&lt;/td&gt;
&lt;td&gt;사용자 시나리오, API&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;테스트 순서&lt;/td&gt;
&lt;td&gt;Domain &amp;rarr; Service &amp;rarr; Controller&lt;/td&gt;
&lt;td&gt;Controller &amp;rarr; Service &amp;rarr; Domain&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&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;/td&gt;
&lt;td&gt;단위 테스트 중심&lt;/td&gt;
&lt;td&gt;Mock, 인수 테스트 중심&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;장점&lt;/td&gt;
&lt;td&gt;빠른 피드백, 리팩토링 용이&lt;/td&gt;
&lt;td&gt;비즈니스 요구에 초점, UI 연동 쉬움&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&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;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;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Inside-Out과 Outside-In은 TDD에서만 쓰이는 용어가 아니었다.&lt;br /&gt;&lt;a href=&quot;https://brunch.co.kr/@mime3/2&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://brunch.co.kr/@mime3/2&lt;/a&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;figure id=&quot;og_1761760388520&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;Inside-out, Outside-in&quot; data-og-description=&quot;대기업 n년차라면 스스로에게 물어야 하는 것 | 링크드인에서 흥미로운 글을 읽었다. 범선과 크루즈에 비유한 대기업 직원과 스타트업 창업자 얘기다. 범선은 바람이 적당히 불고 큰 돛대를 달&quot; data-og-host=&quot;brunch.co.kr&quot; data-og-source-url=&quot;https://brunch.co.kr/@mime3/2&quot; data-og-url=&quot;https://brunch.co.kr/@mime3/undefined/@mime3/2&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/sqxUs/hyZMnPjR1s/Md07yIbwGUcZT471ITSocK/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot;&gt;&lt;a href=&quot;https://brunch.co.kr/@mime3/2&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://brunch.co.kr/@mime3/2&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/sqxUs/hyZMnPjR1s/Md07yIbwGUcZT471ITSocK/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720');&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;Inside-out, Outside-in&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;대기업 n년차라면 스스로에게 물어야 하는 것 | 링크드인에서 흥미로운 글을 읽었다. 범선과 크루즈에 비유한 대기업 직원과 스타트업 창업자 얘기다. 범선은 바람이 적당히 불고 큰 돛대를 달&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;brunch.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;257&quot; data-start=&quot;116&quot;&gt;&lt;b&gt;Inside-Out&lt;/b&gt;: 내부 관점에서 시작
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;257&quot; data-start=&quot;149&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;183&quot; data-start=&quot;149&quot;&gt;소프트웨어: 도메인/클래스 중심 &amp;rarr; 외부 시나리오 연결&lt;/li&gt;
&lt;li data-end=&quot;216&quot; data-start=&quot;186&quot;&gt;마케팅: 자사 제품&amp;middot;강점 중심 &amp;rarr; 고객에게 제공&lt;/li&gt;
&lt;li data-end=&quot;257&quot; data-start=&quot;219&quot;&gt;전략/인사: 조직 역량 중심 &amp;rarr; 외부 시장이나 직원 요구 대응&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;403&quot; data-start=&quot;259&quot;&gt;&lt;b&gt;Outside-In&lt;/b&gt;: 외부 관점에서 시작
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;403&quot; data-start=&quot;292&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;332&quot; data-start=&quot;292&quot;&gt;소프트웨어: 사용자 시나리오/인수 테스트 중심 &amp;rarr; 내부 구현 연결&lt;/li&gt;
&lt;li data-end=&quot;366&quot; data-start=&quot;335&quot;&gt;마케팅: 고객 요구&amp;middot;니즈 중심 &amp;rarr; 내부 역량 조정&lt;/li&gt;
&lt;li data-end=&quot;403&quot; data-start=&quot;369&quot;&gt;전략/인사: 시장/직원 요구 중심 &amp;rarr; 조직 역량 최적화&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>컴퓨터사이언스</category>
      <category>insideout</category>
      <category>OutsideIn</category>
      <category>TDD접근법</category>
      <author>believekim</author>
      <guid isPermaLink="true">https://believekim.tistory.com/115</guid>
      <comments>https://believekim.tistory.com/entry/CS-Inside-Out-vs-Outside-In-TDD%EC%9D%98-%EB%91%90-%EA%B0%80%EC%A7%80-%EC%A0%91%EA%B7%BC%EB%B2%95#entry115comment</comments>
      <pubDate>Mon, 3 Nov 2025 03:48:35 +0900</pubDate>
    </item>
    <item>
      <title>[CS] 패키지 구조 선택하기(Package by Layer vs Package by Feature vs Hexagonal Architecture)</title>
      <link>https://believekim.tistory.com/entry/CS-%ED%8C%A8%ED%82%A4%EC%A7%80-%EA%B5%AC%EC%A1%B0-%EC%84%A0%ED%83%9D%ED%95%98%EA%B8%B0Package-by-Layer-vs-Package-by-Feature-vs-Hexagonal-Architecture</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;프로젝트를 진행하다보면 가장 먼저 떠오르는 고민이 &lt;br /&gt;&quot;패키지 구조를 어떻게 가져갈 것인가?&quot;이다.&lt;br /&gt;&lt;/span&gt;그래서 여러가지 패키지구조를 비교해보았다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;0. 참고자료&lt;/b&gt;&lt;/h2&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://medium.com/sahibinden-technology/package-by-layer-vs-package-by-feature-7e89cde2ae3a&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://medium.com/sahibinden-technology/package-by-layer-vs-package-by-feature-7e89cde2ae3a&lt;/a&gt;&lt;/b&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1761755791675&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;Package by Layer vs Package by Feature&quot; data-og-description=&quot;Which one should we use? And why?&quot; data-og-host=&quot;medium.com&quot; data-og-source-url=&quot;https://medium.com/sahibinden-technology/package-by-layer-vs-package-by-feature-7e89cde2ae3a&quot; data-og-url=&quot;https://medium.com/sahibinden-technology/package-by-layer-vs-package-by-feature-7e89cde2ae3a&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/Xw7gi/hyZMOq01CD/rEUHLySJCOmEzD2wn8C39k/img.png?width=1200&amp;amp;height=750&amp;amp;face=0_0_1200_750&quot;&gt;&lt;a href=&quot;https://medium.com/sahibinden-technology/package-by-layer-vs-package-by-feature-7e89cde2ae3a&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://medium.com/sahibinden-technology/package-by-layer-vs-package-by-feature-7e89cde2ae3a&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/Xw7gi/hyZMOq01CD/rEUHLySJCOmEzD2wn8C39k/img.png?width=1200&amp;amp;height=750&amp;amp;face=0_0_1200_750');&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;Package by Layer vs Package by Feature&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Which one should we use? And why?&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;medium.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. Layered Architecture&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;소프트웨어를 역할(role) 기반으로 나눈 전통적인 구조&lt;/li&gt;
&lt;li&gt;&amp;ldquo;서비스는 비즈니스 로직만 담당해야 하고, 데이터 접근은 리포지토리가 담당해야 해&amp;rdquo; 라는 설계 원칙&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1761756385046&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Presentation (Controller)
&amp;darr;
Business (Service)
&amp;darr;
Persistence (Repository)&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-end=&quot;926&quot; data-start=&quot;917&quot; data-ke-size=&quot;size23&quot;&gt;  특징&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1005&quot; data-start=&quot;927&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;957&quot; data-start=&quot;927&quot;&gt;UI &amp;rarr; 비즈니스 &amp;rarr; 데이터 순으로 흐름이 고정&lt;/li&gt;
&lt;li data-end=&quot;983&quot; data-start=&quot;958&quot;&gt;각 계층은 아래 계층에 의존 (단방향)&lt;/li&gt;
&lt;li data-end=&quot;1005&quot; data-start=&quot;984&quot;&gt;기술 스택과 계층이 1:1 대응&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-end=&quot;1016&quot; data-start=&quot;1007&quot; data-ke-size=&quot;size23&quot;&gt;⚠️ 한계&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1129&quot; data-start=&quot;1017&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1072&quot; data-start=&quot;1017&quot;&gt;계층 간 강한 결합 (Controller &amp;rarr; Service &amp;rarr; Repository로 의존 연결)&lt;/li&gt;
&lt;li data-end=&quot;1102&quot; data-start=&quot;1073&quot;&gt;기능 단위로 이동하려면 여러 계층을 건너야 함&lt;/li&gt;
&lt;li data-end=&quot;1129&quot; data-start=&quot;1103&quot;&gt;기능 추가 시 여러 패키지를 수정해야 함&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. Package by Layer&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Layered Architecture를 그대로 코드 패키지 구조로 옮긴 형태&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1761756577985&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;├── com.app
    └── controller
        ├── CompanyController
        ├── ProductController
        └── UserController
    └── model
        ├── Company   
        ├── Product
        └── User
    └── repository
        ├── CompanyRepository   
        ├── ProductRepository
        └── UserRepository
    └── service
        ├── CompanyService
        ├── ProductService
        └── UserService
    └── util&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-end=&quot;1371&quot; data-start=&quot;1362&quot; data-ke-size=&quot;size23&quot;&gt;  특징&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1460&quot; data-start=&quot;1372&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1396&quot; data-start=&quot;1372&quot;&gt;한눈에 &amp;ldquo;역할별 클래스&amp;rdquo;를 찾기 쉬움&lt;/li&gt;
&lt;li data-end=&quot;1460&quot; data-start=&quot;1425&quot;&gt;Layered Architecture와 거의 동일한 개념&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-end=&quot;1471&quot; data-start=&quot;1462&quot; data-ke-size=&quot;size23&quot;&gt;⚠️ 한계&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1620&quot; data-start=&quot;1472&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1519&quot; data-start=&quot;1472&quot;&gt;낮은 응집도: 같은 기능에 속한 코드가 여러 패키지로 흩어짐&lt;/li&gt;
&lt;li data-end=&quot;1567&quot; data-start=&quot;1520&quot;&gt;높은 결합도: Repository 변경 시 Controller까지 영향&lt;/li&gt;
&lt;li data-end=&quot;1620&quot; data-start=&quot;1568&quot;&gt;확장성 부족: 기능이 늘수록 Controller/Service 패키지가 거대해짐&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. Package by Feature&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Layered 철학에서 벗어나 &amp;ldquo;도메인 단위로 구조를 짜자!&amp;rdquo;는 대안적 구조&lt;/li&gt;
&lt;li&gt;각 기능(feature) 안에 controller, service, repository 배치&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1761756802026&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;├── com.app
    └── company
        ├── Company
        ├── CompanyController
        ├── CompanyRepository        
        └── CompanyService
    └── product
        ├── Product   
        ├── ProductController
        ├── ProductRepository
        └── ProductService
    └── util
    └── user
        ├── User   
        ├── UserController
        ├── UserRepository
        └── UserService&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-end=&quot;2082&quot; data-start=&quot;2073&quot; data-ke-size=&quot;size23&quot;&gt;  특징&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2163&quot; data-start=&quot;2083&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2117&quot; data-start=&quot;2083&quot;&gt;같은 기능에 필요한 코드가 모두 한곳에 모임(높은 응집도, 낮은 결합도)&lt;/li&gt;
&lt;li data-end=&quot;2163&quot; data-start=&quot;2137&quot;&gt;기능 단위로 이동, 테스트, 배포가 쉬움&lt;/li&gt;
&lt;li data-end=&quot;2163&quot; data-start=&quot;2137&quot;&gt;캡슐화 강화 (패키지 내부에서 private 접근 가능)&lt;/li&gt;
&lt;li data-end=&quot;2163&quot; data-start=&quot;2137&quot;&gt;마이크로서비스로 전환 용이&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-end=&quot;2260&quot; data-start=&quot;2251&quot; data-ke-size=&quot;size23&quot;&gt;⚠️ 단점&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2308&quot; data-start=&quot;2261&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2283&quot; data-start=&quot;2261&quot;&gt;처음 구조 설계 시 통일성이 필요&lt;/li&gt;
&lt;li data-end=&quot;2308&quot; data-start=&quot;2284&quot;&gt;공통 로직(util 등) 관리 어려움&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4. Hexagonal Architecture&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Ports and Adapters 패턴이라고도 불림&lt;/li&gt;
&lt;li&gt;비즈니스 로직(Core) 을 외부 의존성(Web, DB, Message Broker 등) 으로부터 완전히 분리하는 아키텍처&amp;nbsp;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;366&quot; data-start=&quot;318&quot;&gt;Core (Domain + Application): 순수한 비즈니스 로직&lt;/li&gt;
&lt;li data-end=&quot;429&quot; data-start=&quot;367&quot;&gt;Ports: Core가 외부와 소통하기 위한 인터페이스 (InputPort, OutputPort)&lt;/li&gt;
&lt;li data-end=&quot;479&quot; data-start=&quot;430&quot;&gt;Adapters: 실제 구현체 (Controller, Repository 등)&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1761757269756&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;├── com.app
    ├── company
    │   ├── application              # 유스케이스(서비스 계층)
    │   │   ├── CompanyService.java  # 핵심 비즈니스 로직
    │   │   └── CompanyUseCase.java  # Port(인터페이스)
    │   │
    │   ├── domain                   # 도메인 엔티티 + 도메인 로직
    │   │   └── Company.java
    │   │
    │   ├── infrastructure           # 외부 시스템과 연결되는 Adapter
    │   │   ├── persistence
    │   │   │   ├── JpaCompanyRepository.java  # Output Adapter (DB 구현체)
    │   │   │   └── CompanyEntity.java
    │   │   └── web
    │   │       └── CompanyController.java     # Input Adapter (API 진입점)
    │   │
    │   └── ports                    # 외부 의존성에 대한 Port 정의
    │       ├── in
    │       │   └── CompanyUseCase.java        # Input Port (Controller &amp;rarr; Core)
    │       └── out
    │           └── CompanyRepositoryPort.java # Output Port (Core &amp;rarr; Infra)
    │
    ├── product
    │   ├── application
    │   │   └── ProductService.java
    │   ├── domain
    │   │   └── Product.java
    │   ├── infrastructure
    │   │   ├── persistence
    │   │   │   └── JpaProductRepository.java
    │   │   └── web
    │   │       └── ProductController.java
    │   └── ports
    │       ├── in
    │       │   └── ProductUseCase.java
    │       └── out
    │           └── ProductRepositoryPort.java
    │
    └── util&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;2856&quot; data-start=&quot;2847&quot; data-ke-size=&quot;size23&quot;&gt;  특징&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2980&quot; data-start=&quot;2857&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2902&quot; data-start=&quot;2857&quot;&gt;핵심 도메인(domain)은 외부 환경(DB, Web 등)과 완전히 분리됨&lt;/li&gt;
&lt;li data-end=&quot;2955&quot; data-start=&quot;2903&quot;&gt;&amp;ldquo;의존성 역전(Inversion of Dependency)&amp;rdquo;을 통해 내부가 외부를 제어&lt;/li&gt;
&lt;li data-end=&quot;3027&quot; data-start=&quot;2992&quot;&gt;외부 교체(DB &amp;rarr; NoSQL 등) 시 도메인 영향 없음&lt;/li&gt;
&lt;li data-end=&quot;3059&quot; data-start=&quot;3028&quot;&gt;단위 테스트 용이 (mock port 활용 가능)&lt;/li&gt;
&lt;li data-end=&quot;3100&quot; data-start=&quot;3060&quot;&gt;DDD(Domain-Driven Design)와 자연스럽게 맞물림&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-end=&quot;3111&quot; data-start=&quot;3102&quot; data-ke-size=&quot;size23&quot;&gt;⚠️ 단점&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;3154&quot; data-start=&quot;3112&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;3125&quot; data-start=&quot;3112&quot;&gt;설계 복잡도 높음&lt;/li&gt;
&lt;li data-end=&quot;3154&quot; data-start=&quot;3126&quot;&gt;작은 프로젝트엔 오버엔지니어링이 될 수 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;5. 정리&lt;/b&gt;&lt;/h2&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[1]&amp;nbsp;Layered&amp;nbsp;Architecture&amp;nbsp;(철학)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;darr;&lt;br /&gt;[2]&amp;nbsp;Package&amp;nbsp;by&amp;nbsp;Layer&amp;nbsp;(구현&amp;nbsp;구조)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;darr;&lt;br /&gt;[3]&amp;nbsp;Package&amp;nbsp;by&amp;nbsp;Feature&amp;nbsp;(도메인&amp;nbsp;중심&amp;nbsp;재구성)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;darr;&lt;br /&gt;[4]&amp;nbsp;Hexagonal&amp;nbsp;Architecture&amp;nbsp;(의존성&amp;nbsp;역전,&amp;nbsp;포트/어댑터&amp;nbsp;분리)&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&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-end=&quot;3776&quot; data-start=&quot;3215&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style13&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;구분&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;Layered Architecture&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;Package by Layer&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;Package by Feature&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;Hexagonal Architecture&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;3475&quot; data-start=&quot;3407&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3419&quot; data-start=&quot;3407&quot;&gt;&lt;b&gt;구조 기준&lt;/b&gt;&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3431&quot; data-start=&quot;3419&quot;&gt;계층(역할 중심)&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3444&quot; data-start=&quot;3431&quot;&gt;계층(패키지 중심)&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3457&quot; data-start=&quot;3444&quot;&gt;기능(도메인 중심)&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3475&quot; data-start=&quot;3457&quot;&gt;포트/어댑터(도메인 중심)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;3510&quot; data-start=&quot;3476&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3486&quot; data-start=&quot;3476&quot;&gt;&lt;b&gt;응집도&lt;/b&gt;&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3491&quot; data-start=&quot;3486&quot;&gt;낮음&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3496&quot; data-start=&quot;3491&quot;&gt;낮음&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3501&quot; data-start=&quot;3496&quot;&gt;높음&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3510&quot; data-start=&quot;3501&quot;&gt;매우 높음&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;3545&quot; data-start=&quot;3511&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3521&quot; data-start=&quot;3511&quot;&gt;&lt;b&gt;결합도&lt;/b&gt;&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3526&quot; data-start=&quot;3521&quot;&gt;높음&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3531&quot; data-start=&quot;3526&quot;&gt;높음&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3536&quot; data-start=&quot;3531&quot;&gt;낮음&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3545&quot; data-start=&quot;3536&quot;&gt;매우 낮음&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;3582&quot; data-start=&quot;3546&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3558&quot; data-start=&quot;3546&quot;&gt;&lt;b&gt;유지보수성&lt;/b&gt;&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3563&quot; data-start=&quot;3558&quot;&gt;보통&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3568&quot; data-start=&quot;3563&quot;&gt;낮음&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3573&quot; data-start=&quot;3568&quot;&gt;높음&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3582&quot; data-start=&quot;3573&quot;&gt;매우 높음&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;3621&quot; data-start=&quot;3583&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3597&quot; data-start=&quot;3583&quot;&gt;&lt;b&gt;테스트 용이성&lt;/b&gt;&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3602&quot; data-start=&quot;3597&quot;&gt;낮음&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3607&quot; data-start=&quot;3602&quot;&gt;낮음&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3612&quot; data-start=&quot;3607&quot;&gt;높음&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3621&quot; data-start=&quot;3612&quot;&gt;매우 높음&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;3665&quot; data-start=&quot;3622&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3639&quot; data-start=&quot;3622&quot;&gt;&lt;b&gt;마이크로서비스 전환&lt;/b&gt;&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3645&quot; data-start=&quot;3639&quot;&gt;어려움&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3651&quot; data-start=&quot;3645&quot;&gt;어려움&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3656&quot; data-start=&quot;3651&quot;&gt;쉬움&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3665&quot; data-start=&quot;3656&quot;&gt;매우 쉬움&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;3701&quot; data-start=&quot;3666&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3679&quot; data-start=&quot;3666&quot;&gt;&lt;b&gt;설계 난이도&lt;/b&gt;&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3684&quot; data-start=&quot;3679&quot;&gt;쉬움&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3689&quot; data-start=&quot;3684&quot;&gt;쉬움&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3694&quot; data-start=&quot;3689&quot;&gt;중간&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3701&quot; data-start=&quot;3694&quot;&gt;어려움&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;3776&quot; data-start=&quot;3702&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3714&quot; data-start=&quot;3702&quot;&gt;&lt;b&gt;적용 시점&lt;/b&gt;&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3728&quot; data-start=&quot;3714&quot;&gt;초기, 간단한 서비스&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3743&quot; data-start=&quot;3728&quot;&gt;학습, 소규모 프로젝트&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3757&quot; data-start=&quot;3743&quot;&gt;중규모 이상 프로젝트&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3776&quot; data-start=&quot;3757&quot;&gt;대규모, DDD 기반 시스템&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;소프트웨어 아키텍쳐 연대기라는 글을 보았다.&lt;br /&gt;세상엔 아키텍쳐가 너무 많다.&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://herbertograca.com/2017/07/03/the-software-architecture-chronicles/&quot;&gt;https://herbertograca.com/2017/07/03/the-software-architecture-chronicles/&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>컴퓨터사이언스</category>
      <category>소프트웨어아키텍쳐</category>
      <category>패키지구조</category>
      <author>believekim</author>
      <guid isPermaLink="true">https://believekim.tistory.com/114</guid>
      <comments>https://believekim.tistory.com/entry/CS-%ED%8C%A8%ED%82%A4%EC%A7%80-%EA%B5%AC%EC%A1%B0-%EC%84%A0%ED%83%9D%ED%95%98%EA%B8%B0Package-by-Layer-vs-Package-by-Feature-vs-Hexagonal-Architecture#entry114comment</comments>
      <pubDate>Fri, 31 Oct 2025 23:09:52 +0900</pubDate>
    </item>
    <item>
      <title>[IntelliJ] TODO, FIXME와 커스텀 주석 활용법</title>
      <link>https://believekim.tistory.com/entry/IntelliJ-TODO-FIXME%EC%99%80-%EC%BB%A4%EC%8A%A4%ED%85%80-%EC%A3%BC%EC%84%9D-%ED%99%9C%EC%9A%A9%EB%B2%95</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;코드를 작성하다가 주석이 많아지다보니 코드를 설명한 주석과&lt;br /&gt;구현하거나 고쳐야할 주석을 구분하기가 어려워져 작성하게 되었다.&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. 주석 예시&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;IntelliJ 공식 문서는 기본기능과 커스텀 주석을 만드는 방법만 나와있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;a href=&quot;https://www.jetbrains.com/help/idea/using-todo.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.jetbrains.com/help/idea/using-todo.html&lt;/a&gt;&lt;/b&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1761739805823&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;TODO comments | IntelliJ&amp;nbsp;IDEA&quot; data-og-description=&quot; &quot; data-og-host=&quot;www.jetbrains.com&quot; data-og-source-url=&quot;https://www.jetbrains.com/help/idea/using-todo.html&quot; data-og-url=&quot;https://www.jetbrains.com/help/idea/using-todo.html&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/b66bSW/hyZLbuzfvo/Lf0kGtWtg8SUWSkqbKfun1/img.png?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/1rV3z/hyZMXIebPb/RrZ59k61ZJuaShogD4m2lk/img.png?width=1800&amp;amp;height=1400&amp;amp;face=0_0_1800_1400,https://scrap.kakaocdn.net/dn/bTVQQN/hyZMi8i8CT/jw3KoDg2Z3Dijk4NoPApvk/img.png?width=870&amp;amp;height=1182&amp;amp;face=0_0_870_1182&quot;&gt;&lt;a href=&quot;https://www.jetbrains.com/help/idea/using-todo.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.jetbrains.com/help/idea/using-todo.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/b66bSW/hyZLbuzfvo/Lf0kGtWtg8SUWSkqbKfun1/img.png?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/1rV3z/hyZMXIebPb/RrZ59k61ZJuaShogD4m2lk/img.png?width=1800&amp;amp;height=1400&amp;amp;face=0_0_1800_1400,https://scrap.kakaocdn.net/dn/bTVQQN/hyZMi8i8CT/jw3KoDg2Z3Dijk4NoPApvk/img.png?width=870&amp;amp;height=1182&amp;amp;face=0_0_870_1182');&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;TODO comments | IntelliJ&amp;nbsp;IDEA&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.jetbrains.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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;기본 기능은 TODO와 FIXME가 있고 View -&amp;gt; Tool Windows -&amp;gt; TODO를 클릭하면 확인할 수 있다&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1172&quot; data-origin-height=&quot;1668&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/AzD5A/dJMcaj8lwUJ/836M5f0kicRkHTWZyO5Za1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/AzD5A/dJMcaj8lwUJ/836M5f0kicRkHTWZyO5Za1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/AzD5A/dJMcaj8lwUJ/836M5f0kicRkHTWZyO5Za1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAzD5A%2FdJMcaj8lwUJ%2F836M5f0kicRkHTWZyO5Za1%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;474&quot; height=&quot;1668&quot; data-origin-width=&quot;1172&quot; data-origin-height=&quot;1668&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1332&quot; data-origin-height=&quot;610&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bv3TG6/dJMcajHg9HY/NhvJpHCL2kzEOJ4e7Bix51/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bv3TG6/dJMcajHg9HY/NhvJpHCL2kzEOJ4e7Bix51/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bv3TG6/dJMcajHg9HY/NhvJpHCL2kzEOJ4e7Bix51/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbv3TG6%2FdJMcajHg9HY%2FNhvJpHCL2kzEOJ4e7Bix51%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;513&quot; height=&quot;235&quot; data-origin-width=&quot;1332&quot; data-origin-height=&quot;610&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;하지만 주로 쓰이는 주석은 다음과 같다고 GPT에 검색했다.&lt;/li&gt;
&lt;/ul&gt;
&lt;table style=&quot;border-collapse: collapse; width: 81.0465%; height: 150px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style13&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;height: 19px; width: 18.6047%;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;태그&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 19px; width: 20.2326%;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;의미&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 19px; width: 42.093%;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;예시&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;height: 19px; width: 18.6047%;&quot;&gt;&lt;b&gt;NOTE&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 19px; width: 20.2326%;&quot;&gt;참고용 메모&lt;/td&gt;
&lt;td style=&quot;height: 19px; width: 42.093%;&quot;&gt;// NOTE: DB 커넥션은 풀링 중&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;height: 19px; width: 18.6047%;&quot;&gt;&lt;b&gt;REVIEW&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 19px; width: 20.2326%;&quot;&gt;리뷰 필요&lt;/td&gt;
&lt;td style=&quot;height: 19px; width: 42.093%;&quot;&gt;// REVIEW: 이 로직 복잡도 높음&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;height: 19px; width: 18.6047%;&quot;&gt;&lt;b&gt;OPTIMIZE&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 19px; width: 20.2326%;&quot;&gt;성능 개선&lt;/td&gt;
&lt;td style=&quot;height: 19px; width: 42.093%;&quot;&gt;// OPTIMIZE: 반복문 줄이기&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;height: 19px; width: 18.6047%;&quot;&gt;&lt;b&gt;HACK&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 19px; width: 20.2326%;&quot;&gt;임시 해결책&lt;/td&gt;
&lt;td style=&quot;height: 19px; width: 42.093%;&quot;&gt;// HACK: 예외 회피용 코드, 임시 하드코드&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;height: 19px; width: 18.6047%;&quot;&gt;&lt;b&gt;BUG&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 19px; width: 20.2326%;&quot;&gt;버그 표시&lt;/td&gt;
&lt;td style=&quot;height: 19px; width: 42.093%;&quot;&gt;// BUG: 간헐적 실패 발생&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;height: 19px; width: 18.6047%;&quot;&gt;&lt;b&gt;DEPRECATED&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 19px; width: 20.2326%;&quot;&gt;사용 중단 예정&lt;/td&gt;
&lt;td style=&quot;height: 19px; width: 42.093%;&quot;&gt;// DEPRECATED: 다음 버전에서 제거&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;style3&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. 커스텀 주석 설정 방법&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Settings -&amp;gt; Editor -&amp;gt; TODO로 들어간후 +버튼을 사용해 추가한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2004&quot; data-origin-height=&quot;1460&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bbBixL/dJMcaaQ6oJ9/viWiqwwj7LzLoyTPRkh3c1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bbBixL/dJMcaaQ6oJ9/viWiqwwj7LzLoyTPRkh3c1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bbBixL/dJMcaaQ6oJ9/viWiqwwj7LzLoyTPRkh3c1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbbBixL%2FdJMcaaQ6oJ9%2FviWiqwwj7LzLoyTPRkh3c1%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;2004&quot; height=&quot;1460&quot; data-origin-width=&quot;2004&quot; data-origin-height=&quot;1460&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;기능 확인&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-10-29 오후 9.20.45.png&quot; data-origin-width=&quot;1314&quot; data-origin-height=&quot;774&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Ajvx5/dJMcaboWjCR/opbxdTkKYzHU46kmJ1y4Y0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Ajvx5/dJMcaboWjCR/opbxdTkKYzHU46kmJ1y4Y0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Ajvx5/dJMcaboWjCR/opbxdTkKYzHU46kmJ1y4Y0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAjvx5%2FdJMcaboWjCR%2FopbxdTkKYzHU46kmJ1y4Y0%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;1314&quot; height=&quot;774&quot; data-filename=&quot;스크린샷 2025-10-29 오후 9.20.45.png&quot; data-origin-width=&quot;1314&quot; data-origin-height=&quot;774&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. 커스텀 주석 그룹화&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;TODO설정창 아래 Filters에서 +버튼을 클릭한다.&lt;/li&gt;
&lt;li&gt;Name을 지정하고 커스텀주석 항목을 선택하여 적용한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1490&quot; data-origin-height=&quot;688&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d35cOq/dJMcake67pZ/ORW6gzy2t37QAsG586jkLK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d35cOq/dJMcake67pZ/ORW6gzy2t37QAsG586jkLK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d35cOq/dJMcake67pZ/ORW6gzy2t37QAsG586jkLK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd35cOq%2FdJMcake67pZ%2FORW6gzy2t37QAsG586jkLK%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;1490&quot; height=&quot;688&quot; data-origin-width=&quot;1490&quot; data-origin-height=&quot;688&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Filter TODO Items(깔대기모양)을 클릭하면 그룹화된 내용만 따로 볼 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-10-29 오후 9.31.18.png&quot; data-origin-width=&quot;814&quot; data-origin-height=&quot;574&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b6WQGX/dJMcadUATYt/JsieMxh054A057Q0BJUsY0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b6WQGX/dJMcadUATYt/JsieMxh054A057Q0BJUsY0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b6WQGX/dJMcadUATYt/JsieMxh054A057Q0BJUsY0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb6WQGX%2FdJMcadUATYt%2FJsieMxh054A057Q0BJUsY0%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;519&quot; height=&quot;574&quot; data-filename=&quot;스크린샷 2025-10-29 오후 9.31.18.png&quot; data-origin-width=&quot;814&quot; data-origin-height=&quot;574&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4. 플러그인&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;NextTask TODO Manager는&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;JetBrains IDE에 필요한 유일한 작업 관리 플러그인입니다.&lt;/li&gt;
&lt;li&gt;아직은 나에게 과분한거 같아 설치하지는 않았다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://plugins.jetbrains.com/plugin/26765-nexttask-todo-task-manager&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://plugins.jetbrains.com/plugin/26765-nexttask-todo-task-manager&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1761741502570&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;NextTask TODO Task Manager - IntelliJ IDEs Plugin | Marketplace&quot; data-og-description=&quot;NextTask TODO Task Manager Plugin Source Code NextTask TODO Manager is the only task management plugin for JetBrains IDEs you will need. Allows you to track, organize...&quot; data-og-host=&quot;plugins.jetbrains.com&quot; data-og-source-url=&quot;https://plugins.jetbrains.com/plugin/26765-nexttask-todo-task-manager&quot; data-og-url=&quot;https://plugins.jetbrains.com/plugin/26765-nexttask-todo-task-manager&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/KVNiH/hyZMkZkHIZ/W2pxxRoJcXOxBeLJeKv7w0/img.png?width=600&amp;amp;height=600&amp;amp;face=0_0_600_600,https://scrap.kakaocdn.net/dn/by8fSD/hyZMj0pk9L/SOWNN99OJvx0ICKPxYV76K/img.png?width=600&amp;amp;height=600&amp;amp;face=0_0_600_600&quot;&gt;&lt;a href=&quot;https://plugins.jetbrains.com/plugin/26765-nexttask-todo-task-manager&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://plugins.jetbrains.com/plugin/26765-nexttask-todo-task-manager&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/KVNiH/hyZMkZkHIZ/W2pxxRoJcXOxBeLJeKv7w0/img.png?width=600&amp;amp;height=600&amp;amp;face=0_0_600_600,https://scrap.kakaocdn.net/dn/by8fSD/hyZMj0pk9L/SOWNN99OJvx0ICKPxYV76K/img.png?width=600&amp;amp;height=600&amp;amp;face=0_0_600_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;NextTask TODO Task Manager - IntelliJ IDEs Plugin | Marketplace&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;NextTask TODO Task Manager Plugin Source Code NextTask TODO Manager is the only task management plugin for JetBrains IDEs you will need. Allows you to track, organize...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;plugins.jetbrains.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1996&quot; data-origin-height=&quot;1444&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/biPCJv/dJMcadmKWEU/EhKhYGVkg9RVfOP9K2f6Ak/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/biPCJv/dJMcadmKWEU/EhKhYGVkg9RVfOP9K2f6Ak/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/biPCJv/dJMcadmKWEU/EhKhYGVkg9RVfOP9K2f6Ak/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbiPCJv%2FdJMcadmKWEU%2FEhKhYGVkg9RVfOP9K2f6Ak%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;1996&quot; height=&quot;1444&quot; data-origin-width=&quot;1996&quot; data-origin-height=&quot;1444&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>IDE/IntelliJ</category>
      <category>fixme</category>
      <category>TODO</category>
      <category>인텔리제이TODO</category>
      <category>인텔리제이주석</category>
      <author>believekim</author>
      <guid isPermaLink="true">https://believekim.tistory.com/113</guid>
      <comments>https://believekim.tistory.com/entry/IntelliJ-TODO-FIXME%EC%99%80-%EC%BB%A4%EC%8A%A4%ED%85%80-%EC%A3%BC%EC%84%9D-%ED%99%9C%EC%9A%A9%EB%B2%95#entry113comment</comments>
      <pubDate>Thu, 30 Oct 2025 15:47:23 +0900</pubDate>
    </item>
  </channel>
</rss>