<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>Passwd</title>
    <link>https://passwd.tistory.com/</link>
    <description>아무튼 개발자. 모르는 걸 적습니다.</description>
    <language>ko</language>
    <pubDate>Mon, 13 Apr 2026 20:23:55 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>비번변경</managingEditor>
    <image>
      <title>Passwd</title>
      <url>https://tistory1.daumcdn.net/tistory/4732416/attach/cd0a8ff5c5414bd5a0a47d8055f0cca6</url>
      <link>https://passwd.tistory.com</link>
    </image>
    <item>
      <title>[Java] Jackson - ArrayNode 다루기</title>
      <link>https://passwd.tistory.com/entry/Java-Jackson-ArrayNode-%EB%8B%A4%EB%A3%A8%EA%B8%B0</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size23&quot;&gt;개요&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Jackson에서 다루는 JsonNode, ObjectNode는 기본적으로 단일 JSON 데이터를 취급한다. 하지만 JSON 데이터는 Array도 지원하고 있다. 때문에 이번 글에서는 Java에서 JSON Array를 다룰 때 사용하는 ArrayNode에 대해 알아본다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;ArrayNode&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;ArrayNode는 Jackson 라이브러리에서 JSON 배열([...])을 표현하는 클래스이다. ObjectNode와 동일하게 JsonNode의 자식 클래스이고, 불변성을 가진 JsonNode와 다르게 데이터의 추가와 수정이 가능하다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt; &lt;span style=&quot;font-size: 21px;&quot;&gt;사용법&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;생성 및 요소 추가&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;생성은 ObjectNode와 같이 ObjectMapper.createArrayNode를 사용하고, 값 추가는 add 함수를 사용한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;아래는 ArrayNode를 생성하고 기본 데이터 타입, ObjectNode, ArrayNode를 추가하는 예시 코드이다.&lt;/p&gt;
&lt;div style=&quot;background-color: #ffffff; color: #080808;&quot;&gt;
&lt;pre class=&quot;java&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;

public class main {
    public static void main(String[] args) {
        ObjectMapper objectMapper = new ObjectMapper();
        ArrayNode arrayNode = objectMapper.createArrayNode();
        
        // 기본 타입 추가
        arrayNode.add(&quot;text&quot;);
        arrayNode.add(42);
        arrayNode.add(3.14);
        arrayNode.add(true);
        arrayNode.addNull();
        
        // ObjectNode 중첩
        ObjectNode obj = objectMapper.createObjectNode();
        obj.put(&quot;name&quot;, &quot;passwd&quot;);
        arrayNode.add(obj);

        // ArrayNode 중첩
        ArrayNode inner = objectMapper.createArrayNode();
        inner.add(1).add(2).add(3);
        arrayNode.add(inner);
        
        System.out.println(arrayNode);
    }&lt;/code&gt;&lt;/pre&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;436&quot; data-origin-height=&quot;180&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ddBAEh/dJMcajaI4kx/rIkcjPuWTpDwpK4KrrHtPK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ddBAEh/dJMcajaI4kx/rIkcjPuWTpDwpK4KrrHtPK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ddBAEh/dJMcajaI4kx/rIkcjPuWTpDwpK4KrrHtPK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FddBAEh%2FdJMcajaI4kx%2FrIkcjPuWTpDwpK4KrrHtPK%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;436&quot; height=&quot;180&quot; data-origin-width=&quot;436&quot; data-origin-height=&quot;180&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;직렬화&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존과 동일하게 objectMapper.writeValueAsString를 사용한다.&lt;/p&gt;
&lt;pre id=&quot;code_1775801758764&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;

public class main {
    public static void main(String[] args) {
        ObjectMapper objectMapper = new ObjectMapper();
        ArrayNode arrayNode = objectMapper.createArrayNode();
        
        // 생략

        try {
            System.out.println(objectMapper.writeValueAsString(arrayNode));
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;446&quot; data-origin-height=&quot;179&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/po3dw/dJMcagrzfrE/kHrBiLSb4zRi4NKKEKBVMK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/po3dw/dJMcagrzfrE/kHrBiLSb4zRi4NKKEKBVMK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/po3dw/dJMcagrzfrE/kHrBiLSb4zRi4NKKEKBVMK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fpo3dw%2FdJMcagrzfrE%2FkHrBiLSb4zRi4NKKEKBVMK%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;446&quot; height=&quot;179&quot; data-origin-width=&quot;446&quot; data-origin-height=&quot;179&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;요소 접근&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ArrayNode 요소에 접근할 때는 get, path를 사용한다. 배열과 동일하게 인덱스로 접근하면 된다.&lt;/p&gt;
&lt;pre id=&quot;code_1775801978086&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;

public class main {
    public static void main(String[] args) {
        ObjectMapper objectMapper = new ObjectMapper();
        ArrayNode arrayNode = objectMapper.createArrayNode();

        // 기본 타입 추가
        arrayNode.add(&quot;text&quot;);
        arrayNode.add(42);
        arrayNode.add(3.14);
        arrayNode.add(true);
        arrayNode.addNull();
       
        System.out.println(arrayNode.get(0));
        System.out.println(arrayNode.get(0).asText());
        System.out.println(arrayNode.path(1));
        System.out.println(arrayNode.path(1).asInt());
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;280&quot; data-origin-height=&quot;248&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dQ04CU/dJMcahquOAI/ZMYMRpBNbnAQXeREgwMAp0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dQ04CU/dJMcahquOAI/ZMYMRpBNbnAQXeREgwMAp0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dQ04CU/dJMcahquOAI/ZMYMRpBNbnAQXeREgwMAp0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdQ04CU%2FdJMcahquOAI%2FZMYMRpBNbnAQXeREgwMAp0%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;280&quot; height=&quot;248&quot; data-origin-width=&quot;280&quot; data-origin-height=&quot;248&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;역직렬화&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;역직렬화할 때는 ObjectNode와 동일하게 JsonNode로 역직렬화한 뒤 ArrayNode로 형변환해야 한다.&lt;/p&gt;
&lt;pre id=&quot;code_1775802900189&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;

public class main {
    public static void main(String[] args) {
        ObjectMapper objectMapper = new ObjectMapper();
        String json = &quot;[1, 2, 3]&quot;;

        try {
            JsonNode jsonNode = objectMapper.readTree(json);
            ArrayNode arrayNode = (ArrayNode) jsonNode;
            arrayNode.add(0);
            System.out.println(arrayNode);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 시작--&gt;&lt;/p&gt;
&lt;h4 style=&quot;font-size: 10px; color: #1f1f1f; border-left: #ff327f 10px solid; margin: 0px 0px 10px; letter-spacing: -1px; line-height: normal; font-stretch: normal; padding: 0px 0px 0px 7px;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-size: 21px; color: #ff327f;&quot;&gt; 참고 문서&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://yeonyeon.tistory.com/136&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://yeonyeon.tistory.com/136&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://getthismoment.tistory.com/82&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://getthismoment.tistory.com/82&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Java</category>
      <category>Java</category>
      <author>비번변경</author>
      <guid isPermaLink="true">https://passwd.tistory.com/1520</guid>
      <comments>https://passwd.tistory.com/entry/Java-Jackson-ArrayNode-%EB%8B%A4%EB%A3%A8%EA%B8%B0#entry1520comment</comments>
      <pubDate>Mon, 13 Apr 2026 16:38:13 +0900</pubDate>
    </item>
    <item>
      <title>[Java] Jackson - ObjectNode 다루기</title>
      <link>https://passwd.tistory.com/entry/Java-Jackson-ObjectNode</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size23&quot;&gt;개요&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://passwd.tistory.com/entry/Java-Jackson-JsonNode-%EB%8B%A4%EB%A3%A8%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;2026.04.08-[Java] Jackson - JsonNode 다루기&lt;/a&gt;에서 JSON 데이터를 다루기 위한 기본적인 클래스인 JsonNode에 대해 알아보았다. 하지만 JsonNode는 불변 객체로 값 수정을 할 수 없기 때문에 값을 수정하거나 추가하는 등의 작업을 수행하기에는 적합하지 않다. 이런 경우를 위해 Jackson은 ObjectNode라는 클래스를 제공한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용법을 알아보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;ObjectNode&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Jackson의 ObjecNode는 JSON 객체를 Java 코드 상에서 동적으로 생성, 수정, 삭제할 수 있는, 즉 변경 가능한(Mutable) JsonNode 하위 클래스다. 빈 ObjecNode를 생성하여 put, set과 같은 메서드로 키와 값을 추가할 수 있어 유영한 데이터 조작이 필요할 때 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt; &lt;span style=&quot;font-size: 21px;&quot;&gt;사용법&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 ObjectNode를 생성하여 값을 추가한 뒤, 직렬화해 보겠다. 빈 ObjectNode는 ObjectMapper.createObjectNode로 생성하고, put을 사용해 값을 추가한다.&lt;/p&gt;
&lt;pre id=&quot;code_1775697911960&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;

public class main {
    public static void main(String[] args) {
        ObjectMapper objectMapper = new ObjectMapper();

        ObjectNode root = objectMapper.createObjectNode();
        root.put(&quot;name&quot;,&quot;John&quot;);
        root.put(&quot;age&quot;, 20);

        try {
            System.out.println(objectMapper.writeValueAsString(root));
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }

    }&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;324&quot; data-origin-height=&quot;179&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/n86iC/dJMcadasWk2/GK8kDzWjoyjrAJVqjXG5y0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/n86iC/dJMcadasWk2/GK8kDzWjoyjrAJVqjXG5y0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/n86iC/dJMcadasWk2/GK8kDzWjoyjrAJVqjXG5y0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fn86iC%2FdJMcadasWk2%2FGK8kDzWjoyjrAJVqjXG5y0%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;324&quot; height=&quot;179&quot; data-origin-width=&quot;324&quot; data-origin-height=&quot;179&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 style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;다음으로 역직렬화를 해보자. JSON 문자열을 ObjectNode로 변환할 때는 JsonNode를 거쳐야 한다. 때문에 ObjectMapper.readTree로 JsonNode 객체를 얻은 뒤, ObjectNode로 형변환하여 사용하면 된다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;아래 코드는 JSON 문자열을 ObjectNode로 변환하여 값을 추가한 예시다.&lt;/p&gt;
&lt;pre id=&quot;code_1775697278200&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;

public class main {
    public static void main(String[] args) {
        String json = &quot;{\&quot;name\&quot;:\&quot;Passwd\&quot;,\&quot;age\&quot;:30}&quot;;

        // ObjectMapper 생성
        ObjectMapper objectMapper = new ObjectMapper();
        JsonNode jsonNode = null;
        try {
            jsonNode = objectMapper.readTree(json);

            // JsonNode -&amp;gt; JsonNode
            ObjectNode node = (ObjectNode) jsonNode;
            
            // 값 추가
            node.put(&quot;sex&quot;, &quot;male&quot;);
            System.out.println(node);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;339&quot; data-origin-height=&quot;181&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cB6Urj/dJMcaarlLmP/Kw5dqgUJeP78KoAc7c7iP1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cB6Urj/dJMcaarlLmP/Kw5dqgUJeP78KoAc7c7iP1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cB6Urj/dJMcaarlLmP/Kw5dqgUJeP78KoAc7c7iP1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcB6Urj%2FdJMcaarlLmP%2FKw5dqgUJeP78KoAc7c7iP1%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;339&quot; height=&quot;181&quot; data-origin-width=&quot;339&quot; data-origin-height=&quot;181&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 끝--&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;&lt;!--문단 마지막 사용 시작--&gt;&lt;/p&gt;
&lt;h4 style=&quot;font-size: 10px; color: #1f1f1f; border-left: #ff327f 10px solid; margin: 0px 0px 10px; letter-spacing: -1px; line-height: normal; font-stretch: normal; padding: 0px 0px 0px 7px;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #ff327f;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;참고 문서&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://yeonyeon.tistory.com/136&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://yeonyeon.tistory.com/136&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://dejavuhyo.github.io/posts/java-jackson-jsonnode-objectnode/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://dejavuhyo.github.io/posts/java-jackson-jsonnode-objectnode/&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://getthismoment.tistory.com/82&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://getthismoment.tistory.com/82&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Java</category>
      <category>Java</category>
      <author>비번변경</author>
      <guid isPermaLink="true">https://passwd.tistory.com/1519</guid>
      <comments>https://passwd.tistory.com/entry/Java-Jackson-ObjectNode#entry1519comment</comments>
      <pubDate>Fri, 10 Apr 2026 11:26:09 +0900</pubDate>
    </item>
    <item>
      <title>[Java] Jackson - JsonNode 다루기</title>
      <link>https://passwd.tistory.com/entry/Java-Jackson-JsonNode-%EB%8B%A4%EB%A3%A8%EA%B8%B0</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size23&quot;&gt;개요&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://passwd.tistory.com/entry/Java-Jackson-JSON-%EB%AC%B8%EC%9E%90%EC%97%B4%EC%9D%84-Map%EC%9C%BC%EB%A1%9C-%EB%B3%80%ED%99%98&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;2026.04.07-[Java] Jackson - JSON 문자열을 Map으로 변환&lt;/a&gt;에서 JSON 문자열을 Java Map으로 변환하는 방법을 살펴봤는데, 이 방식에는 타입 안정성이 낮다는 한계점이 존재한다. 때문에 DTO(&lt;span style=&quot;background-color: #ffffff; color: #0a0a0a; text-align: start;&quot;&gt;Data Transfer Object&lt;/span&gt;)를 생성하지 않고 데이터를 Java 객체로 변환할 때에는 일반적으로 좀 더 안정적인 JsonNode를 활용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 글에선 JsonNode에 대해서 알아보려고 한다.&lt;/p&gt;
&lt;p style=&quot;float: none; clear: none;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;JsonNode&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Jackson이 제공하는 불변 추상 클래스로, JSON 데이터를 트리 구조로 다루기 위해 제공한다. DTO 정의 없이 유연하게 데이터에 접근하고, 복잡한 &lt;span style=&quot;color: #333333; text-align: left;&quot;&gt;JSON&lt;span&gt; &lt;/span&gt;&lt;/span&gt;구조를 탐색하고 가공할 때 적합한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;특징&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;- 트리 기반 : &lt;span style=&quot;color: #333333; text-align: left;&quot;&gt;JSON&lt;/span&gt; 데이터를 노드 단위로 표현하여 구조 파악에 용이하다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;- 유연성 : DTO나 Map과 다르게 JSON 구조가 유동적이고 명확하지 않을 때 필드 존재 여부와 타입을 확인하여 안전하게 값을 처리할 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;- 불변성 : 데이터 추가, 수정할 수 없다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;- 타입 : 문자열, 숫자, Boolean, 배열, 객체 등 다양한 JSON 데이터 형식을 표현한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;사용법&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;JSON 문자열을 JsonNode로 변환할 때에는 기존에 Map과 DTO로 변환했던 것과 다르게 ObjectMapper.readTree를 사용한다.&lt;/p&gt;
&lt;pre id=&quot;code_1775610204404&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

public class main {
    public static void main(String[] args) {
        String json = &quot;{\&quot;name\&quot;:\&quot;Passwd\&quot;,\&quot;age\&quot;:30}&quot;;

        // ObjectMapper 생성
        ObjectMapper objectMapper = new ObjectMapper();

        JsonNode node = null;
        try {
            node = objectMapper.readTree(json);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
        System.out.println(json);
        System.out.println(node);
        System.out.println(node instanceof JsonNode);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 끝--&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;303&quot; data-origin-height=&quot;218&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/defCHt/dJMcacCGNlR/kUgf5tk1ykHhBgkE4iRvyK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/defCHt/dJMcacCGNlR/kUgf5tk1ykHhBgkE4iRvyK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/defCHt/dJMcacCGNlR/kUgf5tk1ykHhBgkE4iRvyK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdefCHt%2FdJMcacCGNlR%2FkUgf5tk1ykHhBgkE4iRvyK%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;303&quot; height=&quot;218&quot; data-origin-width=&quot;303&quot; data-origin-height=&quot;218&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JsonNode를 문자열로 출력하면 JSON 문자열과 동일한 결과가 나온다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;값 읽기&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특정 키의 값을 읽을 때는 get 또는 path를 사용한다.&lt;/p&gt;
&lt;pre id=&quot;code_1775610378939&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;System.out.println(node.path(&quot;name&quot;));
System.out.println(node.path(&quot;name&quot;).asText());
System.out.println(node.get(&quot;name&quot;));
System.out.println(node.get(&quot;name&quot;).asText());&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;287&quot; data-origin-height=&quot;203&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ptkfm/dJMcaf0runk/sq2TdKtQkKBjdtAEuEwGc1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ptkfm/dJMcaf0runk/sq2TdKtQkKBjdtAEuEwGc1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ptkfm/dJMcaf0runk/sq2TdKtQkKBjdtAEuEwGc1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fptkfm%2FdJMcaf0runk%2Fsq2TdKtQkKBjdtAEuEwGc1%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;287&quot; height=&quot;203&quot; data-origin-width=&quot;287&quot; data-origin-height=&quot;203&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;&lt;b&gt;직렬화&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JsonNode를 다시 직렬화하는 방법은 기존과 동일하다. 이 때 writerWithDefaultPrettyPrinter를 사용하면 들여쓰기와 개행이 포함된 문자열을 얻을 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1775610962151&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;System.out.println(objectMapper.writeValueAsString(node));

// pretty string
System.out.println(objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(node));&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;291&quot; data-origin-height=&quot;222&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bUcAvA/dJMcaadNMw0/2waZmHYEOiEtnCNVQhVTy0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bUcAvA/dJMcaadNMw0/2waZmHYEOiEtnCNVQhVTy0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bUcAvA/dJMcaadNMw0/2waZmHYEOiEtnCNVQhVTy0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbUcAvA%2FdJMcaadNMw0%2F2waZmHYEOiEtnCNVQhVTy0%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;291&quot; height=&quot;222&quot; data-origin-width=&quot;291&quot; data-origin-height=&quot;222&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 시작--&gt;&lt;/p&gt;
&lt;h4 style=&quot;font-size: 10px; color: #1f1f1f; border-left: #ff327f 10px solid; margin: 0px 0px 10px; letter-spacing: -1px; line-height: normal; font-stretch: normal; padding: 0px 0px 0px 7px;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-size: 21px; color: #ff327f;&quot;&gt; 참고 문서&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://cojoop.tistory.com/entry/Spring-API%EC%97%90%EC%84%9C-JSON-%EC%9A%94%EC%B2%AD%EC%9D%80-Map-DTO-JsonNode-%EC%A4%91-%EB%AC%B4%EC%97%87%EC%9C%BC%EB%A1%9C-%EB%B0%9B%EC%95%84%EC%95%BC-%ED%95%A0%EA%B9%8C&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt; &lt;span style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot;&gt;Spring API에서 JSON 요청은 Map, DTO, JsonNode 중 무엇으로 받아야 할까?&lt;/span&gt; &lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://blog.zungta.com/posts/3263cd4a-e46a-4ec6-a9e5-b49d3a35f9ae/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Java&amp;nbsp;JsonNode&amp;nbsp;get과&amp;nbsp;path&amp;nbsp;차이&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Java</category>
      <category>Java</category>
      <author>비번변경</author>
      <guid isPermaLink="true">https://passwd.tistory.com/1518</guid>
      <comments>https://passwd.tistory.com/entry/Java-Jackson-JsonNode-%EB%8B%A4%EB%A3%A8%EA%B8%B0#entry1518comment</comments>
      <pubDate>Wed, 8 Apr 2026 10:18:11 +0900</pubDate>
    </item>
    <item>
      <title>[Java] Jackson - JSON 문자열을 Map으로 변환</title>
      <link>https://passwd.tistory.com/entry/Java-Jackson-JSON-%EB%AC%B8%EC%9E%90%EC%97%B4%EC%9D%84-Map%EC%9C%BC%EB%A1%9C-%EB%B3%80%ED%99%98</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size23&quot;&gt;개요&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://passwd.tistory.com/entry/Java-Jackson-JSON-%EB%8B%A4%EB%A3%A8%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;2026.04.06-[Java] Jackson - JSON 다루기&lt;/a&gt;에서 JSON 문자열과 Java 객체 간에 데이터 변환 수행 방법을 알아보았다. 다만 이 방법은 데이터 모델 클래스를 별도로 만들어주어야 한다는 번거로움이 있다. 클래스가 아니라 단순 Map으로 처리할 방법은 없을까? 정리해 둔다.&lt;/p&gt;
&lt;p style=&quot;float: none; clear: none;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;JSON 문자열 -&amp;gt; Map&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;JSON 문자열을 Map으로 변환하는 건 별도 클래스로 변환하는 것과 동일한 방식으로 처리할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1775520352090&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Map;

public class main {
    public static void main(String[] args) {
        String json = &quot;{\&quot;name\&quot;:\&quot;Passwd\&quot;,\&quot;age\&quot;:30}&quot;;

        // ObjectMapper 생성
        ObjectMapper objectMapper = new ObjectMapper();
        try {
            // JSON 문자열을 Map으로 변환
            Map user = objectMapper.readValue(json, Map.class);
            System.out.println(user);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;313&quot; data-origin-height=&quot;180&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/D0msj/dJMb99MFGdd/cimXrkkpcAeJvKQEAulUik/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/D0msj/dJMb99MFGdd/cimXrkkpcAeJvKQEAulUik/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/D0msj/dJMb99MFGdd/cimXrkkpcAeJvKQEAulUik/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FD0msj%2FdJMb99MFGdd%2FcimXrkkpcAeJvKQEAulUik%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;313&quot; height=&quot;180&quot; data-origin-width=&quot;313&quot; data-origin-height=&quot;180&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;만약 중첩이 있거나 복잡한 경우에는 타입 안정성을 위해 전체 제네릭 타입 정보를 전달하는 TypeReference를 사용해도 된다.&lt;/p&gt;
&lt;pre id=&quot;code_1775520543660&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Map;

public class main {
    public static void main(String[] args) {
        String json = &quot;{\&quot;name\&quot;:\&quot;Passwd\&quot;,\&quot;age\&quot;:30}&quot;;

        // ObjectMapper 생성
        ObjectMapper objectMapper = new ObjectMapper();
        try {
            // JSON 문자열을 Map으로 변환
            Map&amp;lt;String, String&amp;gt; map = objectMapper.readValue(json, new TypeReference&amp;lt;Map&amp;lt;String, Object&amp;gt;&amp;gt;(){});
            System.out.println(map);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;Map -&amp;gt; JSON&amp;nbsp;문자열&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;반대로 Map을 JSON 문자열로 직렬화하는 방법도 기존과 동일하다.&lt;/p&gt;
&lt;pre id=&quot;code_1775522625140&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.util.HashMap;
import java.util.Map;

public class main {
    public static void main(String[] args) {
        Map&amp;lt;String, Object&amp;gt; map = new HashMap&amp;lt;&amp;gt;();
        map.put(&quot;name&quot;, &quot;Passwd&quot;);
        map.put(&quot;age&quot;, 30);
        
        // ObjectMapper 생성
        ObjectMapper objectMapper = new ObjectMapper();
        
        try {
            // Map을 JSON 문자열로 변환
            String jsonString = objectMapper.writeValueAsString(map);
            System.out.println(jsonString);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }

    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;299&quot; data-origin-height=&quot;179&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/LSpqX/dJMcadVPlSp/UffbarZyNEpSbXpk8FWFp1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/LSpqX/dJMcadVPlSp/UffbarZyNEpSbXpk8FWFp1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/LSpqX/dJMcadVPlSp/UffbarZyNEpSbXpk8FWFp1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLSpqX%2FdJMcadVPlSp%2FUffbarZyNEpSbXpk8FWFp1%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;299&quot; height=&quot;179&quot; data-origin-width=&quot;299&quot; data-origin-height=&quot;179&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;다만 Map을 활용하는 건 오타에 취약하고 데이터 의미를 파악하기 어렵다. 또한 존재하지 않는 키를 참조하거나 잘못된 타입으로 형변환 하는 등의 오류를 수반할 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 시작--&gt;&lt;/p&gt;
&lt;h4 style=&quot;font-size: 10px; color: #1f1f1f; border-left: #ff327f 10px solid; margin: 0px 0px 10px; letter-spacing: -1px; line-height: normal; font-stretch: normal; padding: 0px 0px 0px 7px;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-size: 21px; color: #ff327f;&quot;&gt; 참고 문서&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://4urdev.tistory.com/92&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://4urdev.tistory.com/92&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://codewos.tistory.com/67&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://codewos.tistory.com/67&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Java</category>
      <category>Java</category>
      <author>비번변경</author>
      <guid isPermaLink="true">https://passwd.tistory.com/1517</guid>
      <comments>https://passwd.tistory.com/entry/Java-Jackson-JSON-%EB%AC%B8%EC%9E%90%EC%97%B4%EC%9D%84-Map%EC%9C%BC%EB%A1%9C-%EB%B3%80%ED%99%98#entry1517comment</comments>
      <pubDate>Wed, 8 Apr 2026 10:11:51 +0900</pubDate>
    </item>
    <item>
      <title>[Java] Jackson - JSON 다루기</title>
      <link>https://passwd.tistory.com/entry/Java-Jackson-JSON-%EB%8B%A4%EB%A3%A8%EA%B8%B0</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size23&quot;&gt;Jackson&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;604&quot; data-origin-height=&quot;211&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cowf3S/dJMcaf7b2m1/KpBMdosT9hKK5UWeaq8Mek/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cowf3S/dJMcaf7b2m1/KpBMdosT9hKK5UWeaq8Mek/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cowf3S/dJMcaf7b2m1/KpBMdosT9hKK5UWeaq8Mek/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcowf3S%2FdJMcaf7b2m1%2FKpBMdosT9hKK5UWeaq8Mek%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;604&quot; height=&quot;211&quot; data-origin-width=&quot;604&quot; data-origin-height=&quot;211&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Jackson은 대표적인 Java JSON 라이브러리 중 하나로, Java 객체(POJO, &lt;span style=&quot;background-color: #ffffff; color: #474747; text-align: start;&quot;&gt;Plain Old Java Object&lt;/span&gt;)를 JSON 형식의 데이터로 직렬화하거나 JSON 형식의 데이터를 Java 객체(POJO)로 역직렬화한다. 또한 JSON 뿐만 아니라 Avro, BSON, Smile, Properties 등 다양한 데이터 형식을 지원하기도 한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;현재는 2.x(com.fasterxml.jackson), 3.x(tools.jackson) 버전이 유지보수되고 있다. 2.x 버전 기준으로 Jackson은 세 개의 코어 모듈로 이루어져 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;jackson-core : 스트리밍. 가장 낮은 수준의 입출력 처리를 지원하면 JsonParsor, JsonGenerator을 통해 코튼 단위로 데이터를 읽고 쓴다.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot;&gt;jackson-annotations : 범용 어노테이션&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot;&gt;jackson-databind : Databind. 데이터를 트리 구조로 표현하거나 객체와 데이터 간 자동 매핑을 수행한다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;설치&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;작성일 기준 가장 많이 사용 중인 것으로 추정하는 2.x 버전으로 설치한다. 참고로 이 글에서는 gradle로 의존성을 관리하고 있기 때문에 build.gradle 파일의 dependencies에 아래 내용을 추가한다.&lt;/p&gt;
&lt;pre id=&quot;code_1775434241600&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;dependencies {
    implementation 'com.fasterxml.jackson.core:jackson-databind:2.16.1'
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot;&gt;jackson-databind는 &lt;span style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot;&gt;jackson-core, &lt;span style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot;&gt;jackson-&lt;span style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot;&gt;annotations&lt;span&gt; 모두 의존하고 있기 때문에 &lt;span style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot;&gt;jackson-databind만 추가해 주면 된다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt; &lt;span style=&quot;font-size: 21px;&quot;&gt;사용법&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Jackson은 ObjectMapper라는 클래스를 선언하는 것부터 시작한다. 즉, Jackson은 ObjectMapper를 통해 Java 객체와 JSON 문자열 간의 데이터 직렬화와 역직렬화를 수행한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;예로 들어 아래와 같은 Java 객체를 JSON 문자열로 직렬화한다고 하자.&lt;/p&gt;
&lt;pre id=&quot;code_1775434950517&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class User {
    String name;
    int age;
    
    // 기본 생성자, Getter, Setter 생략
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이 경우, 아래와 같은 흐름으로 객체를 직렬화할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1775435150605&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

public class main {
    public static void main(String[] args) {
        User user = new User(&quot;Passwd&quot;, 30);
        
        // ObjectMapper 생성
        ObjectMapper objectMapper = new ObjectMapper();

        try {
            // 객체를 JSON 문자열로 변환
            System.out.println(objectMapper.writeValueAsString(user));
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;329&quot; data-origin-height=&quot;193&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/brG9zQ/dJMb996ZGsi/XfASbCfk1qogBlWKIP4xP0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/brG9zQ/dJMb996ZGsi/XfASbCfk1qogBlWKIP4xP0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/brG9zQ/dJMb996ZGsi/XfASbCfk1qogBlWKIP4xP0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbrG9zQ%2FdJMb996ZGsi%2FXfASbCfk1qogBlWKIP4xP0%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;329&quot; height=&quot;193&quot; data-origin-width=&quot;329&quot; data-origin-height=&quot;193&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;반대로 JSON 문자열을 역직렬화하는 방법은 다음과 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1775436036097&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

public class main {
    public static void main(String[] args) {
        String json = &quot;{\&quot;name\&quot;:\&quot;Passwd\&quot;,\&quot;age\&quot;:30}&quot;;

        // ObjectMapper 생성
        ObjectMapper objectMapper = new ObjectMapper();
        try {
            // JSON 문자열을 객체로 변환
            User user = objectMapper.readValue(json, User.class);
            System.out.println(user.getName() + &quot;, &quot; + user.getAge());
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;305&quot; data-origin-height=&quot;183&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bdfnpj/dJMcahjGG1r/klb05DPEW6BjgMcFkiCvp0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bdfnpj/dJMcahjGG1r/klb05DPEW6BjgMcFkiCvp0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bdfnpj/dJMcahjGG1r/klb05DPEW6BjgMcFkiCvp0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbdfnpj%2FdJMcahjGG1r%2Fklb05DPEW6BjgMcFkiCvp0%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;305&quot; height=&quot;183&quot; data-origin-width=&quot;305&quot; data-origin-height=&quot;183&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 시작--&gt;&lt;/p&gt;
&lt;h4 style=&quot;font-size: 10px; color: #1f1f1f; border-left: #ff327f 10px solid; margin: 0px 0px 10px; letter-spacing: -1px; line-height: normal; font-stretch: normal; padding: 0px 0px 0px 7px;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #ff327f;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;참고 문서&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/fasterxml/jackson&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/fasterxml/jackson&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://velog.io/@whwo9745/Java-Jackson-ObjectMapper-%EC%82%AC%EC%9A%A9%EB%B2%95&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;[Java]&amp;nbsp;Jackson&amp;nbsp;-&amp;nbsp;ObjectMapper&amp;nbsp;사용법&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Java</category>
      <category>Java</category>
      <author>비번변경</author>
      <guid isPermaLink="true">https://passwd.tistory.com/1516</guid>
      <comments>https://passwd.tistory.com/entry/Java-Jackson-JSON-%EB%8B%A4%EB%A3%A8%EA%B8%B0#entry1516comment</comments>
      <pubDate>Tue, 7 Apr 2026 10:42:12 +0900</pubDate>
    </item>
    <item>
      <title>[Gradle] Task</title>
      <link>https://passwd.tistory.com/entry/Gradle-Task</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size23&quot;&gt;개요&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://passwd.tistory.com/entry/Java-Gradle-%EA%B8%B0%EB%B3%B8-%EA%B0%9C%EB%85%90&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;2026.03.27-[Java] Gradle 기본 개념&lt;/a&gt;에서 Task에 대해 언급했는데 이번 글에서 조금 더 알아보려고 한다.&lt;/p&gt;
&lt;p style=&quot;float: none; clear: none;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;Task&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Task는 빌드가 수행하는 독립적인 실행 단위를 말하며, 클래스 컴파일, jar 생성, javadoc 생성 등의 작업이 해당된다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;일반적인 작업 유형은 다음과 같다&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;- 소스 코드 컴파일&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;- 테스트 실행&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;- 패키징 생성&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;- 문서 생성&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;- 저장소에 빌드 아티팩트 게시&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;각 작업은 독립적이나 다른 작업이 먼저 실행될 수 있으며, gradle은 가장 효율적인 작업 실행 순서를 파악하고 최신 상태인 작업은 건너뛴다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;Task 수행&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;아래 명령어로 Task를 실행시킬 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1775093259381&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;./gradlew TASK_NAME

# 예시
./gradlew build

## 사용할 수 있는 task 확인
./gradlew tasks

## 기존 output 제거
./gradlew clean&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;gradle은 각 태스크가 내부적으로 의존하는 관계를 파악한 후 가장 먼저 수행해야 하는 task 순서대로 수행한다. 가령 build를 수행하면 compileJava, testm jar 등도 함께 수행한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;430&quot; data-origin-height=&quot;353&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cuIrzI/dJMcai3Pmuw/okupTpAKUPlJg3LsDG7shk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cuIrzI/dJMcai3Pmuw/okupTpAKUPlJg3LsDG7shk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cuIrzI/dJMcai3Pmuw/okupTpAKUPlJg3LsDG7shk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcuIrzI%2FdJMcai3Pmuw%2FokupTpAKUPlJg3LsDG7shk%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;430&quot; height=&quot;353&quot; data-origin-width=&quot;430&quot; data-origin-height=&quot;353&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;Task 종류&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;gradle은 다양한 태스크를 가지고 있다. 이 글에서는 대표적인 태스크만 정리한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;build&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;애플리케이션 소스코드를 실행화하는 task로, 라이브러리 의존성 확인, 리소스 파일 패키징, 소스 코드 컴파일, 테스트 코드 수행 등을 수행하여 산출물인 apk 파일을 생성한다. 태스크가 성공적으로 완료되었다면 모든 테스트를 통과하여 애플리케이션이 생성되었음을 의미한다. 그리고 프로젝트의 build 디렉터리에 수행 결과를 생성한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;308&quot; data-origin-height=&quot;191&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KeZuG/dJMcacJorB9/7ceKRXHiClkqEIKHCobnK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KeZuG/dJMcacJorB9/7ceKRXHiClkqEIKHCobnK0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KeZuG/dJMcacJorB9/7ceKRXHiClkqEIKHCobnK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKeZuG%2FdJMcacJorB9%2F7ceKRXHiClkqEIKHCobnK0%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;308&quot; height=&quot;191&quot; data-origin-width=&quot;308&quot; data-origin-height=&quot;191&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;classes : java 소스 파일에 대해 컴파일러를 실행한 결과인 컴파일된 .class 파일을 포함한다.&lt;/li&gt;
&lt;li&gt;libs : 생성된 jar 파일, 실행 또는 게시할 수 있도록 컴파일된 클래스가 포함된 아카이브를 저장한다.&lt;/li&gt;
&lt;li&gt;reports : 테스트 결과를 요약한 HTML 보고서를 포함한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;gradle은 기본적으로 재빌드 시 이전 빌드와 비교하여 재빌드가 필요한 부분만 판단하여 빌드하는 증분 빌드를 지향한다. 이때 필요한 부분만 빌드할 수 있도록 캐싱하는 것을 빌드 캐시라고 한다.&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;clean&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;build를 통해 생성된 모든 아티팩트를 포함해 빌드 캐시, gradle 디렉터리 등 산출물을 삭제하여 프로젝트를 초기 빌드 상태로 되돌린다. 캐시 된 데이터가 많은 경우에는 캐시 데이터를 불러오는 시간이 디스크 저장 데이터를 불러오는 시간보다 길어질 수 있어 전체 빌드 시간이 증가할 수 있다. 또한 디스크 공간 부족으로 빌드가 실패할 수 있기 때문에 clean 태스크를 통해 빌드 시간을 단축하고 안정성을 올릴 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;test&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트에 구현된 단위 테스트를 실행한다. 기본적으로 모든 단위 테스트를 수행하는데, 옵션을 통해 특정 테스트만 수행할 수도 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1775093203510&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 특정 하위프로젝트 전체 TestCase 수행
./gradlew &amp;lt;module&amp;gt;:testDebugUnitTest

# 특정 패키지에 대한 TestCase 수행
./gradlew &amp;lt;module&amp;gt;:testDebugUnitTest --tests &quot;&amp;lt;package&amp;gt;.*&quot;

# 특정 TestCase만 수행
./gradlew &amp;lt;module&amp;gt;:testDebugUnitTest --tests &quot;&amp;lt;package&amp;gt;.&amp;lt;test_name&amp;gt;&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;dependencies&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트에서 사용하는 라이브러리에 대한 의존성 트리를 확인할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1775093232035&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;./gradlew dependencies
./gradlew &amp;lt;module&amp;gt;:dependencies&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;737&quot; data-origin-height=&quot;683&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/UjGKa/dJMcagSxVyZ/j9y8MhgTFiYJAgoCEIlYg1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/UjGKa/dJMcagSxVyZ/j9y8MhgTFiYJAgoCEIlYg1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/UjGKa/dJMcagSxVyZ/j9y8MhgTFiYJAgoCEIlYg1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FUjGKa%2FdJMcagSxVyZ%2Fj9y8MhgTFiYJAgoCEIlYg1%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;737&quot; height=&quot;683&quot; data-origin-width=&quot;737&quot; data-origin-height=&quot;683&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;gradle에서는 하나의 라이브러리에 대해 서로 다른 버전을 사용할 때 발생하는데, gradle은 사용자가 어떤 버전을 사용할 지 알 수 없기 때문에 에러 메시지를 출력한다. 이때 사용자가 의존성 트리를 활용해 문제가 되는 라이브러리를 찾아 해결하는 방식으로 활용할 수 있다.&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;!--부제목사용1 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 시작--&gt;&lt;/p&gt;
&lt;h4 style=&quot;font-size: 10px; color: #1f1f1f; border-left: #ff327f 10px solid; margin: 0px 0px 10px; letter-spacing: -1px; line-height: normal; font-stretch: normal; padding: 0px 0px 0px 7px;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-size: 21px; color: #ff327f;&quot;&gt; 참고 문서&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;color: #555555; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a style=&quot;color: #3d62ce;&quot; href=&quot;https://go-gradually.tistory.com/entry/Gradle-Gradle-%EA%B8%B0%EB%B3%B8-%EA%B5%AC%EC%A1%B0-%EC%95%8C%EC%95%84%EB%B3%B4%EA%B8%B0&quot;&gt;[Gradle]&amp;nbsp;Gradle&amp;nbsp;-&amp;nbsp;기본&amp;nbsp;구조&amp;nbsp;알아보기&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://velog.io/@alsgus92/Android-Gradle-Task%EB%8A%94-%EB%8F%84%EB%8C%80%EC%B2%B4-%EC%96%B4%EB%96%A4-%EC%97%AD%ED%95%A0%EC%9D%84-%EC%88%98%ED%96%89-%ED%95%98%EB%8A%94-%EA%B1%B8%EA%B9%8C&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;[Android]&amp;nbsp;Gradle&amp;nbsp;Task&amp;nbsp;종류&amp;nbsp;및&amp;nbsp;사용법&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Java</category>
      <category>Gradle</category>
      <author>비번변경</author>
      <guid isPermaLink="true">https://passwd.tistory.com/1515</guid>
      <comments>https://passwd.tistory.com/entry/Gradle-Task#entry1515comment</comments>
      <pubDate>Mon, 6 Apr 2026 11:30:52 +0900</pubDate>
    </item>
    <item>
      <title>[Gradle] 종속성 관리</title>
      <link>https://passwd.tistory.com/entry/Gradle-%EC%A2%85%EC%86%8D%EC%84%B1-%EA%B4%80%EB%A6%AC</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size23&quot;&gt;개요&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Gradle의 주요 기능 중 하나는 프로젝트의 종속성을 편하게 관리할 수 있다는 것이다. 이번 글에서는 Gradle에서의 종속성 관리에 대해서 알아보려고 한다.&lt;/p&gt;
&lt;p style=&quot;float: none; clear: none;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt; &lt;span style=&quot;font-size: 21px;&quot;&gt;종속성&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Gradle에서 종속성이란 프로젝트 빌드를 지원하는 jar, 플러그인, 라이브러리 및 소스 코드와 같은 외부 리소스를 의미하는데, build.gradle이라는 빌드 스크립트에서 선언된다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Gradle은 종속성을 다운로드, 캐싱, 해결하는 작업을 자동으로 처리하여 사용자가 직접 관리할 필요가 없게 한다. 또한 버전 충돌을 처리하고 유연한 버전 선언을 가능하게 한다. 그리고 일련의 자동화 기술을 바로 종속성 관리하고 한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt; &lt;span style=&quot;font-size: 21px;&quot;&gt;종속성 선언&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;종속성은 아래 예시와 같이 선언하면 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;462&quot; data-origin-height=&quot;185&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/U3Sj1/dJMcabcAfOl/PThRXibuSjPnKLT0daaZck/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/U3Sj1/dJMcabcAfOl/PThRXibuSjPnKLT0daaZck/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/U3Sj1/dJMcabcAfOl/PThRXibuSjPnKLT0daaZck/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FU3Sj1%2FdJMcabcAfOl%2FPThRXibuSjPnKLT0daaZck%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;462&quot; height=&quot;185&quot; data-origin-width=&quot;462&quot; data-origin-height=&quot;185&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;1번의 경우 java-library 플러그인을 적용한다는 것을 의미하고, 2-3번은 각 라이브러리에 대한 종속성 추가를 의미한다. 라이브러리 추가에 사용한 메서드(implementation, api)가 서로 다른데 gradle은 필요에 맞는 메서드를 선택하여 사용할 수 있도록 여러 가지 메서드를 지원하고 있다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 181px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style8&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;width: 23.1395%; height: 21px;&quot;&gt;구성&lt;/td&gt;
&lt;td style=&quot;width: 76.8605%; height: 21px;&quot;&gt;설명&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;width: 23.1395%; height: 21px;&quot;&gt;implemantation&lt;/td&gt;
&lt;td style=&quot;width: 76.8605%; height: 21px;&quot;&gt;컴파일, 런타임에 필요한 종속성&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;width: 23.1395%; height: 21px;&quot;&gt;api&lt;/td&gt;
&lt;td style=&quot;width: 76.8605%; height: 21px;&quot;&gt;컴파일, 런타임에 필요한 종속성이 게시된 api에 포함되어 있음&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;width: 23.1395%; height: 21px;&quot;&gt;compileOnly&lt;/td&gt;
&lt;td style=&quot;width: 76.8605%; height: 21px;&quot;&gt;컴파일에만 필요한 종속성&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;width: 23.1395%; height: 21px;&quot;&gt;compileOnlyApi&lt;/td&gt;
&lt;td style=&quot;width: 76.8605%; height: 21px;&quot;&gt;컴파일에만 필요한 종속성이 게시도니 api에 포함되어 있음&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;width: 23.1395%; height: 21px;&quot;&gt;runtimeOnly&lt;/td&gt;
&lt;td style=&quot;width: 76.8605%; height: 21px;&quot;&gt;런타임에만 필요한 종속성&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 23.1395%; height: 17px;&quot;&gt;testImplementation&lt;/td&gt;
&lt;td style=&quot;width: 76.8605%; height: 17px;&quot;&gt;테스트를 컴파일하고 실행하는데 필요한 종속성&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;width: 23.1395%; height: 21px;&quot;&gt;testCompileOnly&lt;/td&gt;
&lt;td style=&quot;width: 76.8605%; height: 21px;&quot;&gt;테스트 컴파일에만 필요한 종속성&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 23.1395%; height: 17px;&quot;&gt;testRuntimeOnly&lt;/td&gt;
&lt;td style=&quot;width: 76.8605%; height: 17px;&quot;&gt;테스트 실행에만 필요한 종속성&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;종속성 확인&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;gradle은 dependencies task를 사용해 종속성 트리를 확인할 수 있다. 실행 명령어는 다음과 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1775003031454&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# app 프로젝트 내 종속성 확인
./gradlew :app:dependecies&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;721&quot; data-origin-height=&quot;539&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cJvJQH/dJMcaiJwQqe/k8scahEOfQcnpYpQArRom1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cJvJQH/dJMcaiJwQqe/k8scahEOfQcnpYpQArRom1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cJvJQH/dJMcaiJwQqe/k8scahEOfQcnpYpQArRom1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcJvJQH%2FdJMcaiJwQqe%2Fk8scahEOfQcnpYpQArRom1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;721&quot; height=&quot;539&quot; data-origin-width=&quot;721&quot; data-origin-height=&quot;539&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;버전 카탈로그 활용&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;버전 정보는 build.gradle에서 분리해 특정 카탈로그에 모아서 관리할 수도 있다. 카탈로그는 libs.versions.toml로 정의하며, 루트 폴더의 gradle 폴더에 위치해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;카탈로그는 4개의 섹션으로 이루어져있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;[versions]: 플러그인과 라이브러리가 참조할 버전 번호를 선언한다.&lt;/li&gt;
&lt;li&gt;[libraries]: 빌드 파일에서 사용되는 라이브러리를 정의한다.&lt;/li&gt;
&lt;li&gt;[bundles]: 종속성 집합을 정의한다.&lt;/li&gt;
&lt;li&gt;[plugins]: 플러그인을 정의한다.&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;824&quot; data-origin-height=&quot;216&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/VkYhQ/dJMcafzkkHy/eLTYkiLoZvpvCvz5FPBKJ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/VkYhQ/dJMcafzkkHy/eLTYkiLoZvpvCvz5FPBKJ1/img.png&quot; data-alt=&quot;libs.versions.toml&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/VkYhQ/dJMcafzkkHy/eLTYkiLoZvpvCvz5FPBKJ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FVkYhQ%2FdJMcafzkkHy%2FeLTYkiLoZvpvCvz5FPBKJ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;824&quot; height=&quot;216&quot; data-origin-width=&quot;824&quot; data-origin-height=&quot;216&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;libs.versions.toml&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래는 카탈로그에 정의한 정보를 참조하여 작성한 build.gradle이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;398&quot; data-origin-height=&quot;151&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NoYJe/dJMcagLLZN8/N9jADmPjpO7y0WYn3YKyZk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NoYJe/dJMcagLLZN8/N9jADmPjpO7y0WYn3YKyZk/img.png&quot; data-alt=&quot;build.gradle&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NoYJe/dJMcagLLZN8/N9jADmPjpO7y0WYn3YKyZk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNoYJe%2FdJMcagLLZN8%2FN9jADmPjpO7y0WYn3YKyZk%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;398&quot; height=&quot;151&quot; data-origin-width=&quot;398&quot; data-origin-height=&quot;151&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;build.gradle&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 시작--&gt;&lt;/p&gt;
&lt;h4 style=&quot;font-size: 10px; color: #1f1f1f; border-left: #ff327f 10px solid; margin: 0px 0px 10px; letter-spacing: -1px; line-height: normal; font-stretch: normal; padding: 0px 0px 0px 7px;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #ff327f;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;참고 문서&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;color: #555555; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a style=&quot;color: #3d62ce;&quot; href=&quot;https://go-gradually.tistory.com/entry/Gradle-Gradle-%EA%B8%B0%EB%B3%B8-%EA%B5%AC%EC%A1%B0-%EC%95%8C%EC%95%84%EB%B3%B4%EA%B8%B0&quot;&gt;[Gradle]&amp;nbsp;Gradle&amp;nbsp;-&amp;nbsp;기본&amp;nbsp;구조&amp;nbsp;알아보기&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://developer.android.com/build/dependencies?hl=ko#:~:text=%EB%AA%A8%EB%93%88%EC%97%90%20api%20%EC%A2%85%EC%86%8D%20%ED%95%AD%EB%AA%A9%EC%9D%B4%20%ED%8F%AC%ED%95%A8%EB%90%98%EB%A9%B4%20%EB%AA%A8%EB%93%88%EC%9D%B4%20%EB%8B%A4%EB%A5%B8,%EC%88%98%20%EC%9E%88%EB%8F%84%EB%A1%9D%20%ED%95%9C%EB%8B%A4%EB%8A%94%20%EA%B2%83%EC%9D%84%20Gradle%EC%97%90%20%EC%95%8C%EB%A0%A4%EC%A3%BC%EB%8A%94%20%EA%B2%83&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;빌드&amp;nbsp;종속&amp;nbsp;항목&amp;nbsp;추가&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Java</category>
      <category>Gradle</category>
      <author>비번변경</author>
      <guid isPermaLink="true">https://passwd.tistory.com/1514</guid>
      <comments>https://passwd.tistory.com/entry/Gradle-%EC%A2%85%EC%86%8D%EC%84%B1-%EA%B4%80%EB%A6%AC#entry1514comment</comments>
      <pubDate>Fri, 3 Apr 2026 10:28:23 +0900</pubDate>
    </item>
    <item>
      <title>[Gradle] settings.gradle / build.gradle</title>
      <link>https://passwd.tistory.com/entry/Gradle-settingsgradle-buildgradle</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size23&quot;&gt;개요&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;최근 &lt;a href=&quot;https://passwd.tistory.com/entry/Gradle-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EA%B5%AC%EC%A1%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;2026.03.30-[Gradle] 프로젝트 구조와 Wrapper&lt;/a&gt; 글을 통해 gradle 프로젝트의 구조와 wrapper에 대해서 알아보았다. 이번 글에서는 gradle의 설정 파일에 해당하는 settings.gradle에 대해서 알아보려고 한다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;settings.gradle&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;settings.gradle은 프로젝트의 구조를 정의하고 빌드에 하위 프로젝트를 추가하는 역할을 담당한다. 싱글 모듈 프로젝트인 경우에는 선택적으로 사용하고, 멀티 모듈 프로젝트인 경우에는 모든 하위 프로젝트를 선언하기 위해 &lt;span style=&quot;color: #333333; text-align: left;&quot;&gt;필수적으로&lt;span&gt; &lt;/span&gt;&lt;/span&gt;사용해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;settings.gradle은 크게 두 가지 요소로 구성된다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;717&quot; data-origin-height=&quot;374&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7QI9f/dJMcahDRoMu/Fa9I1eg8rfh5v8mzOiP4S1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7QI9f/dJMcahDRoMu/Fa9I1eg8rfh5v8mzOiP4S1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7QI9f/dJMcahDRoMu/Fa9I1eg8rfh5v8mzOiP4S1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7QI9f%2FdJMcahDRoMu%2FFa9I1eg8rfh5v8mzOiP4S1%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;717&quot; height=&quot;374&quot; data-origin-width=&quot;717&quot; data-origin-height=&quot;374&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;프로젝트 이름 (rootProject.name)&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;하나만 존재한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;하위 프로젝트&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;해당 프로젝트에 포함된 하위 프로젝트를 선언한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;build.gradle&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;build.gradle은 빌드 구성, task, plugin에 대한 세부 정보를 포함하며, 최소 하나의 빌드 스크립트로 구성된다. groovy, kotlin으로 작성하며 멀티 모듈 프로젝트에서 하위 프로젝트는 자신의 루트 디렉터리에 build.gradle을 가진다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;빌드 스크립트는 플러그인과 종속성을 지정하는데, 이때 종속성은 gradle 자체 또는 빌드 스크립트에 필요한 플러그인, 라이브러리, 그리고 프로젝트 코드 컴파일 및 실행하기 위한 라이브러리 종속성에 해당한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;아래는 build.gradle 예시이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;762&quot; data-origin-height=&quot;413&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bajMuW/dJMcabXYvDK/ClGzGyP3xIsNjpQV6IBmgK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bajMuW/dJMcabXYvDK/ClGzGyP3xIsNjpQV6IBmgK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bajMuW/dJMcabXYvDK/ClGzGyP3xIsNjpQV6IBmgK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbajMuW%2FdJMcabXYvDK%2FClGzGyP3xIsNjpQV6IBmgK%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;762&quot; height=&quot;413&quot; data-origin-width=&quot;762&quot; data-origin-height=&quot;413&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 플러그인&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;gradle 기능을 확장하고 프로젝트에 task를 추가하는 작업. 플러그인 추가는 플러그인 적용이라고 하며 예시에서는 application 플러그인을 추가한 모습이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. 종속성&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;예시의 경우 jUnit Jupiter를 의존성에 추가한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. convnetion properties&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;사용하고자 한 플러그인에 convention property를 지정한다. 예시는 application 플러그인에 필요한 mainClass 속성을 지정한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 시작--&gt;&lt;/p&gt;
&lt;h4 style=&quot;font-size: 10px; color: #1f1f1f; border-left: #ff327f 10px solid; margin: 0px 0px 10px; letter-spacing: -1px; line-height: normal; font-stretch: normal; padding: 0px 0px 0px 7px;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #ff327f;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;참고 문서&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;color: #555555; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a style=&quot;color: #3d62ce;&quot; href=&quot;https://go-gradually.tistory.com/entry/Gradle-Gradle-%EA%B8%B0%EB%B3%B8-%EA%B5%AC%EC%A1%B0-%EC%95%8C%EC%95%84%EB%B3%B4%EA%B8%B0&quot;&gt;[Gradle]&amp;nbsp;Gradle&amp;nbsp;-&amp;nbsp;기본&amp;nbsp;구조&amp;nbsp;알아보기&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Java</category>
      <category>Gradle</category>
      <author>비번변경</author>
      <guid isPermaLink="true">https://passwd.tistory.com/1513</guid>
      <comments>https://passwd.tistory.com/entry/Gradle-settingsgradle-buildgradle#entry1513comment</comments>
      <pubDate>Thu, 2 Apr 2026 14:57:08 +0900</pubDate>
    </item>
    <item>
      <title>[Gradle] 프로젝트 구조와 Wrapper</title>
      <link>https://passwd.tistory.com/entry/Gradle-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EA%B5%AC%EC%A1%B0</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size23&quot;&gt;개요&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://passwd.tistory.com/entry/Java-Gradle-%EA%B8%B0%EB%B3%B8-%EA%B0%9C%EB%85%90&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;2026.03.27-[Java] Gradle 기본 개념&lt;/a&gt;에서 Gradle을 이루는 기본 개념에 대해서 알아보았다. 이번 글에서는 Gradle 프로젝트의 구조에 대해서 알아두려고 한다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt; &lt;span style=&quot;font-size: 21px;&quot;&gt;프로젝트 구조&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;gradle init 명령어를 수행하면 프로젝트는 아래와 같은 파일 구조를 가진다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;541&quot; data-origin-height=&quot;342&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bSsqFH/dJMcad2tQkn/KLVLmJ84KEinn71kRo74uk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bSsqFH/dJMcad2tQkn/KLVLmJ84KEinn71kRo74uk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bSsqFH/dJMcad2tQkn/KLVLmJ84KEinn71kRo74uk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbSsqFH%2FdJMcad2tQkn%2FKLVLmJ84KEinn71kRo74uk%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;541&quot; height=&quot;342&quot; data-origin-width=&quot;541&quot; data-origin-height=&quot;342&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;1. gradle : Wrapper 파일 등을 저장하는 Gradle 디렉터리&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;2. libs.versions.toml : 종속성 관리를 위한 Gradle 버전 카탈로그&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;3. gradlew : Gradle Wrapper 스크립트. Gradle&amp;nbsp;프로젝트는&amp;nbsp;특정&amp;nbsp;gradle&amp;nbsp;버전을&amp;nbsp;포함하고,&amp;nbsp;wrapper&amp;nbsp;형태로&amp;nbsp;형상관리를&amp;nbsp;수행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;4. settings.gradle : 루트 프로젝트와 하위 프로젝트를 정의하는 gradle 설정 파일. 프로젝트 루트에 존재하고 유일하다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;5. build.gradle : 서브 프로젝트의 gradle 빌드 스크립트. 단일 모듈 프로젝트의 경우, settings.gradle과 같은 위치에 존재한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;6. src : 소스 코드&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;Gradle Wrapper&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Gradle 프로젝트에는 Wrapper가 존재하는데, Wrapper 스크립트는 선언된 gradle 버전을 호출하고 필요한 경우 미리 다운로드한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;553&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ll08Y/dJMcaa5OGyk/NxBsSwsxfAv72k1D1fvm8k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ll08Y/dJMcaa5OGyk/NxBsSwsxfAv72k1D1fvm8k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ll08Y/dJMcaa5OGyk/NxBsSwsxfAv72k1D1fvm8k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fll08Y%2FdJMcaa5OGyk%2FNxBsSwsxfAv72k1D1fvm8k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;553&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;553&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Wrapper 스크립트는 gradlew, gradlew.bat 파일로 사용할 수 있다. 만약 프로젝트에 파일이 포함되어 있지 않다면 gradle 프로젝트가 아니거나 Wrapper가 아직 설정되지 않은 상태라고 할 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;시스템에 설치된 gradle을 사용하지 않은 이유는 여럿이지만 가장 큰 이유는 표준화라고 할 수 있다. 특정 gradle 버전을 자동으로 다운로드하여 사용하고, gradle 버전에 따라 프로젝트를 표준화하면 다양한 사용자 환경에 동일한 gradle 버전을 제공할 수 있기 때문이다. 또한 gradle을 직접 설치하지 않아도 쉽게 빌드할 수 있는 환경을 제공해주기도 한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;때문에 시스템에 설치된 gradle 배포판을 사용하는 gradle build와 gradle wrapper를 사용하는 ./gradlew build의 차이를 이해하고 있어야 한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size18&quot;&gt;구조&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;511&quot; data-origin-height=&quot;162&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bZMTNm/dJMcajhkRgY/9qkgLDcDKNwV06df31tZ51/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bZMTNm/dJMcajhkRgY/9qkgLDcDKNwV06df31tZ51/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bZMTNm/dJMcajhkRgY/9qkgLDcDKNwV06df31tZ51/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbZMTNm%2FdJMcajhkRgY%2F9qkgLDcDKNwV06df31tZ51%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;511&quot; height=&quot;162&quot; data-origin-width=&quot;511&quot; data-origin-height=&quot;162&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;1. gradle-wrapper.jar : gradle wrapper 코드가 포함된 jar 파일로, 프로젝트에 맞는 gradle 버전이 설치되어 있지 않은 경우 해당 버전을 다운로드하고 설치하는 역할을 수행한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;2. gradle-wrapper.properties : gradle wrapper의 구성 속성을 포함하는 파일이다. 배포 url, 유형 등이 들어있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;3-4. gradlew : 래퍼 역할을 하는 스크립트 또는 배치 파일&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 시작--&gt;&lt;/p&gt;
&lt;h4 style=&quot;font-size: 10px; color: #1f1f1f; border-left: #ff327f 10px solid; margin: 0px 0px 10px; letter-spacing: -1px; line-height: normal; font-stretch: normal; padding: 0px 0px 0px 7px;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-size: 21px; color: #ff327f;&quot;&gt; 참고 문서&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;color: #555555; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a style=&quot;color: #3d62ce;&quot; href=&quot;https://go-gradually.tistory.com/entry/Gradle-Gradle-%EA%B8%B0%EB%B3%B8-%EA%B5%AC%EC%A1%B0-%EC%95%8C%EC%95%84%EB%B3%B4%EA%B8%B0&quot;&gt;[Gradle]&amp;nbsp;Gradle&amp;nbsp;-&amp;nbsp;기본&amp;nbsp;구조&amp;nbsp;알아보기&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Java</category>
      <category>Gradle</category>
      <author>비번변경</author>
      <guid isPermaLink="true">https://passwd.tistory.com/1512</guid>
      <comments>https://passwd.tistory.com/entry/Gradle-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EA%B5%AC%EC%A1%B0#entry1512comment</comments>
      <pubDate>Wed, 1 Apr 2026 09:52:36 +0900</pubDate>
    </item>
    <item>
      <title>[Java] Gradle 기본 개념</title>
      <link>https://passwd.tistory.com/entry/Java-Gradle-%EA%B8%B0%EB%B3%B8-%EA%B0%9C%EB%85%90</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size23&quot;&gt;개요&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;현재 개발하는 Java 애플리케이션은 Gradle 프로젝트인데 Gradle에 대한 이해도가 부족하다 보니 어떻게 설정하는지, 어떤 개념이 있는지 헤매고 있는 중이다. 이번 글에서는 기초적인 개념 위주로 훑어보려고 한다.&lt;/p&gt;
&lt;p style=&quot;float: none; clear: none;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt; &lt;span style=&quot;font-size: 21px;&quot;&gt;Gradle&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;프로젝트 초기화 및 빌드 자동화 도구로, 설정이나 외부 라이브러리 의존 관리를 편리하게 하는 역할을 수행한다. 개발자는 설정과 의존성 관리, 컴파일 방식 정의, 테스트, 패키징, 작업 설정 등을 위해 Gradle을 사용하게 된다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt; &lt;span style=&quot;font-size: 21px;&quot;&gt;구조 및 개념&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Gradle은 5개의 핵심적인 개념을 가진다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;731&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dcqCLB/dJMb996Sa9H/XcORwkn2LNPoEvhws0eGEk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dcqCLB/dJMb996Sa9H/XcORwkn2LNPoEvhws0eGEk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dcqCLB/dJMb996Sa9H/XcORwkn2LNPoEvhws0eGEk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdcqCLB%2FdJMb996Sa9H%2FXcORwkn2LNPoEvhws0eGEk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;731&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;731&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;프로젝트&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;빌드 가능한 소프트웨어를 의미한다. 단일 프로젝트 빌드에는 루트 프로젝트라는 단일 프로젝트가 포함되며, 멀티 모듈 프로젝트 빌드에는 하나의 루트 프로젝트와 여러 개의 하위 프로젝트를 포함한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;일반적으로 IntelliJ에서 기본 옵션으로 프로젝트를 생성하면 build.grade, settings.grade이라는 파일이 루트 폴더 내에 생성된다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;빌드 스크립트&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;브로젝트 빌드에 필요한 단계를 설명한 파일. build.grade, build.gradle.kts이라는 이름의 파일로, 프로젝트에 대한 태스크, 의존성, 플러그인 및 기타 구성을 정의한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;settings.grade은 루트 프로젝트를 위한 스크립트이고, build.grade은 하위 프로젝트를 위한 스크립트에 해당한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;의존성 관리&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;프로젝트에 필요한 외부 리소스를 선언하고 해결하기 위해 자동화된 기술이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;태스크&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;코드 컴파일, 테스트 실행 과 같은 기본적인 작업 단위를 말한다. 각 프로젝트는 빌드 스크립트 또는 플러그인 내에 정의된 하나 이상의 태스크가 존재하고, 그 태스크를 따라 빌드를 수행한다. 태스크는 파일 복사, 소스 컴파일과 같은 작업 조각인 &lt;b&gt;액션&lt;/b&gt;, 액션이 사용하거나 입력하는 값인 &lt;b&gt;입력&lt;/b&gt;, 그리고 액션이 수정하느 파일인 &lt;b&gt;출력&lt;/b&gt;으로 구성한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;플러그인&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;코드 컴파일, 테스트와 같은 태스크를 gradle에서 실행할 수 있도록 gradle의 기본 기능을 확장하는 도구이다. 로직과 구성을 재사용할 수 있는 수단을 제공하여, 한 번 작성한 태스크를 여러 빌드에서 사용할 수 있게 한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;빌드&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;gradle 빌드는 gradle 프로젝트에서 태스크를 실행하는 것이다. gradle은 빌드를 구성하고 실행할 태스크를 선택하고, 요청한 태스크와 의존성을 바탕으로 가장 작은 태스크 집합을 실행한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;빌드 명령어는 다음과 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1774575385047&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;gradle build

/gradlew build 
gradlew.bat build&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 시작--&gt;&lt;/p&gt;
&lt;h4 style=&quot;font-size: 10px; color: #1f1f1f; border-left: #ff327f 10px solid; margin: 0px 0px 10px; letter-spacing: -1px; line-height: normal; font-stretch: normal; padding: 0px 0px 0px 7px;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #ff327f;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;참고 문서&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://go-gradually.tistory.com/entry/Gradle-Gradle-%EA%B8%B0%EB%B3%B8-%EA%B5%AC%EC%A1%B0-%EC%95%8C%EC%95%84%EB%B3%B4%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;[Gradle]&amp;nbsp;Gradle&amp;nbsp;-&amp;nbsp;기본&amp;nbsp;구조&amp;nbsp;알아보기&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://velog.io/@hyemin916/Gradle%EC%97%90-%EB%8C%80%ED%95%B4-%EC%95%8C%EC%95%84%EB%B3%B4%EC%9E%90-1-Gradle%EC%9D%98-%EA%B8%B0%EB%B3%B8-%EA%B0%9C%EB%85%90&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Gradle에&amp;nbsp;대해&amp;nbsp;알아보자&amp;nbsp;#1&amp;nbsp;-&amp;nbsp;Gradle의&amp;nbsp;기본&amp;nbsp;개념&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Java</category>
      <category>Gradle</category>
      <author>비번변경</author>
      <guid isPermaLink="true">https://passwd.tistory.com/1511</guid>
      <comments>https://passwd.tistory.com/entry/Java-Gradle-%EA%B8%B0%EB%B3%B8-%EA%B0%9C%EB%85%90#entry1511comment</comments>
      <pubDate>Tue, 31 Mar 2026 11:36:33 +0900</pubDate>
    </item>
    <item>
      <title>[Github] Github Action 트리거 스킵하기</title>
      <link>https://passwd.tistory.com/entry/Github-Github-Action-%ED%8A%B8%EB%A6%AC%EA%B1%B0-%EC%8A%A4%ED%82%B5%ED%95%98%EA%B8%B0</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size23&quot;&gt;개요&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Github 레포지터리의 특정 브랜치에 푸시가 발생하거나 PR이 생성되었을 때 자동으로 Github Action이 트리거 되도록 설정해 두었는데, Action 수행이 필요하지 않은 단순 수정 건에도 Action이 트리거 되는 것에 불편함을 느끼곤 했다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;적당한 방법이 없나 확인해보니 Github는 Action 트리거를 건너뛰는 방법도 제공하고 있는 것을 알게 되었다. 간단하게 기록해 둔다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt; &lt;span style=&quot;font-size: 21px;&quot;&gt;방법&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Action 트리거를 건너뛰는 방법은 생각보다 간단하다. 커밋 메시지나 PR 헤드에 아래 문자열을 포함시켜 주면 Action 트리거를 건너뛸 수 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;[skip ci]&lt;/li&gt;
&lt;li&gt;[ci &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;skip&lt;/span&gt;]&amp;nbsp;&lt;/li&gt;
&lt;li&gt;[no ci]&lt;/li&gt;
&lt;li&gt;[skip actions]&lt;/li&gt;
&lt;li&gt;[actions skip]&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1774486405196&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git commit -m &quot;Update README.md [skip ci]&quot;
git commit -m &quot;문서 오타 수정 [no ci]&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또는 커밋 메시지에 skip-checks 트레일러를 포함시켜도 된다. 커밋 메세지 마지막에 빈 줄 두 개를 넣고 작성해야 한다.&lt;/p&gt;
&lt;pre id=&quot;code_1774486453568&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;문서 수정

skip-checks: true&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 git이 줄 바꿈을 자동 정리하지 않도록 커밋 명령어에 --cleanup=verbatim 옵션을 포함시켜주어야 한다.&lt;/p&gt;
&lt;pre id=&quot;code_1774486550121&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git commit --cleanup=verbatim&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;테스트&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;예로 들어 아래와 같이 레포지터리에 push 이벤트가 발생하면 트리거 되도록 구성한 워크플로우가 있다고 하자.&lt;/p&gt;
&lt;pre id=&quot;code_1774486592816&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;name: learn-github-actions
run-name: ${{ github.actor }} is learning GitHub Actions
on: [push]
jobs:
  job1:
    runs-on: ubuntu-latest
    outputs:
      output1: ${{ steps.step1.outputs.test }}
      output2: ${{ steps.step2.outputs.test }}
    steps:
      - id: step1
        run: echo &quot;test=hello&quot; &amp;gt;&amp;gt; &quot;$GITHUB_OUTPUT&quot;
      - id: step2
        run: echo &quot;test=world&quot; &amp;gt;&amp;gt; &quot;$GITHUB_OUTPUT&quot;
  job2:
    runs-on: ubuntu-latest
    needs: job1
    steps:
      - env:
          OUTPUT1: ${{needs.job1.outputs.output1}}
          OUTPUT2: ${{needs.job1.outputs.output2}}
        run: echo &quot;$OUTPUT1 $OUTPUT2&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이 워크플로우를 구성한 레포지터리에 README.md 파일을 편집하려고 한다. 레포지터리를 설명하는 문서 편집이기 때문에 github action을 트리거할 필요는 없을 것 같다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;949&quot; data-origin-height=&quot;710&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NRQ8v/dJMcagEV7Au/CMt1thfkU03eHsAEoKl7k0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NRQ8v/dJMcagEV7Au/CMt1thfkU03eHsAEoKl7k0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NRQ8v/dJMcagEV7Au/CMt1thfkU03eHsAEoKl7k0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNRQ8v%2FdJMcagEV7Au%2FCMt1thfkU03eHsAEoKl7k0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;949&quot; height=&quot;710&quot; data-origin-width=&quot;949&quot; data-origin-height=&quot;710&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;파일을 편집하고 메시지에 [skip actions]를 포함시켰다. 그리고 Commit changes를 클릭하면 직전 커밋과는 다르게 actions이 트리거 되지 않은 모습을 확인할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;328&quot; data-origin-height=&quot;323&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bO5t09/dJMcadH8QTA/OcGRqUGbnpu8A58OqAP58K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bO5t09/dJMcadH8QTA/OcGRqUGbnpu8A58OqAP58K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bO5t09/dJMcadH8QTA/OcGRqUGbnpu8A58OqAP58K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbO5t09%2FdJMcadH8QTA%2FOcGRqUGbnpu8A58OqAP58K%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;328&quot; height=&quot;323&quot; data-origin-width=&quot;328&quot; data-origin-height=&quot;323&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 시작--&gt;&lt;/p&gt;
&lt;h4 style=&quot;font-size: 10px; color: #1f1f1f; border-left: #ff327f 10px solid; margin: 0px 0px 10px; letter-spacing: -1px; line-height: normal; font-stretch: normal; padding: 0px 0px 0px 7px;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #ff327f;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;참고 문서&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.github.com/ko/actions/how-tos/manage-workflow-runs/skip-workflow-runs&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.github.com/ko/actions/how-tos/manage-workflow-runs/skip-workflow-runs&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://shanepark.tistory.com/544&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://shanepark.tistory.com/544&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Git | GitLab</category>
      <category>github</category>
      <author>비번변경</author>
      <guid isPermaLink="true">https://passwd.tistory.com/1510</guid>
      <comments>https://passwd.tistory.com/entry/Github-Github-Action-%ED%8A%B8%EB%A6%AC%EA%B1%B0-%EC%8A%A4%ED%82%B5%ED%95%98%EA%B8%B0#entry1510comment</comments>
      <pubDate>Mon, 30 Mar 2026 11:04:12 +0900</pubDate>
    </item>
    <item>
      <title>[Java] regex - 정규표현식 사용 기본</title>
      <link>https://passwd.tistory.com/entry/Java-regex-%EC%A0%95%EA%B7%9C%ED%91%9C%ED%98%84%EC%8B%9D-%EC%82%AC%EC%9A%A9-%EA%B8%B0%EB%B3%B8</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size23&quot;&gt;개요&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://passwd.tistory.com/entry/Python-re-%EC%A0%95%EA%B7%9C-%ED%91%9C%ED%98%84%EC%8B%9D%EC%9D%84-%EC%9D%B4%EC%9A%A9%ED%95%9C-%EB%AC%B8%EC%9E%90%EC%97%B4-%EA%B2%80%EC%83%89&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;2022.08.14-[Python] re - 정규 표현식을 이용한 문자열 검색&lt;/a&gt;에서 Python에서의 정규표현식 관련 작업을 하는 방법을 살펴보았었다. Java에서도 당연히 정규표현식을 다루는 regex 패키지가 존재하는데, 이번 글에서는 regex에 대해서 조금 적어둔다.&lt;/p&gt;
&lt;p style=&quot;float: none; clear: none;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt; &lt;span style=&quot;font-size: 21px;&quot;&gt;regex&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Java에서는 java.util.regex 패키지를 통해 정규 표현식을 다룰 수 있는데, 주로 사용하는 Pattern, Matcher 클래스를 많이 사용한다.&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;Pattern&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;문자열을 정규표현식 패턴 객체로 변환시켜 주는 역할을 담당한다. 다른 클래스와 달리 공개 생성자를 제공하지 않고, compile이라는 정적 메서드를 호출해야 한다.&lt;/p&gt;
&lt;pre id=&quot;code_1774398528312&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 문자열 형태의 정규표현식 문법을 정규식 패턴으로 변환
String patternString = &quot;^[0-9]*$&quot;;
Pattern pattern = Pattern.compile(patternString); // Pattern 객체로 컴파일된 정규식은 뒤의 Matcher 클래스에서 사용된다&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Pattern 객체로 컴파일된 정규식은 Matcher 클래스에서 활용한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;또는 정규표현식 컴파일 없이 바로 matches 메서드를 사용해 검증할 수 있다. matches 메서드는 첫 매개변수에 정규표현식을, 다음 매개변수에 대상 문자열을 제공한다. 검증 문자열이 정규표현식과 일치하면 true를 그렇지 않다면 false를 반환한다.&lt;/p&gt;
&lt;pre id=&quot;code_1774400483050&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.util.regex.Pattern;

public class Main {
    public static void main(String[] args) {
        // 샘플 문자열
        String txt1 = &quot;123123&quot;;
        String txt2 = &quot;123이것은숫자입니다00&quot;;

        boolean result = Pattern.matches(&quot;^[0-9]*$&quot;, txt1); // 첫번째 매개값은 정규표현식이고 두번째 매개값은 검증 대상 문자열
        System.out.println(result); // true

        boolean result2 = Pattern.matches(&quot;^[0-9]*$&quot;, txt2);
        System.out.println(result2); // false
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1214&quot; data-origin-height=&quot;580&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bE8njH/dJMb99TinFn/9JoQa8SiRItooKTy7O3p7K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bE8njH/dJMb99TinFn/9JoQa8SiRItooKTy7O3p7K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bE8njH/dJMb99TinFn/9JoQa8SiRItooKTy7O3p7K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbE8njH%2FdJMb99TinFn%2F9JoQa8SiRItooKTy7O3p7K%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;1214&quot; height=&quot;580&quot; data-origin-width=&quot;1214&quot; data-origin-height=&quot;580&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt; &lt;span style=&quot;font-size: 21px;&quot;&gt;Matcher&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Matcher 클래스는 문자열의 패턴을 해석하여 주어진 패턴과 일치하는지 판별하고, 반환된 결괏값을 가지고 있다. Matcher 클래슨 공개 생성자 대신 Pattern.matcher 메서드를 통해 얻을 수 있다. 즉 Patterm.compile -&amp;gt; Pattern.matcher 순으로 실행하는 흐름이다. pattern.matches는 단순 일치 여부만을 확인할 수 있지만. matcher는 보다 상세한 결괏값을 얻을 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1774402381320&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Main {
    public static void main(String[] args) {
        String txt = &quot;1487안녕&quot;;
        String patternString = &quot;^[0-9]+&quot;;

        // 1) 문자열 형태의 정규표현식 문법을 정규식 패턴으로 변환
        Pattern pattern = Pattern.compile(patternString);

        // 2) 패턴 객체로 matcher 메서드를 통해 문자열을 검사하고 필터링된 결과를 매처 객체로 반환
        Matcher matcher = pattern.matcher(txt);

        // 3) 정규식 필터링된 결과를 담은 matcher에서 메소드를 통해 결과를 출력
        System.out.println(matcher.find()); // 매칭된 결과가 있는지? : true
        System.out.println(matcher.group()); // 매칭된 부분을 반환 : 1487
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;412&quot; data-origin-height=&quot;46&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/LbgW8/dJMcafsrlU2/F6vThSSjScoVNsHGimdoF0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/LbgW8/dJMcafsrlU2/F6vThSSjScoVNsHGimdoF0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/LbgW8/dJMcafsrlU2/F6vThSSjScoVNsHGimdoF0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLbgW8%2FdJMcafsrlU2%2FF6vThSSjScoVNsHGimdoF0%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;412&quot; height=&quot;46&quot; data-origin-width=&quot;412&quot; data-origin-height=&quot;46&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 시작--&gt;&lt;/p&gt;
&lt;h4 style=&quot;font-size: 10px; color: #1f1f1f; border-left: #ff327f 10px solid; margin: 0px 0px 10px; letter-spacing: -1px; line-height: normal; font-stretch: normal; padding: 0px 0px 0px 7px;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #ff327f;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;참고 문서&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://inpa.tistory.com/entry/JAVA-%E2%98%95-%EC%A0%95%EA%B7%9C%EC%8B%9DRegular-Expression-%EC%82%AC%EC%9A%A9%EB%B2%95-%EC%A0%95%EB%A6%AC&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;☕&amp;nbsp;자바&amp;nbsp;정규식(Regular&amp;nbsp;Expression)&amp;nbsp;사용법&amp;nbsp; &amp;nbsp;정리&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Java</category>
      <category>Java</category>
      <author>비번변경</author>
      <guid isPermaLink="true">https://passwd.tistory.com/1509</guid>
      <comments>https://passwd.tistory.com/entry/Java-regex-%EC%A0%95%EA%B7%9C%ED%91%9C%ED%98%84%EC%8B%9D-%EC%82%AC%EC%9A%A9-%EA%B8%B0%EB%B3%B8#entry1509comment</comments>
      <pubDate>Fri, 27 Mar 2026 11:34:36 +0900</pubDate>
    </item>
    <item>
      <title>[Java] 개선된 switch/case (Java 12)</title>
      <link>https://passwd.tistory.com/entry/Java-%EA%B0%9C%EC%84%A0%EB%90%9C-switchcase-Java-12</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size23&quot;&gt;개요&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Java를 들여다보지 않은지 어언 n년, 그간 버전이 올라가면서 switch/case 문에도 약간 변화가 있었던 모양인지 못 본 새 화살표로 case에 대한 실행 코드를 표현하고 있는 코드를 발견했다. 간략하게나마 사용법을 기재해 둔다.&lt;/p&gt;
&lt;p style=&quot;float: none; clear: none;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;switch/case&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;전통적인 switch/case 문의 구조는 다음과 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1774309368120&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;switch (변수) {
    case 값1:
        // 실행 코드       
        break;
    case 값2:
        // 실행 코드        
        break;
    default:
        // 위의 case와 일치하는 값이 없을 때 실행
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;단순한 구조지만 여러 케이스를 묶을 때 불필요한 타이핑이 많고, break 누락에 의한 버그가 발생할 가능성이 많다. break 없이 이어갈 코드는 작성 빈도가 낮고 작성하더라고 주석으로 의도한 non-break임을 명시하게 된다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Java에서는 이러한 불편함을 개선하기 위해 보다 간결한 문법을 도입했다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt; &lt;span style=&quot;font-size: 21px;&quot;&gt;간결한 switch/case&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Java 12에서부터 switch/case문은 화살표 연산자를 사용해 간결하게 표현할 수 있게 되었다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1774309922034&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;switch (변수) {
    case 값1 -&amp;gt; 실행 코드
    case 값2 -&amp;gt; 실행 코드
    default -&amp;gt; 위의 case와 일치하는 값이 없을 때 실행
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;break를 생략할 수 있고, 여러 케이스를 한 줄에 처리할 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;예로 들어, 각 달의 계절을 반환하는 switch/case문을 작성한다고 하자. 기존 코드는 다음과 같이 작성해야 했다.&lt;/p&gt;
&lt;pre id=&quot;code_1774310213340&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;switch (month) {
    case 12:
    case 1:
    case 2:
        season = &quot;winter&quot;;
        break;
    case 3:
    case 4:
    case 5:
        season = &quot;spring&quot;;
        break;
    case 6:
    case 7:
    case 8:
        season = &quot;summer&quot;;
        break;
    case 9:
    case 10:
    case 11:
        season = &quot;autumn&quot;;
        break;
    default:
        season = &quot;unknown&quot;;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;반면 화살표 연산자를 도입하여 표현하면 아래와 같이 정리된다.&lt;/p&gt;
&lt;pre id=&quot;code_1774310354406&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;switch (month) {
    case 12, 1, 2 -&amp;gt; season = &quot;winter&quot;;
    case 3, 4, 5 -&amp;gt; season = &quot;spring&quot;;
    case 6, 7, 8 -&amp;gt; season = &quot;summer&quot;;
    case 9, 10, 11 -&amp;gt; season = &quot;autumn&quot;;
    default -&amp;gt; season = &quot;unknown&quot;;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;코드가 늘어지지 않아 가독성이 개선된 모습을 볼 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 시작--&gt;&lt;/p&gt;
&lt;h4 style=&quot;font-size: 10px; color: #1f1f1f; border-left: #ff327f 10px solid; margin: 0px 0px 10px; letter-spacing: -1px; line-height: normal; font-stretch: normal; padding: 0px 0px 0px 7px;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #ff327f;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;참고 문서&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://velog.io/@letsdev/Java-%EA%B0%9C%EC%84%A0%EB%90%9C-Switch-Case&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Java&amp;nbsp;14~21에서의&amp;nbsp;Switch&amp;nbsp;Case&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://hianna.tistory.com/903&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://hianna.tistory.com/903&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Java</category>
      <category>Java</category>
      <author>비번변경</author>
      <guid isPermaLink="true">https://passwd.tistory.com/1508</guid>
      <comments>https://passwd.tistory.com/entry/Java-%EA%B0%9C%EC%84%A0%EB%90%9C-switchcase-Java-12#entry1508comment</comments>
      <pubDate>Thu, 26 Mar 2026 10:00:18 +0900</pubDate>
    </item>
    <item>
      <title>[Java] 텍스트 블록</title>
      <link>https://passwd.tistory.com/entry/Java-%ED%85%8D%EC%8A%A4%ED%8A%B8-%EB%B8%94%EB%A1%9D</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size23&quot;&gt;개요&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Java에서는 개행을 포함한 문자열을 선언할 때 + 연산자와 개행 문자를 함께 사용하는 문자열 조합을 활용해 선언을 해왔다.&lt;/p&gt;
&lt;pre id=&quot;code_1774224167127&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 문자열 조합
String html1 = &quot;&amp;lt;html&amp;gt;\n&quot; +
          &quot;    &amp;lt;body&amp;gt;\n&quot; +
          &quot;        &amp;lt;p&amp;gt;Hello, world&amp;lt;/p&amp;gt;\n&quot; +
          &quot;    &amp;lt;/body&amp;gt;\n&quot; +
          &quot;&amp;lt;/html&amp;gt;\n&quot;;&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;그러나 Java 15부터 텍스트 블록이 도입됨에 따라 보다 가독성 있는 여러 줄 문자열을 선언할 수 있게 되었다. 이번 글에서는 Java의 텍스트 블록에 대해서 적어둔다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt; &lt;span style=&quot;font-size: 21px;&quot;&gt;텍스트 블록&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;텍스트 블록은 큰따옴표 세 개(&quot;&quot;&quot;)로 열고 닫을 수 있는데, &quot;&quot;&quot; 뒤에 바로 문자열이 올 수 없다는 특징이 있다. &quot;&quot;&quot; ~ &quot;&quot;&quot; 블록 내에는 반드시 하나 이상의 개행이 포함되어 있어야 한다.&lt;/p&gt;
&lt;pre id=&quot;code_1774224430700&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;String html = &quot;&quot;&quot;
  &amp;lt;html&amp;gt;
      &amp;lt;body&amp;gt;
          &amp;lt;p&amp;gt;Hello, world&amp;lt;/p&amp;gt;
      &amp;lt;/body&amp;gt;
  &amp;lt;/html&amp;gt;
  &quot;&quot;&quot;;&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;문자열에 큰따옴표가 포함되어 있는 경우도 별도의 이스케이프 바로 사용할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1774224734786&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;String query = &quot;&quot;&quot;
        SELECT &quot;EMP_ID&quot;, &quot;LAST_NAME&quot; FROM &quot;EMPLOYEE_TB&quot;
        WHERE &quot;CITY&quot; = 'INDIANAPOLIS'
        ORDER BY &quot;EMP_ID&quot;, &quot;LAST_NAME&quot;;
        &quot;&quot;&quot;;&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;다만 \의 경우에는 개행을 무시할 때 사용할 수 있기 때문에&amp;nbsp; \ 자체를 표현하기 위해서는 이스케이프가 필요하다.&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;505&quot; data-origin-height=&quot;361&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bBF8i2/dJMcaivSgx4/UhOxW4mngiKXIefBWrCGPK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bBF8i2/dJMcaivSgx4/UhOxW4mngiKXIefBWrCGPK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bBF8i2/dJMcaivSgx4/UhOxW4mngiKXIefBWrCGPK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbBF8i2%2FdJMcaivSgx4%2FUhOxW4mngiKXIefBWrCGPK%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;505&quot; height=&quot;361&quot; data-origin-width=&quot;505&quot; data-origin-height=&quot;361&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;출력을 보면 \에 의해 개행이 무시되고 \가 출력된 것을 볼 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;들여 쓰기&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;SQL 등을 작성할 때는 들여 쓰기가 코드의 가독성을 좌우한다. Java는 들여 쓰기를 문자열에 반영하기 위해 여러 배려를 해두었는데, 닫는 &quot;&quot;&quot;가 그 기준 중 하나이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;가령 닫는 큰따옴표가 각 줄의 시작위치와 동일한 경우와 그렇지 않은 경우의 출력을 비교하면 다음과 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1774225349257&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class Main {
    public static void main(String[] args) {
        String query_1 = &quot;&quot;&quot;
                SELECT &quot;EMP_ID&quot;, &quot;LAST_NAME&quot; FROM &quot;EMPLOYEE_TB&quot;
                WHERE &quot;CITY&quot; = 'INDIANAPOLIS'
                ORDER BY &quot;EMP_ID&quot;, &quot;LAST_NAME&quot;;
                &quot;&quot;&quot;;

        String query_2 = &quot;&quot;&quot;
                SELECT &quot;EMP_ID&quot;, &quot;LAST_NAME&quot; FROM &quot;EMPLOYEE_TB&quot;
                WHERE &quot;CITY&quot; = 'INDIANAPOLIS'
                ORDER BY &quot;EMP_ID&quot;, &quot;LAST_NAME&quot;;
            &quot;&quot;&quot;;
        System.out.println(query_1);
        System.out.println(query_2);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;425&quot; data-origin-height=&quot;159&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cMyfhM/dJMcagESXxG/ABTdA68JCnnPjdDxjMMBP1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cMyfhM/dJMcagESXxG/ABTdA68JCnnPjdDxjMMBP1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cMyfhM/dJMcagESXxG/ABTdA68JCnnPjdDxjMMBP1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcMyfhM%2FdJMcagESXxG%2FABTdA68JCnnPjdDxjMMBP1%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;425&quot; height=&quot;159&quot; data-origin-width=&quot;425&quot; data-origin-height=&quot;159&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;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;format&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;텍스트 블록은 원활한 포매팅을 위해 replace, format과 같은 메서드를 지원하고 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1774226285214&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// Strnig::repalce 예제
String code_1 = &quot;&quot;&quot;
      public void print($type o) {
          System.out.println(Objects.toString(o));
      }
      &quot;&quot;&quot;.replace(&quot;$type&quot;, type);

// String::formatted 예제
String code_2 = &quot;&quot;&quot;
      public void print(%s o) {
          System.out.println(Objects.toString(o));
      }
      &quot;&quot;&quot;.formatted(type);&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;format 메서드의 경우에는 String.format과 이름이 다르니 주의할 필요가 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 시작--&gt;&lt;/p&gt;
&lt;h4 style=&quot;font-size: 10px; color: #1f1f1f; border-left: #ff327f 10px solid; margin: 0px 0px 10px; letter-spacing: -1px; line-height: normal; font-stretch: normal; padding: 0px 0px 0px 7px;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #ff327f;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;참고 문서&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.baeldung.com/java-text-blocks&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.baeldung.com/java-text-blocks&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://mostadmired.tistory.com/132&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://mostadmired.tistory.com/132&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Java</category>
      <category>Java</category>
      <author>비번변경</author>
      <guid isPermaLink="true">https://passwd.tistory.com/1507</guid>
      <comments>https://passwd.tistory.com/entry/Java-%ED%85%8D%EC%8A%A4%ED%8A%B8-%EB%B8%94%EB%A1%9D#entry1507comment</comments>
      <pubDate>Wed, 25 Mar 2026 10:17:45 +0900</pubDate>
    </item>
    <item>
      <title>[IntelliJ] Gradle 빌드하기</title>
      <link>https://passwd.tistory.com/entry/IntelliJ-Gradle-%EB%B9%8C%EB%93%9C%ED%95%98%EA%B8%B0</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size23&quot;&gt;개요&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;IntelliJ 상에서 Java 애플리케이션을 개발하고 이제 빌드를 해야 하는데, 문서상으로는 CLI로 안내가 되어있었다. 하지만 IntelliJ 내장 JDK로 개발하고 있어 Java를 설치하라는 오류가 발생하는 문제가 있었다. 확인해 보니 IntelliJ 내에서 빌드 기능을 지원하고 있는 걸로 보여 방법을 기록해 둔다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt; &lt;span style=&quot;font-size: 21px;&quot;&gt;방법&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 오른쪽 메뉴의 Gradle 버튼 클릭&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;385&quot; data-origin-height=&quot;263&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/edvH1H/dJMcaiCCSBX/QmkhNCbEAXOjlJyAj8Bzz0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/edvH1H/dJMcaiCCSBX/QmkhNCbEAXOjlJyAj8Bzz0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/edvH1H/dJMcaiCCSBX/QmkhNCbEAXOjlJyAj8Bzz0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FedvH1H%2FdJMcaiCCSBX%2FQmkhNCbEAXOjlJyAj8Bzz0%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;385&quot; height=&quot;263&quot; data-origin-width=&quot;385&quot; data-origin-height=&quot;263&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;&lt;!--부제목사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. Tasks 접근&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;382&quot; data-origin-height=&quot;352&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ctp2VN/dJMcacoTN7e/6xYYTJ4vPfEppstGEhn8HK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ctp2VN/dJMcacoTN7e/6xYYTJ4vPfEppstGEhn8HK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ctp2VN/dJMcacoTN7e/6xYYTJ4vPfEppstGEhn8HK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fctp2VN%2FdJMcacoTN7e%2F6xYYTJ4vPfEppstGEhn8HK%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;382&quot; height=&quot;352&quot; data-origin-width=&quot;382&quot; data-origin-height=&quot;352&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;&lt;b&gt;3. 실행할 태스크 더블클릭&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;381&quot; data-origin-height=&quot;559&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b6Zjme/dJMcag5UtEs/YW3piW1BPluPJ6mlBhvSq0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b6Zjme/dJMcag5UtEs/YW3piW1BPluPJ6mlBhvSq0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b6Zjme/dJMcag5UtEs/YW3piW1BPluPJ6mlBhvSq0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb6Zjme%2FdJMcag5UtEs%2FYW3piW1BPluPJ6mlBhvSq0%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;381&quot; height=&quot;559&quot; data-origin-width=&quot;381&quot; data-origin-height=&quot;559&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;빌드를 더블클릭하면 프로젝트에 build 경로가 생기면서 libs 경로 아래에 jar 파일이 생성된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;454&quot; data-origin-height=&quot;197&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cIBGDD/dJMcah4ON0Y/QTYyB1Zgq1R1OCnHGK3FN0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cIBGDD/dJMcah4ON0Y/QTYyB1Zgq1R1OCnHGK3FN0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cIBGDD/dJMcah4ON0Y/QTYyB1Zgq1R1OCnHGK3FN0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcIBGDD%2FdJMcah4ON0Y%2FQTYyB1Zgq1R1OCnHGK3FN0%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;454&quot; height=&quot;197&quot; data-origin-width=&quot;454&quot; data-origin-height=&quot;197&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 시작--&gt;&lt;/p&gt;
&lt;h4 style=&quot;font-size: 10px; color: #1f1f1f; border-left: #ff327f 10px solid; margin: 0px 0px 10px; letter-spacing: -1px; line-height: normal; font-stretch: normal; padding: 0px 0px 0px 7px;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-size: 21px; color: #ff327f;&quot;&gt; 참고 문서&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://gist.github.com/sungkwangsong/3717edde69390238e3de836e8364ccdb&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://gist.github.com/sungkwangsong/3717edde69390238e3de836e8364ccdb&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://lucas-owner.tistory.com/21&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://lucas-owner.tistory.com/21&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Java</category>
      <category>Java</category>
      <author>비번변경</author>
      <guid isPermaLink="true">https://passwd.tistory.com/1506</guid>
      <comments>https://passwd.tistory.com/entry/IntelliJ-Gradle-%EB%B9%8C%EB%93%9C%ED%95%98%EA%B8%B0#entry1506comment</comments>
      <pubDate>Tue, 24 Mar 2026 14:44:36 +0900</pubDate>
    </item>
    <item>
      <title>[Java] Record</title>
      <link>https://passwd.tistory.com/entry/Java-Record</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size23&quot;&gt;Record&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Java 14 버전에서 도입된 클래스 타입으로 변경 불가(immuatable) 데이터 객체를 만드는 기능을 제공한다. 기존 클래스와 비슷하지만 더 간결하게 데이터 객체를 만들 수 있다.&lt;/p&gt;
&lt;p style=&quot;float: none; clear: none;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt; &lt;span style=&quot;font-size: 21px;&quot;&gt;특징&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Record 클래스는 다음과 같은 특징을 가지고 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;- 간결성 : 간결한 코드를 작성하기 위해 도입되어, 정의한 필드를 기반으로 메서드가 자동 생성된다. 코드의 양을 줄임으로써 가독성을 확보한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;- 메서드 자동 생성 : 필드를 기반으로 equals, hashCode, toString, getter을 자동 생성하여 반복적인 코드 작성을 피한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;- 불변성 : 필드가 설정되면 값을 변경하지 못하여 데이터 안정성을 높인다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;- final 생략 : 필드를 불변으로 취급하기 때문에 자동으로 final 처리를 한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;- 패턴 매칭 : 패턴 매칭을 사용해 데이터 추출 및 일치 검사에 효과적이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;- 데이터 전달 : Record의 주된 목적은 불변 데이터를 전달하는 것으로 DTO(Data Transfer Object)를 표현하기에 적합한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt; &lt;span style=&quot;font-size: 21px;&quot;&gt;사용 예시&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;예로 들어 아래와 같은 User를 표현하는 DTO가 있다고 하자.&lt;/p&gt;
&lt;pre id=&quot;code_1773880017042&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// User.java
public final class User {
    private final Long id;
    private final String email;
    private final String name;

    public User(Long id, String email, String name) {
        this.id = id;
        this.email = email;
        this.name = name;
    }

    public Long getId() {
        return id;
    }

    public String getEmail() {
        return email;
    }

    public String getName() {
        return name;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof User user)) return false;
        return id.equals(user.id) &amp;amp;&amp;amp; email.equals(user.email) &amp;amp;&amp;amp; name.equals(user.name);
    }

    @Override
    public int hashCode() {
        return java.util.Objects.hash(id, email, name);
    }

    @Override
    public String toString() {
        return &quot;User{&quot; + &quot;id=&quot; + id + &quot;, email='&quot; + email + '\'' + &quot;, name='&quot; + name + '\'' + '}';
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1773880130529&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// Main.java
public class Main {
    public static void main(String[] args) {
        User user = new User(1L, &quot;passwd@tistorycom&quot;, &quot;user1&quot;);
        System.out.println(user);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;754&quot; data-origin-height=&quot;280&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EABsh/dJMcajnVBtv/TvO2baH5kMPsxTVjyy15p0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EABsh/dJMcajnVBtv/TvO2baH5kMPsxTVjyy15p0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EABsh/dJMcajnVBtv/TvO2baH5kMPsxTVjyy15p0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEABsh%2FdJMcajnVBtv%2FTvO2baH5kMPsxTVjyy15p0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;754&quot; height=&quot;280&quot; data-origin-width=&quot;754&quot; data-origin-height=&quot;280&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이 User 클래스를 record를 활용하여 작성하면 아래와 같이 작성할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1773880305061&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// User.java
public record User(
        Long id,
        String email,
        String name
) {

}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만 getter는 getVarName 형식이 아닌 변수명으로 생성된다.&lt;/p&gt;
&lt;div style=&quot;background-color: #ffffff; color: #080808;&quot;&gt;
&lt;pre class=&quot;pgsql&quot;&gt;&lt;code&gt;public class Main {
    public static void main(String[] args) {
        User user = new User(1L, &quot;passwd@tistorycom&quot;, &quot;user1&quot;);
        System.out.println(user.id());
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;690&quot; data-origin-height=&quot;279&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bt6yNV/dJMcaakiwov/XizELQMphwQlkLDnrHhx1k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bt6yNV/dJMcaakiwov/XizELQMphwQlkLDnrHhx1k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bt6yNV/dJMcaakiwov/XizELQMphwQlkLDnrHhx1k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbt6yNV%2FdJMcaakiwov%2FXizELQMphwQlkLDnrHhx1k%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;690&quot; height=&quot;279&quot; data-origin-width=&quot;690&quot; data-origin-height=&quot;279&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 시작--&gt;&lt;/p&gt;
&lt;h4 style=&quot;font-size: 10px; color: #1f1f1f; border-left: #ff327f 10px solid; margin: 0px 0px 10px; letter-spacing: -1px; line-height: normal; font-stretch: normal; padding: 0px 0px 0px 7px;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-size: 21px; color: #ff327f;&quot;&gt; 참고 문서&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://s7won.tistory.com/2&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://s7won.tistory.com/2&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://m.blog.naver.com/seek316/223341255150&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://m.blog.naver.com/seek316/223341255150&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Java</category>
      <category>Java</category>
      <author>비번변경</author>
      <guid isPermaLink="true">https://passwd.tistory.com/1505</guid>
      <comments>https://passwd.tistory.com/entry/Java-Record#entry1505comment</comments>
      <pubDate>Mon, 23 Mar 2026 10:46:55 +0900</pubDate>
    </item>
    <item>
      <title>[Python] unittest - 미설치 라이브러리 모킹</title>
      <link>https://passwd.tistory.com/entry/Python-unittest-%EB%AF%B8%EC%84%A4%EC%B9%98-%EB%9D%BC%EC%9D%B4%EB%B8%8C%EB%9F%AC%EB%A6%AC-%EB%AA%A8%ED%82%B9</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size23&quot;&gt;현상&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;unittest를 작성하다 ModuleNotFoundError: No module named 'airflow' 오류를 만났다.&lt;br /&gt;테스트하려는 모듈이 airflow를 import 하고 있었는데, 현재 개발 환경에는 Airflow가 설치되어 있지 않아 발생한 문제다. 진짜 문제는 환경적인 제약사항으로 설치할 수도 없는 상황이라는 것이었다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이런 문제를 좀 해결할 수 있는 방법이 없을까? 찾다가 적어둔다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt; &lt;span style=&quot;font-size: 21px;&quot;&gt;해결&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;`sys.modules`에&amp;nbsp;해당&amp;nbsp;모듈&amp;nbsp;이름을&amp;nbsp;키로,&amp;nbsp;`MagicMock()`을&amp;nbsp;값으로&amp;nbsp;등록해 두면&amp;nbsp;된다.&lt;/p&gt;
&lt;pre id=&quot;code_1773358919279&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import sys
from unittest.mock import MagicMock
 
AIRFLOW_MOCKS = [
    &quot;airflow&quot;,
    &quot;airflow.decorators&quot;,
    &quot;airflow.providers.postgres.hooks.postgres&quot;,
    # ... 필요한 모듈들
]
 
for mod in AIRFLOW_MOCKS:
    sys.modules[mod] = MagicMock()&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;sys.modules은 이전에 &lt;a href=&quot;https://passwd.tistory.com/entry/Python-import-%EA%B2%80%EC%83%89-%EC%88%9C%EC%84%9C&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;2022.07.23-[Python] import - 검색 순서&lt;/a&gt;에서 살폈었는데, 파이썬 인터프리터가 모듈을 찾는 캐싱 저장소이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;모듈을 찾는 순서는 다음과 같다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;1. `sys.modules`&amp;nbsp;캐시&amp;nbsp;확인 &amp;mdash; 이미 import된 적 있으면 캐시에서 꺼낸다 &lt;br /&gt;2. `sys.path`에서 파일 탐색 &amp;mdash; 설치된 패키지, 현재 디렉터리 등을 순서대로 탐색한다 &lt;br /&gt;3. 모듈 로드 및 캐시 저장 &amp;mdash; 찾은 모듈을 실행하고 `sys.modules`에 저장한다&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;모듈을 찾는 과정에서 sys.modules에 해당 키가 있으면 파일을 찾는 시도를 하지 않는다. import 하는 과정에서 sys.modules에 저장된 값이 진짜 모듈인지 검사하지도 않는다. 그리고 sys.modules 자체는 평범한 딕셔너리이기 때문에 Mock 객체도 가질 수 있다. Mock 객체는 어떤 속성 접근이나 메서드 호출도 응답하는 객체이기 때문에 가짜 모듈 역할을 능히 수행할 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;따라서 `sys.modules[&quot;airflow&quot;] = MagicMock()`을 설정해 두면:&amp;nbsp;&amp;nbsp;&lt;br /&gt;-&amp;nbsp;`import&amp;nbsp;airflow`&amp;nbsp;&amp;rarr;&amp;nbsp;`sys.modules`에서&amp;nbsp;`MagicMock`&amp;nbsp;반환&amp;nbsp;✅ &lt;br /&gt;-&amp;nbsp;`from&amp;nbsp;airflow.decorators&amp;nbsp;import&amp;nbsp;dag`&amp;nbsp;&amp;rarr;&amp;nbsp;`MagicMock().dag`&amp;nbsp;반환&amp;nbsp;✅ &lt;br /&gt;-&amp;nbsp;`hook&amp;nbsp;=&amp;nbsp;PostgresHook(...)`&amp;nbsp;&amp;rarr;&amp;nbsp;`MagicMock()(...)`&amp;nbsp;반환&amp;nbsp;✅&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이런 식의 꼼수를 부릴 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt; &lt;span style=&quot;font-size: 21px;&quot;&gt;예시 코드&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;테스트&amp;nbsp;대상&amp;nbsp;모듈&amp;nbsp;(`my_dag.py`)&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;airflow 라이브러리를 임포트하는 코드이다.&lt;/p&gt;
&lt;pre id=&quot;code_1773359394993&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from airflow.decorators import dag, task
from airflow.providers.postgres.hooks.postgres import PostgresHook
 
@dag
def my_pipeline():
    @task
    def extract():
        hook = PostgresHook(postgres_conn_id=&quot;my_conn&quot;)
        return hook.get_records(&quot;SELECT * FROM users&quot;)
 
    extract()&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;테스트&amp;nbsp;코드&amp;nbsp;(`test_my_dag.py`)&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;테스트 코드에서 &lt;span style=&quot;color: #333333; text-align: left;&quot;&gt;airflow&lt;span&gt; 임포트를 포함하는 my_dag 내 함수를 테스트한다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1773359407158&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import sys
import unittest
from unittest.mock import MagicMock
 
# 테스트 파일 최상단, import 전에 설정해야 한다
AIRFLOW_MOCKS = [
    &quot;airflow&quot;,
    &quot;airflow.decorators&quot;,
    &quot;airflow.providers.postgres.hooks.postgres&quot;,
]
for mod in AIRFLOW_MOCKS:
    sys.modules[mod] = MagicMock()
 
from my_dag import my_pipeline
 
 
class TestMyPipeline(unittest.TestCase):
    def test_pipeline_runs_without_error(self):
        result = my_pipeline()
        self.assertIsNotNone(result)
 
 
if __name__ == &quot;__main__&quot;:
    unittest.main()&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;주의&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만 라이브러리를 모킹할 때는 다음과 같은 주의사항이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 설정 순서 &lt;/b&gt;&lt;br /&gt;&amp;nbsp;`sys.modules`&amp;nbsp;패치는&amp;nbsp;반드시&amp;nbsp;해당&amp;nbsp;모듈을&amp;nbsp;import 하기&amp;nbsp;전에&amp;nbsp;이루어져야&amp;nbsp;한다.&amp;nbsp;한&amp;nbsp;번&amp;nbsp;import 된&amp;nbsp;모듈은&amp;nbsp;이미&amp;nbsp;캐시 되기&amp;nbsp;때문에,&amp;nbsp;순서가&amp;nbsp;바뀌면&amp;nbsp;소용없다.&lt;/p&gt;
&lt;pre id=&quot;code_1773359534651&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# ❌ 잘못된 순서
from my_dag import my_pipeline
sys.modules[&quot;airflow&quot;] = MagicMock()  # 너무 늦음
 
# ✅ 올바른 순서
sys.modules[&quot;airflow&quot;] = MagicMock()
from my_dag import my_pipeline&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. 서브모듈도&amp;nbsp;명시&amp;nbsp;필요&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;`sys.modules[&quot;airflow&quot;]&amp;nbsp;=&amp;nbsp;MagicMock()`만&amp;nbsp;설정해도&amp;nbsp;`import&amp;nbsp;airflow`는&amp;nbsp;되지만,&amp;nbsp;`from&amp;nbsp;airflow.decorators&amp;nbsp;import&amp;nbsp;dag`처럼&amp;nbsp;서브모듈을&amp;nbsp;직접&amp;nbsp;import 하는&amp;nbsp;경우엔&amp;nbsp;해당&amp;nbsp;경로도&amp;nbsp;별도로&amp;nbsp;등록해야&amp;nbsp;한다.&lt;/p&gt;
&lt;pre id=&quot;code_1773359555406&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sys.modules[&quot;airflow&quot;] = MagicMock()
sys.modules[&quot;airflow.decorators&quot;] = MagicMock()  # 별도 등록 필요&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. 전역 상태 오염&lt;/b&gt;&lt;br /&gt;`sys.modules`는 프로세스 전체에서 공유되는 전역 상태다. 파일 최상단에서 한 번 설정하면 같은 프로세스에서 실행되는 모든 테스트에 영향을 준다.&lt;br /&gt;테스트 A에서 `airflow`를 MagicMock으로 등록해두면, 이후 실행되는 테스트 B에서도 실제 airflow 대신 MagicMock이 반환된다. 테스트 실행 순서에 따라 결과가 달라지는 비결정적 테스트가 될 수 있고, 테스트 간 격리가 깨진다.&lt;br /&gt;또한 `my_dag` 모듈 자체도 `sys.modules`에 캐시되기 때문에, 다른 테스트에서 다시 import해도 mock이 적용된 버전이 재사용된다.&lt;br /&gt;더&amp;nbsp;안전한&amp;nbsp;방법으로는&amp;nbsp;`patch.dict(sys.modules,&amp;nbsp;{...})`를&amp;nbsp;데코레이터나&amp;nbsp;컨텍스트&amp;nbsp;매니저로&amp;nbsp;사용하거나,&amp;nbsp;`setUp`&amp;nbsp;/&amp;nbsp;`tearDown`에서&amp;nbsp;패치/복구하는&amp;nbsp;방식이&amp;nbsp;있다.&amp;nbsp;이&amp;nbsp;내용은&amp;nbsp;별도&amp;nbsp;포스트에서&amp;nbsp;다룰&amp;nbsp;예정이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;정리&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;`sys.modules`는&amp;nbsp;Python&amp;nbsp;import&amp;nbsp;시스템의&amp;nbsp;캐시다.&amp;nbsp;이&amp;nbsp;딕셔너리를&amp;nbsp;직접&amp;nbsp;조작하면&amp;nbsp;파일시스템&amp;nbsp;탐색&amp;nbsp;없이&amp;nbsp;원하는&amp;nbsp;객체를&amp;nbsp;모듈로&amp;nbsp;반환시킬&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp;`MagicMock`은&amp;nbsp;어떤&amp;nbsp;속성/메서드&amp;nbsp;접근에도&amp;nbsp;응답하기&amp;nbsp;때문에&amp;nbsp;가짜&amp;nbsp;모듈&amp;nbsp;역할로&amp;nbsp;적합하다.&lt;/p&gt;
&lt;pre id=&quot;code_1773359725269&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import airflow 실행 시:
    &amp;darr;
sys.modules에 &quot;airflow&quot; 키가 있는가?
    &amp;darr; Yes                  &amp;darr; No
그 값을 반환           파일시스템에서 탐색
(MagicMock 반환)       (없으면 ModuleNotFoundError)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만 라이브러리 모킹은 &quot;설치할 수 없는 라이브러리의 존재를 속이는&quot; 것이다. 때문에 테스트하려는 대상은 Airflow 자체가 아니라 Airflow를 사용하는 내 코드의 로직일 때 사용할 수 있다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 76px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 21px;&quot;&gt;테스트&amp;nbsp;목적&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 21px;&quot;&gt;적합 여부&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 21px;&quot;&gt;내&amp;nbsp;비즈니스&amp;nbsp;로직이&amp;nbsp;올바르게&amp;nbsp;동작하는가&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 21px;&quot;&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 17px;&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;Airflow의 실제 기능이 올바르게 동작하는가&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 17px;&quot;&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 17px;&quot;&gt;DB 쿼리 결과를 검증하고 싶다&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 17px;&quot;&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 시작--&gt;&lt;/p&gt;
&lt;h4 style=&quot;font-size: 10px; color: #1f1f1f; border-left: #ff327f 10px solid; margin: 0px 0px 10px; letter-spacing: -1px; line-height: normal; font-stretch: normal; padding: 0px 0px 0px 7px;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-size: 21px; color: #ff327f;&quot;&gt; 참고 문서&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://stackoverflow.com/questions/63421480/how-to-mock-using-sys-modules-and-with-mock-patch-python-interference-on-static&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://stackoverflow.com/questions/63421480/how-to-mock-using-sys-modules-and-with-mock-patch-python-interference-on-static&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Python</category>
      <category>python</category>
      <author>비번변경</author>
      <guid isPermaLink="true">https://passwd.tistory.com/1501</guid>
      <comments>https://passwd.tistory.com/entry/Python-unittest-%EB%AF%B8%EC%84%A4%EC%B9%98-%EB%9D%BC%EC%9D%B4%EB%B8%8C%EB%9F%AC%EB%A6%AC-%EB%AA%A8%ED%82%B9#entry1501comment</comments>
      <pubDate>Fri, 20 Mar 2026 09:57:10 +0900</pubDate>
    </item>
    <item>
      <title>[Python] unittest.patch - 함수 내부 의존성 대체</title>
      <link>https://passwd.tistory.com/entry/Python-unittestpatch-%ED%95%A8%EC%88%98-%EB%82%B4%EB%B6%80-%EC%9D%98%EC%A1%B4%EC%84%B1-%EB%8C%80%EC%B2%B4</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;!--헤드라인시작--&gt;&lt;/h3&gt;
&lt;h3 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size23&quot;&gt;개요&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a style=&quot;color: #0070d1; text-align: start;&quot; href=&quot;https://passwd.tistory.com/entry/Python-unittestmock-%EC%9D%98%EC%A1%B4%EC%84%B1-%EB%8C%80%EC%B2%B4&quot;&gt;2026.03.16-[Python] unittest.mock - 의존성 대체&lt;/a&gt;를 통해 unittest의 Mock에 대해서 알아보았다. Mock은 어떤 객체를 가짜 객체로 대체함으로써 테스트 수행 시의 외부 시스템 의존성을 낮출 수 있다. 단, 의존성을 인자로 직접 주입받는 함수에 한해서다.&lt;/p&gt;
&lt;pre id=&quot;code_1773799025614&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def get_users(db):
    return db.query(&quot;SELECT * FROM users&quot;)

def test_get_users():
    mock_db = Mock()
    mock_db.query.return_value = [{&quot;id&quot;: 1}]
    assert get_users(mock_db) == [{&quot;id&quot;: 1}]&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;float: none; clear: none;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;함수 내부에서 외부 시스템을 직접 참조하는 경우, 인자로 Mock을 주입할 수 없기 때문에 위 방식으로는 테스트할 수 없다. 이런 경우에&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;patch를 사용한다.&lt;/p&gt;
&lt;p style=&quot;float: none; clear: none;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;!--헤드라인 끝--&gt;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;!--부제목사용 시작--&gt;&lt;/h3&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;patch&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;patch&lt;/code&gt;는 테스트 실행 중 특정 이름에 바인딩된 객체를 Mock으로 교체해주는 역할을 한다. 예를 들어 테스트 대상 함수가 &lt;code&gt;requests&lt;/code&gt; 라이브러리를 임포트하여 내부에서 &lt;code&gt;get&lt;/code&gt;을 호출한다면, &lt;code&gt;patch&lt;/code&gt;는 &lt;code&gt;requests.get&lt;/code&gt;을 Mock 객체로 바꿔치기한다.&lt;/p&gt;
&lt;pre class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;# mymodule.py
import requests  # mymodule.requests &amp;rarr; requests 객체
```

`patch(&quot;mymodule.requests.get&quot;)`은 이 바인딩을 임시로 바꾼다.
```
평소:   mymodule.requests.get &amp;rarr; 진짜 HTTP 함수
patch:  mymodule.requests.get &amp;rarr; MagicMock()&lt;/code&gt;&lt;/pre&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;pre class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;# 데코레이터
@patch('mymodule.requests.get')
def test_fetch(self, mock_get):
    ...

# 컨텍스트 매니저
def test_fetch(self):
    with patch('mymodule.requests.get') as mock_get:
        ...&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;경로&amp;nbsp;지정&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;patch&lt;/code&gt;를 사용할 때는 경로 지정에 유의해야 한다. 흔한 실수 중 하나가 원본 객체의 경로를 지정하는 것이다. &lt;code&gt;patch&lt;/code&gt;는 모듈의 네임스페이스에서 이름 바인딩을 교체하는 방식으로 동작하기 때문에, &lt;code&gt;import&lt;/code&gt;된 시점을 기준으로 &lt;b&gt;사용되는 쪽의 경로&lt;/b&gt;를 지정해야 한다.&lt;/p&gt;
&lt;pre class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;# 잘못된 경로
@patch('requests.get')         # 원본 경로 &amp;rarr; 효과 없음

# 올바른 경로
@patch('mymodule.requests.get')  # 사용되는 쪽의 경로&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;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;사용 예시&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전달받은 URL에 GET 요청을 보낸 후 그 응답을 JSON 형태로 반환하는 함수 &lt;code&gt;fetch&lt;/code&gt;가 정의된 &lt;code&gt;mymodule&lt;/code&gt;이 있다고 하자.&lt;/p&gt;
&lt;pre class=&quot;python&quot;&gt;&lt;code&gt;# mymodule.py
import requests

def fetch(url):
    return requests.get(url).json()&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 함수를 그대로 테스트하면 실제 외부 서버에 요청이 나간다.&lt;/p&gt;
&lt;pre class=&quot;python&quot;&gt;&lt;code&gt;import mymodule

class MyTests(TestCase):
    def test_fetch(self):
        result = mymodule.fetch('http://example.com')
        self.assertDictEqual(result, {&quot;ok&quot;: True})&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;patch&lt;/code&gt;를 사용해 &lt;code&gt;requests.get&lt;/code&gt;을 Mock으로 교체한다. 대상 경로는 원본인 &lt;code&gt;requests.get&lt;/code&gt;이 아니라 &lt;code&gt;mymodule.requests.get&lt;/code&gt;으로 지정하고, patch된 Mock 객체를 주입받을 매개변수를 테스트 함수에 추가한다.&lt;/p&gt;
&lt;pre class=&quot;ruby&quot;&gt;&lt;code&gt;class MyTests(TestCase):
    @patch('mymodule.requests.get')
    def test_fetch(self, mock_req_get):
        # requests.get(url)의 반환값에서 .json()을 호출하는 구조이므로
        # return_value를 두 단계로 체이닝해서 지정한다
        mock_req_get.return_value.json.return_value = {&quot;ok&quot;: True}
        result = mymodule.fetch('http://example.com')
        self.assertDictEqual(result, {&quot;ok&quot;: True})&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;mock_req_get.return_value&lt;/code&gt;는 &lt;code&gt;requests.get(url)&lt;/code&gt;의 반환값에 해당하는 Mock이고, &lt;code&gt;.json.return_value&lt;/code&gt;는 그 반환값에서 &lt;code&gt;.json()&lt;/code&gt;을 호출했을 때의 결과다. &lt;code&gt;fetch&lt;/code&gt; 내부의 &lt;code&gt;requests.get(url).json()&lt;/code&gt; 호출 구조를 그대로 따라가면 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1282&quot; data-origin-height=&quot;710&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/brIBJu/dJMcagY45QL/HsJQ2851rfR2TmfBzM3Vb1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/brIBJu/dJMcagY45QL/HsJQ2851rfR2TmfBzM3Vb1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/brIBJu/dJMcagY45QL/HsJQ2851rfR2TmfBzM3Vb1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbrIBJu%2FdJMcagY45QL%2FHsJQ2851rfR2TmfBzM3Vb1%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;1282&quot; height=&quot;710&quot; data-origin-width=&quot;1282&quot; data-origin-height=&quot;710&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;font-size: 10px; color: #1f1f1f; border-left: #ff327f 10px solid; margin: 0px 0px 10px; letter-spacing: -1px; line-height: normal; font-stretch: normal; padding: 0px 0px 0px 7px;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-size: 21px; color: #ff327f;&quot;&gt;참고 문서&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://daleseo.com/python-unittest-mock-patch/&quot;&gt;https://daleseo.com/python-unittest-mock-patch/&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://upright-wing.tistory.com/16&quot;&gt;https://upright-wing.tistory.com/16&lt;/a&gt;&lt;/p&gt;</description>
      <category>Python</category>
      <category>python</category>
      <author>비번변경</author>
      <guid isPermaLink="true">https://passwd.tistory.com/1504</guid>
      <comments>https://passwd.tistory.com/entry/Python-unittestpatch-%ED%95%A8%EC%88%98-%EB%82%B4%EB%B6%80-%EC%9D%98%EC%A1%B4%EC%84%B1-%EB%8C%80%EC%B2%B4#entry1504comment</comments>
      <pubDate>Thu, 19 Mar 2026 10:48:01 +0900</pubDate>
    </item>
    <item>
      <title>[Python] unittest - MagicMock</title>
      <link>https://passwd.tistory.com/entry/Python-unittest-MagicMock</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size23&quot;&gt;개요&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://passwd.tistory.com/entry/Python-unittestmock-%EC%9D%98%EC%A1%B4%EC%84%B1-%EB%8C%80%EC%B2%B4&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;2026.03.16-[Python] unittest.mock - 의존성 대체&lt;/a&gt;에서 mock 객체와 객체가 어떻게 사용되었는지 검증하는 방법에 대해 알아보았다. 다만 실제 사례에서는 일반 Mock이 아니라 MagicMock이라는 객체를 더 많이 사용하는 걸로 보이는데, 어떤 차이가 있는지 알아본다.&lt;/p&gt;
&lt;p style=&quot;float: none; clear: none;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt; &lt;span style=&quot;font-size: 21px;&quot;&gt;Mock&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Python의 모든 객체는 특수한 목적으로 쓰이는 매직 메서드를 갖는다. 가령 __str__의 경우 객체를 문자열로 출력하기 위해 사용되는데, Mock은 매직 메서드가 자동으로 모킹 되지 않는다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1773707281009&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from unittest.mock import Mock, MagicMock, call


if __name__ == '__main__':
    mock = Mock()
    print(mock.__str__.return_value)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;731&quot; data-origin-height=&quot;137&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mPRde/dJMcacPUXzh/81dJKJwUSeE9lliLONyd90/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mPRde/dJMcacPUXzh/81dJKJwUSeE9lliLONyd90/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mPRde/dJMcacPUXzh/81dJKJwUSeE9lliLONyd90/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmPRde%2FdJMcacPUXzh%2F81dJKJwUSeE9lliLONyd90%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;731&quot; height=&quot;137&quot; data-origin-width=&quot;731&quot; data-origin-height=&quot;137&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;따라서 Mock 객체의 매직 메서드를 모킹하려면 새로운 Mock 객체를 생성해서 할당해주어야 하는 불편함이 있다.&lt;/p&gt;
&lt;div style=&quot;background-color: #ffffff; color: #080808;&quot;&gt;
&lt;pre class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;from unittest.mock import Mock, MagicMock, call


if __name__ == '__main__':
    mock = Mock()
    mock.__str__ = Mock(return_value='mock')
    print(mock.__str__.return_value)&lt;/code&gt;&lt;/pre&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;734&quot; data-origin-height=&quot;280&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wsAk6/dJMcac3qdCc/zhm4xa1jIk9sJRAPsV5131/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wsAk6/dJMcac3qdCc/zhm4xa1jIk9sJRAPsV5131/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wsAk6/dJMcac3qdCc/zhm4xa1jIk9sJRAPsV5131/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwsAk6%2FdJMcac3qdCc%2Fzhm4xa1jIk9sJRAPsV5131%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;734&quot; height=&quot;280&quot; data-origin-width=&quot;734&quot; data-origin-height=&quot;280&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이러한 불편함을 해소한 것이 바로 MagicMock이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt; &lt;span style=&quot;font-size: 21px;&quot;&gt;MagicMock&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;MagicMock은 매직 메서드를 모킹해놓은 Mock 클래스의 확장 버전이라고 할 수 있다. Mock 클래스와 달리 매직 메서드를 별도로 모킹 하지 않아도 사용에 문제가 없다.&lt;/p&gt;
&lt;pre id=&quot;code_1773707839264&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from unittest.mock import Mock, MagicMock, call


if __name__ == '__main__':
    mock = MagicMock()
    print(mock.__str__.return_value)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;762&quot; data-origin-height=&quot;261&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bVSwuo/dJMcabjccW8/8riZxW1MhtebYg52HL3uf0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bVSwuo/dJMcabjccW8/8riZxW1MhtebYg52HL3uf0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bVSwuo/dJMcabjccW8/8riZxW1MhtebYg52HL3uf0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbVSwuo%2FdJMcabjccW8%2F8riZxW1MhtebYg52HL3uf0%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;762&quot; height=&quot;261&quot; data-origin-width=&quot;762&quot; data-origin-height=&quot;261&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 시작--&gt;&lt;/p&gt;
&lt;h4 style=&quot;font-size: 10px; color: #1f1f1f; border-left: #ff327f 10px solid; margin: 0px 0px 10px; letter-spacing: -1px; line-height: normal; font-stretch: normal; padding: 0px 0px 0px 7px;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #ff327f;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;참고 문서&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://daleseo.com/python-unittest-mock/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://daleseo.com/python-unittest-mock/&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Python</category>
      <category>python</category>
      <author>비번변경</author>
      <guid isPermaLink="true">https://passwd.tistory.com/1503</guid>
      <comments>https://passwd.tistory.com/entry/Python-unittest-MagicMock#entry1503comment</comments>
      <pubDate>Wed, 18 Mar 2026 10:39:50 +0900</pubDate>
    </item>
    <item>
      <title>[Python] unittest.mock - 의존성 대체</title>
      <link>https://passwd.tistory.com/entry/Python-unittestmock-%EC%9D%98%EC%A1%B4%EC%84%B1-%EB%8C%80%EC%B2%B4</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size23&quot;&gt;Mock&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;테스트를 작성하다 보면 필연적으로 외부 서비스를 의존하는 코드를 테스트하게 된다. 그러나 테스트 환경에서는 제약사항으로 인해 실제 데이터베이스나 외부 서비스에 연동하는 것이 어려운 경우가 많다. 때문에 단위 테스트를 작성할 때는 외부에 의존하는 부분을 임의로 가짜로 대체하는 기법이 자주 사용되는데 이를 모킹(mocking)이라고 한다.&lt;/p&gt;
&lt;p style=&quot;float: none; clear: none;&quot; data-ke-size=&quot;size16&quot;&gt;이번 글에서는 python unittest를 사용할 때 모킹하는 방법에 대해서 적어둔다.&lt;/p&gt;
&lt;p style=&quot;float: none; clear: none;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;unittest.mock&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;unittest.mock은 코드의 특정 부분을 mock 객체로 대체하는 기능을 제공하며, mock 객체가 어떻게 사용되었는지 검증하는데 도움을 준다. unittest가 파이썬 내장 라이브러리인 것과 동일하게 unittest.mock도 내장 라이브러리이기 때문에 별도 설치 없이 임포트 하여 사용할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1773620692945&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from unittest.mock import Mock, MagicMock, call&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt; &lt;span style=&quot;font-size: 21px;&quot;&gt;Mock 객체 설정&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;mock 객체를 생성할 때는 어떻게 작동할지 지정할 수 있고, mock 객체는 자신을 상대로 어떤 작업이 발생했는지 기억한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- 반환값 지정&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;호출될 때 특정 값을 반환하도록 설정할 때는 return_value에 값을 전달하여 생성한다.&lt;/p&gt;
&lt;pre id=&quot;code_1773621663718&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from unittest.mock import Mock, MagicMock, call

if __name__ == '__main__':
    mock = Mock(return_value=&quot;hello&quot;)
    print(mock())&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;782&quot; data-origin-height=&quot;195&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cxSr2U/dJMcafsju6E/DkP2Ehxnjnb24BW4yiBQQ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cxSr2U/dJMcafsju6E/DkP2Ehxnjnb24BW4yiBQQ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cxSr2U/dJMcafsju6E/DkP2Ehxnjnb24BW4yiBQQ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcxSr2U%2FdJMcafsju6E%2FDkP2Ehxnjnb24BW4yiBQQ0%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;782&quot; height=&quot;195&quot; data-origin-width=&quot;782&quot; data-origin-height=&quot;195&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- 예외 발생&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;예외를 발생시킬 때는 side_effect에 예외를 전달한다.&lt;/p&gt;
&lt;pre id=&quot;code_1773621638106&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from unittest.mock import Mock, MagicMock, call


if __name__ == '__main__':
    mock = Mock(side_effect=Exception(&quot;test&quot;))
    print(mock())&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1030&quot; data-origin-height=&quot;455&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/t1B2F/dJMcaaEzCQR/vyNvZ6cfkbNeKLVs5aqHuk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/t1B2F/dJMcaaEzCQR/vyNvZ6cfkbNeKLVs5aqHuk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/t1B2F/dJMcaaEzCQR/vyNvZ6cfkbNeKLVs5aqHuk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Ft1B2F%2FdJMcaaEzCQR%2FvyNvZ6cfkbNeKLVs5aqHuk%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;1030&quot; height=&quot;455&quot; data-origin-width=&quot;1030&quot; data-origin-height=&quot;455&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- 다 회 호출 설정&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;side_effect에는 예외 뿐만 아니라 함수가 여러 번 호출됐을 때의 반환값을 각각 지정할 수도 있다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1773622028588&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from unittest.mock import Mock, MagicMock, call


if __name__ == '__main__':
    mock = Mock(side_effect=[1, 2, 3])
    print(mock())
    print(mock())
    print(mock())&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;773&quot; data-origin-height=&quot;395&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c5yF5x/dJMcahwVngk/tH5D6QQMg2f8mykQRMjmD0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c5yF5x/dJMcahwVngk/tH5D6QQMg2f8mykQRMjmD0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c5yF5x/dJMcahwVngk/tH5D6QQMg2f8mykQRMjmD0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc5yF5x%2FdJMcahwVngk%2FtH5D6QQMg2f8mykQRMjmD0%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;773&quot; height=&quot;395&quot; data-origin-width=&quot;773&quot; data-origin-height=&quot;395&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- 인자 설정&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;side_effect에 함수를 넘기면 mock 객체를 호출할 때 매개변수에 따라 다른 값을 반환할 수도 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1773622198622&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from unittest.mock import Mock, MagicMock, call


if __name__ == '__main__':
    mock = Mock(side_effect=lambda x: x * 10)
    print(mock(2))&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;782&quot; data-origin-height=&quot;270&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/m75zw/dJMcafePqpU/lmQ26yaJizPluS84elXkpk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/m75zw/dJMcafePqpU/lmQ26yaJizPluS84elXkpk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/m75zw/dJMcafePqpU/lmQ26yaJizPluS84elXkpk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fm75zw%2FdJMcafePqpU%2FlmQ26yaJizPluS84elXkpk%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;782&quot; height=&quot;270&quot; data-origin-width=&quot;782&quot; data-origin-height=&quot;270&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- 속성&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;mock 객체는 속성을 가질 수도 있는데, 이 속성도 mock 객체에 해당한다. 따라서 특정 속성에 값을 할당할 수도 있고, 반환값을 지정할 수도 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1773622332043&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from unittest.mock import Mock, MagicMock, call


if __name__ == '__main__':
    mock = Mock()
    mock.attribute = 'ATTRIBUTE'
    mock.method.return_value = 'METHOD RETURN VALUE'

    print(mock.attribute)
    print(mock.method())&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;726&quot; data-origin-height=&quot;368&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bUsnZK/dJMcaiJjlCC/uR3x9usyO6OW4zP1MCWMpk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bUsnZK/dJMcaiJjlCC/uR3x9usyO6OW4zP1MCWMpk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bUsnZK/dJMcaiJjlCC/uR3x9usyO6OW4zP1MCWMpk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbUsnZK%2FdJMcaiJjlCC%2FuR3x9usyO6OW4zP1MCWMpk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;726&quot; height=&quot;368&quot; data-origin-width=&quot;726&quot; data-origin-height=&quot;368&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;mock 객체의 return_value나 side_effect는 생성 이후에도 추가할 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;Mock 객체 검증&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;mock 객체는 작업을 검증할 수 있도록 도와주는 다양한 메서드를 제공한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그중 호출 여부를 검증하는 assert_callecd는 가장 일반적으로 사용되는 메서드로, mock 객체를 한 번도 호출하지 않으면 예외가 발생한다.&lt;/p&gt;
&lt;pre id=&quot;code_1773622778919&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from unittest.mock import Mock, MagicMock, call


if __name__ == '__main__':
    mock = Mock()
    mock.assert_called()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;982&quot; data-origin-height=&quot;386&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cwR6h1/dJMcahDEDb3/FHR2XG0CITYlgcHeChmrpK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cwR6h1/dJMcahDEDb3/FHR2XG0CITYlgcHeChmrpK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cwR6h1/dJMcahDEDb3/FHR2XG0CITYlgcHeChmrpK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcwR6h1%2FdJMcahDEDb3%2FFHR2XG0CITYlgcHeChmrpK%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;982&quot; height=&quot;386&quot; data-origin-width=&quot;982&quot; data-origin-height=&quot;386&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;비슷한 메서드 중 assert_called_once는 mock 객체가 한 번 호출되었는지 검증하고, assert_called_with는 호출될 때 어떤 인자가 넘어왔는지 검증한다.&lt;/p&gt;
&lt;div style=&quot;background-color: #ffffff; color: #080808;&quot;&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;from unittest.mock import Mock, MagicMock, call


if __name__ == '__main__':
    mock = Mock()
    mock(1, 2, c=3)
    mock.assert_called_once()
    mock.assert_called_with(1, 2, c=3)
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;call_count나 call_args 등의 속성은 mock 객체가 몇 번 호출되었는지, 어떤 인자로 호출되었는지를 기억한다.&lt;/p&gt;
&lt;pre id=&quot;code_1773623028039&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from unittest.mock import Mock, MagicMock, call


if __name__ == '__main__':
    mock = Mock()
    mock(1, 2, c=3)
    print(mock.call_count)
    print(mock.call_args)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;766&quot; data-origin-height=&quot;357&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Zz7wo/dJMcag5QzFG/qEEzaUDXG8KFQ7OOn5HWFK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Zz7wo/dJMcag5QzFG/qEEzaUDXG8KFQ7OOn5HWFK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Zz7wo/dJMcag5QzFG/qEEzaUDXG8KFQ7OOn5HWFK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZz7wo%2FdJMcag5QzFG%2FqEEzaUDXG8KFQ7OOn5HWFK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;766&quot; height=&quot;357&quot; data-origin-width=&quot;766&quot; data-origin-height=&quot;357&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;&lt;!--부제목사용1 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 시작--&gt;&lt;/p&gt;
&lt;h4 style=&quot;font-size: 10px; color: #1f1f1f; border-left: #ff327f 10px solid; margin: 0px 0px 10px; letter-spacing: -1px; line-height: normal; font-stretch: normal; padding: 0px 0px 0px 7px;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #ff327f;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;참고 문서&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://daleseo.com/python-unittest-mock/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://daleseo.com/python-unittest-mock/&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.python.org/ko/3/library/unittest.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.python.org/ko/3/library/unittest.html&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Python</category>
      <category>python</category>
      <author>비번변경</author>
      <guid isPermaLink="true">https://passwd.tistory.com/1502</guid>
      <comments>https://passwd.tistory.com/entry/Python-unittestmock-%EC%9D%98%EC%A1%B4%EC%84%B1-%EB%8C%80%EC%B2%B4#entry1502comment</comments>
      <pubDate>Tue, 17 Mar 2026 11:06:22 +0900</pubDate>
    </item>
    <item>
      <title>[Python] unittest - 예외 발생 확인</title>
      <link>https://passwd.tistory.com/entry/Python-unittest-%EC%98%88%EC%99%B8-%EB%B0%9C%EC%83%9D-%ED%99%95%EC%9D%B8</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size23&quot;&gt;개요&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://passwd.tistory.com/entry/Python-unittest-%EB%8B%A8%EC%9C%84-%ED%85%8C%EC%8A%A4%ED%8A%B8&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;2026.03.10-[Python] unittest - 단위 테스트&lt;/a&gt;에서 unittest의 기본적인 사용법에 대해 알아보았다. 그런데 테스트 케이스를 작성하다 보면 로직이 정상적으로 동작하는 경우가 아니라 예외가 발생해야 하는 상황에서 예상한 예외가 발생하는지도 확인할 필요가 있다. 이번 글에서는 예외 발생 여부를 확인하는 방법을 적어둔다.&lt;/p&gt;
&lt;p style=&quot;float: none; clear: none;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;assertRaises&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;예외가 발생하는지 테스트를 해야 할 때는 assertRaises를 컨텍스트 매니저(with 문)과 함께 사용한다.&lt;/p&gt;
&lt;pre id=&quot;code_1773188740588&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;with self.assertRaises(Exception):
	LOGIC_CODE&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;assertRaises는 전달받은 예외가 발생하면 테스트를 통과하고, 다른 예외가 발생하면 오류에 해당한다. 아무 예외도 발생하지 않으면 실패인 걸로 판단한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;예시 코드&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간단하게 숫자를 0으로 나눴을 때 ZeroDivisionError가 발생하는지 확인해 보자.&lt;/p&gt;
&lt;pre id=&quot;code_1773189554462&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import unittest
from unittest import TestCase

class MyTests(TestCase):
    def test_execpt(self):
        with self.assertRaises(ZeroDivisionError):
            1 / 0&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;579&quot; data-origin-height=&quot;321&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/GfKeB/dJMb99S6OWD/MgHyYIKz8qMNOZeCqxRyh1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/GfKeB/dJMb99S6OWD/MgHyYIKz8qMNOZeCqxRyh1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/GfKeB/dJMb99S6OWD/MgHyYIKz8qMNOZeCqxRyh1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGfKeB%2FdJMb99S6OWD%2FMgHyYIKz8qMNOZeCqxRyh1%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;579&quot; height=&quot;321&quot; data-origin-width=&quot;579&quot; data-origin-height=&quot;321&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;지정한 에러가 발생하여 테스트가 통과한 것을 알 수 있다. 그리고 아예 Exception으로 지정하면 당연히 통과한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;593&quot; data-origin-height=&quot;341&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NHobk/dJMcaiJfEjA/Oa4sKek91mxK1ZKoJfNQ2k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NHobk/dJMcaiJfEjA/Oa4sKek91mxK1ZKoJfNQ2k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NHobk/dJMcaiJfEjA/Oa4sKek91mxK1ZKoJfNQ2k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNHobk%2FdJMcaiJfEjA%2FOa4sKek91mxK1ZKoJfNQ2k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;593&quot; height=&quot;341&quot; data-origin-width=&quot;593&quot; data-origin-height=&quot;341&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TypeError를 지정하면 오류가 난다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;755&quot; data-origin-height=&quot;471&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dacolr/dJMcajg5c1V/d18gcOVSWX5ZXmcjPkdQPK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dacolr/dJMcajg5c1V/d18gcOVSWX5ZXmcjPkdQPK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dacolr/dJMcajg5c1V/d18gcOVSWX5ZXmcjPkdQPK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdacolr%2FdJMcajg5c1V%2Fd18gcOVSWX5ZXmcjPkdQPK%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;755&quot; height=&quot;471&quot; data-origin-width=&quot;755&quot; data-origin-height=&quot;471&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;에러를 일으키지 않으면 아래와 같은 결과가 발생한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;725&quot; data-origin-height=&quot;433&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bXnsph/dJMcaiWMS9p/rPz7Aj0FEKtS7xWmjIM5B0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bXnsph/dJMcaiWMS9p/rPz7Aj0FEKtS7xWmjIM5B0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bXnsph/dJMcaiWMS9p/rPz7Aj0FEKtS7xWmjIM5B0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbXnsph%2FdJMcaiWMS9p%2FrPz7Aj0FEKtS7xWmjIM5B0%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;725&quot; height=&quot;433&quot; data-origin-width=&quot;725&quot; data-origin-height=&quot;433&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 시작--&gt;&lt;/p&gt;
&lt;h4 style=&quot;font-size: 10px; color: #1f1f1f; border-left: #ff327f 10px solid; margin: 0px 0px 10px; letter-spacing: -1px; line-height: normal; font-stretch: normal; padding: 0px 0px 0px 7px;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-size: 21px; color: #ff327f;&quot;&gt; 참고 문서&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.python.org/ko/3.14/library/unittest.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.python.org/ko/3.14/library/unittest.html&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://daleseo.com/python-unittest-testcase/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://daleseo.com/python-unittest-testcase/&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Python</category>
      <category>python</category>
      <author>비번변경</author>
      <guid isPermaLink="true">https://passwd.tistory.com/1500</guid>
      <comments>https://passwd.tistory.com/entry/Python-unittest-%EC%98%88%EC%99%B8-%EB%B0%9C%EC%83%9D-%ED%99%95%EC%9D%B8#entry1500comment</comments>
      <pubDate>Mon, 16 Mar 2026 10:28:29 +0900</pubDate>
    </item>
    <item>
      <title>[Python] unittest - 단위 테스트</title>
      <link>https://passwd.tistory.com/entry/Python-unittest-%EB%8B%A8%EC%9C%84-%ED%85%8C%EC%8A%A4%ED%8A%B8</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size23&quot;&gt;개요&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;개발 과정에서 테스트는 필수적이다. 하지만 여태까지 테스트 코드를 작성해 본 적은 없는데, 이유는 여럿이 있겠지만 근본 원인은 잘 몰라서였다. 인터넷에서 떠도는 테스트 주도 개발이라는 게 뭔지, 그래서 어떤 함수를 테스트해야 하는지 등등&amp;hellip;&amp;hellip;. 다만 일단 작성 방법을 알아야 할 것 같으니 Python으로 테스트 코드를 작성하도록 도와주는 unittest라는 라이브러리의 사용 방법을 조금 알아보고자 한다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt; &lt;span style=&quot;font-size: 21px;&quot;&gt;unittest&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Python의 unittest는 Java JUnit, JavaScript Jest와 같은 단위 테스트 프레임워크이다. 기본적으로 내장되어 있어 바로 임포트 해서 사용할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1773104224033&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import unittest&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt; &lt;span style=&quot;font-size: 21px;&quot;&gt;TestCase&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;단위 테스트는 단위 클래스에 필요한 유틸리티 메서드를 제공하는 unitest.TestCase 클래스의 자식 클래스를 구현함으로써 작성한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;예시는 1과 2의 합이 3과 동일하면 통과하는 테스트 케이스이다.&lt;/p&gt;
&lt;pre id=&quot;code_1773104309817&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from unittest import TestCase


class MyTests(TestCase):
    def test_one_plus_two(self):
        self.assertEqual(1 + 2, 3)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;586&quot; data-origin-height=&quot;297&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bW0Ld6/dJMb99Mju30/iAftXVis7kGknXKfHgpeFk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bW0Ld6/dJMb99Mju30/iAftXVis7kGknXKfHgpeFk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bW0Ld6/dJMb99Mju30/iAftXVis7kGknXKfHgpeFk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbW0Ld6%2FdJMb99Mju30%2FiAftXVis7kGknXKfHgpeFk%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;586&quot; height=&quot;297&quot; data-origin-width=&quot;586&quot; data-origin-height=&quot;297&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;실행&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;테스트는 기본적으로 unittest 모듈로 python 파일을 실행하는 방식으로 실행할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1773104915623&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;python -m unittest TEST_FILE.py&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;642&quot; data-origin-height=&quot;105&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/80yXc/dJMcafTkum8/0Gi5fRPHGlswxDemc62pGk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/80yXc/dJMcafTkum8/0Gi5fRPHGlswxDemc62pGk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/80yXc/dJMcafTkum8/0Gi5fRPHGlswxDemc62pGk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F80yXc%2FdJMcafTkum8%2F0Gi5fRPHGlswxDemc62pGk%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;642&quot; height=&quot;105&quot; data-origin-width=&quot;642&quot; data-origin-height=&quot;105&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;테스트가 실패한 경우에는 왜 실패했는지 확인할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;626&quot; data-origin-height=&quot;244&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bA2krd/dJMcaibsMZP/xSjku2ogKIVIPyWnxdjhOK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bA2krd/dJMcaibsMZP/xSjku2ogKIVIPyWnxdjhOK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bA2krd/dJMcaibsMZP/xSjku2ogKIVIPyWnxdjhOK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbA2krd%2FdJMcaibsMZP%2FxSjku2ogKIVIPyWnxdjhOK%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;626&quot; height=&quot;244&quot; data-origin-width=&quot;626&quot; data-origin-height=&quot;244&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;보다 단순하게 실행시키고 싶다면 테스트 코드 파일에 아래와 같음 main을 추가하여 일반 Python 파일 실행하듯이 실행할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1773105140824&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;if __main__ == '__main__':
    unittest.main()&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;실행&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1773105168564&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;python TEST_FILE.py&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;582&quot; data-origin-height=&quot;104&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bzv1b3/dJMcafMAbNh/NbSZuah1BDakKyjb838n30/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bzv1b3/dJMcafMAbNh/NbSZuah1BDakKyjb838n30/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bzv1b3/dJMcafMAbNh/NbSZuah1BDakKyjb838n30/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbzv1b3%2FdJMcafMAbNh%2FNbSZuah1BDakKyjb838n30%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;582&quot; height=&quot;104&quot; data-origin-width=&quot;582&quot; data-origin-height=&quot;104&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;assertion&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;unittest는 여러 유형의 assert 문을 제공하고 있다. 가장 많이 사용하는 것은 아래와 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1773106091244&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from unittest import TestCase


class MyTests(TestCase):
    def test_one_plus_two(self):
        self.assertEqual(1 + 2, 3)

    def test_other_assertions(self):
        self.assertTrue(1 == 1) # 참
        self.assertFalse(1 == 2) # 거짓
        self.assertGreater(2, 1) # &amp;gt;
        self.assertLess(1, 2) # &amp;lt;
        self.assertIn(1, [1, 2]) # 포함
        self.assertIsInstance(1, int) # 데이터 타입&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 시작--&gt;&lt;/p&gt;
&lt;h4 style=&quot;font-size: 10px; color: #1f1f1f; border-left: #ff327f 10px solid; margin: 0px 0px 10px; letter-spacing: -1px; line-height: normal; font-stretch: normal; padding: 0px 0px 0px 7px;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #ff327f;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;참고 문서&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://daleseo.com/python-unittest-testcase/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://daleseo.com/python-unittest-testcase/&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://wikidocs.net/16107&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://wikidocs.net/16107&lt;/a&gt;&lt;/p&gt;</description>
      <category>Python</category>
      <category>python</category>
      <author>비번변경</author>
      <guid isPermaLink="true">https://passwd.tistory.com/1499</guid>
      <comments>https://passwd.tistory.com/entry/Python-unittest-%EB%8B%A8%EC%9C%84-%ED%85%8C%EC%8A%A4%ED%8A%B8#entry1499comment</comments>
      <pubDate>Fri, 13 Mar 2026 11:28:53 +0900</pubDate>
    </item>
    <item>
      <title>[Terraform] external - 외부 프로그램 연동</title>
      <link>https://passwd.tistory.com/entry/Terraform-external-%EC%99%B8%EB%B6%80-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%A8-%EC%97%B0%EB%8F%99</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size23&quot;&gt;개요&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Terraform 코드를 작성하면서 별도로 작성한 스크립트를 실행해야 하는 케이스가 있었다. 이런 경우 외부 프로그램을 연동할 때 사용하는 external 프로바이더를 활용할 수 있는데, 이번 글에서는 그 사용법을 확인하려고 한다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt; &lt;span style=&quot;font-size: 21px;&quot;&gt;external&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;terraform과 외부 프로그램 간의 인터페이스를 제공하는 특수한 프로바이더이다. 프로바이더가 없는 시스템과 연동할 때 유용하지만 정식 프로바이더만큼 강력하지는 않다는 한계점이 있다. 또한 외부 프로그램에 대한 종속성이 생기기 때문에 운영 체제에 따라 사용 가능성이 달라지거나 이식성이 저하될 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;external 프로바이더는 external 데이터소스를 제공한다. 표준 입력으로 JSON 형식의 데이터를 전달하고 표준 출력으로 JSON 형식의 데이터를 받을 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1773016187209&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Terraform &amp;rarr; 외부 프로그램 실행 &amp;rarr; JSON 결과 받기 &amp;rarr; Terraform에서 사용&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;external 데이터소스를 사용할 때는 사용할 프로그램(program)을 필수로 지정해주어야 하고, 필요한 경우 프로그램 실행 시 사용할 매개변수(query)와 프로그램의 디렉터리 (working_dir)를 전달한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt; &lt;span style=&quot;font-size: 21px;&quot;&gt;사용법&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 프로바이더 추가&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1773015481693&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;terraform {
  required_providers {
    external = {
      source = &quot;hashicorp/external&quot;
      version = &quot;2.3.5&quot;
    }
  }
}

provider &quot;external&quot; {
  # Configuration options
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;576&quot; data-origin-height=&quot;192&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Zmxvg/dJMcabi6dJY/yIKvFYL4zl20lzKnbrviR1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Zmxvg/dJMcabi6dJY/yIKvFYL4zl20lzKnbrviR1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Zmxvg/dJMcabi6dJY/yIKvFYL4zl20lzKnbrviR1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZmxvg%2FdJMcabi6dJY%2FyIKvFYL4zl20lzKnbrviR1%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;576&quot; height=&quot;192&quot; data-origin-width=&quot;576&quot; data-origin-height=&quot;192&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로바이더 추가 코드는 생략해도 크게 문제는 없는 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. 외부 프로그램 작성&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테라폼에서 실행할 프로그램을 작성한다. 아래는 매개변수 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;foo, bar를&lt;span&gt; &lt;/span&gt;&lt;/span&gt;전달받아 하나의 문자열로 연결한 결과를 반환하는 쉘 스크립트다.&lt;/p&gt;
&lt;pre id=&quot;code_1773016387529&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#!/bin/bash

# Exit if any of the intermediate steps fail
set -e

# Extract &quot;foo&quot; and &quot;baz&quot; arguments from the input into
# FOO and BAZ shell variables.
# jq will ensure that the values are properly quoted
# and escaped for consumption by the shell.
eval &quot;$(jq -r '@sh &quot;FOO=\(.foo) BAZ=\(.baz)&quot;')&quot;

# Placeholder for whatever data-fetching logic your script implements
FOOBAZ=&quot;$FOO $BAZ&quot;

# Safely produce a JSON object containing the result value.
# jq will ensure that the value is properly quoted
# and escaped to produce a valid JSON string.
jq -n --arg foobaz &quot;$FOOBAZ&quot; '{&quot;foobaz&quot;:$foobaz}'&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;입출력은 다음과 같다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1042&quot; data-origin-height=&quot;70&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bzlUN0/dJMcaibr4sf/N6A0DKBnJ6ZjZaUS4Queh1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bzlUN0/dJMcaibr4sf/N6A0DKBnJ6ZjZaUS4Queh1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bzlUN0/dJMcaibr4sf/N6A0DKBnJ6ZjZaUS4Queh1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbzlUN0%2FdJMcaibr4sf%2FN6A0DKBnJ6ZjZaUS4Queh1%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;1042&quot; height=&quot;70&quot; data-origin-width=&quot;1042&quot; data-origin-height=&quot;70&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;&lt;b&gt;3. external 데이터 소스 구성&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;program에 실행할 명령어와 스크립트를 전달하고, 스크립트에서 사용할 매개변수를 query로 전달한다.&lt;/p&gt;
&lt;pre id=&quot;code_1773016904537&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;data &quot;external&quot; &quot;example&quot; {
  program = [&quot;bash&quot;, &quot;${path.module}/example-data-source.sh&quot;]

  query = {
    # arbitrary map from strings to strings, passed
    # to the external program as the data query.
    foo = &quot;abc123&quot;
    baz = &quot;def456&quot;
  }
}

output &quot;foobaz&quot; {
  value = data.external.example.result.foobaz
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과를 확인하기 편하도록 output으로 지정하고 terraform plan을 수행한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;764&quot; data-origin-height=&quot;108&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/u6BZa/dJMcahKnBaQ/ukoD3pS7Fdz4Pd5Ha1GJBk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/u6BZa/dJMcahKnBaQ/ukoD3pS7Fdz4Pd5Ha1GJBk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/u6BZa/dJMcahKnBaQ/ukoD3pS7Fdz4Pd5Ha1GJBk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fu6BZa%2FdJMcahKnBaQ%2FukoD3pS7Fdz4Pd5Ha1GJBk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;764&quot; height=&quot;108&quot; data-origin-width=&quot;764&quot; data-origin-height=&quot;108&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사전에 확인했던 대로 foo, baz로 전달한 문자열이 공백을 구분자로 연결된 모습을 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 시작--&gt;&lt;/p&gt;
&lt;h4 style=&quot;font-size: 10px; color: #1f1f1f; border-left: #ff327f 10px solid; margin: 0px 0px 10px; letter-spacing: -1px; line-height: normal; font-stretch: normal; padding: 0px 0px 0px 7px;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #ff327f;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;참고 문서&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://registry.terraform.io/providers/hashicorp/external/latest&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://registry.terraform.io/providers/hashicorp/external/latest&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Terraform</category>
      <category>terraform</category>
      <author>비번변경</author>
      <guid isPermaLink="true">https://passwd.tistory.com/1498</guid>
      <comments>https://passwd.tistory.com/entry/Terraform-external-%EC%99%B8%EB%B6%80-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%A8-%EC%97%B0%EB%8F%99#entry1498comment</comments>
      <pubDate>Thu, 12 Mar 2026 10:46:45 +0900</pubDate>
    </item>
    <item>
      <title>[Grafana] too many consecutive incorrect login attempts for user - login for user temporarily blocked</title>
      <link>https://passwd.tistory.com/entry/Grafana-too-many-consecutive-incorrect-login-attempts-for-user-login-for-user-temporarily-blocked</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size23&quot;&gt;개요&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Grafana에 로그인을 하려고 했는데 맞는 계정정보를 입력해도 로그인이 되질 않았다.&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;413&quot; data-origin-height=&quot;500&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bk7bqW/dJMcaivFEg7/sEa9nPhu4UmTaCL2FzLxq1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bk7bqW/dJMcaivFEg7/sEa9nPhu4UmTaCL2FzLxq1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bk7bqW/dJMcaivFEg7/sEa9nPhu4UmTaCL2FzLxq1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbk7bqW%2FdJMcaivFEg7%2FsEa9nPhu4UmTaCL2FzLxq1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;413&quot; height=&quot;500&quot; data-origin-width=&quot;413&quot; data-origin-height=&quot;500&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;float: none; clear: none;&quot; data-ke-size=&quot;size16&quot;&gt;원인을 확인해 보고 현상을 해결해 본다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;원인&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Grafana는 ubuntu에서 docker compose로 설치해 둔 상태다. 파일 로그는 딱히 보이지 않아 컨테이너 로그를 확인해 보니 아래와 같은 내용을 찾을 수 있었다.&lt;/p&gt;
&lt;pre id=&quot;code_1772756524805&quot; class=&quot;routeros&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;logger=context userId=0 orgId=0 uname= t=2026-03-03T06:56:15.634017708Z level=info msg=&quot;Request Completed&quot; method=POST path=/login status=401 remote_addr=100.100.100.100 time_ms=0 duration=990.695&amp;micro;s size=94 referer=http://100.100.100.100:3000/login handler=/login status_source=server errorReason=Unauthorized errorMessageID=password-auth.failed error=&quot;too many consecutive incorrect login attempts for user - login for user temporarily blocked&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;로그인 실패 횟수가 누적되어 일시적인 로그인 차단이 발생한 것으로 보인다. 로그 상의 내용만 보면 일정 시간이 지나면 로그인이 가능해질 것 같은데, 정확히 언제부터 가능한지는 나오지 않는 것 같다. 아마 5분 정도인 듯?&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt; &lt;span style=&quot;font-size: 21px;&quot;&gt;해결&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;관리자 권한으로 비밀번호를 변경해 주면 즉시 로그인이 가능한 것 같다. 변경할 때는 기존 비밀번호로 초기화해도 괜찮다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 사용자 관리 페이지 이동&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;메뉴 &amp;gt; 관리 &amp;gt; 사용자 및 액세스 권한 &amp;gt; 사용자로 접근한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;294&quot; data-origin-height=&quot;496&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sYpus/dJMcacPNtCQ/NS31TJcKS0DfTlwBR5aLkK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sYpus/dJMcacPNtCQ/NS31TJcKS0DfTlwBR5aLkK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sYpus/dJMcacPNtCQ/NS31TJcKS0DfTlwBR5aLkK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsYpus%2FdJMcacPNtCQ%2FNS31TJcKS0DfTlwBR5aLkK%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;294&quot; height=&quot;496&quot; data-origin-width=&quot;294&quot; data-origin-height=&quot;496&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. 비밀번호를 초기화할 사용자 선택&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;953&quot; data-origin-height=&quot;340&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/byg0wn/dJMcac3iyLB/QMXok285VzbYbfkyTMnXTK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/byg0wn/dJMcac3iyLB/QMXok285VzbYbfkyTMnXTK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/byg0wn/dJMcac3iyLB/QMXok285VzbYbfkyTMnXTK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbyg0wn%2FdJMcac3iyLB%2FQMXok285VzbYbfkyTMnXTK%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;953&quot; height=&quot;340&quot; data-origin-width=&quot;953&quot; data-origin-height=&quot;340&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;3. &lt;b&gt;비밀번호&lt;/b&gt; 편집&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;938&quot; data-origin-height=&quot;433&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bnO6yv/dJMcagScDLZ/yFnEKkY5Mzzr5YyA3cY7f0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bnO6yv/dJMcagScDLZ/yFnEKkY5Mzzr5YyA3cY7f0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bnO6yv/dJMcagScDLZ/yFnEKkY5Mzzr5YyA3cY7f0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbnO6yv%2FdJMcagScDLZ%2FyFnEKkY5Mzzr5YyA3cY7f0%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;938&quot; height=&quot;433&quot; data-origin-width=&quot;938&quot; data-origin-height=&quot;433&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;편집 버튼을 클릭하면 아래와 같이 입력 폼이 표시된다. 원하는 값으로 설정하여 Save 버튼을 클릭한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;909&quot; data-origin-height=&quot;389&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/swOmY/dJMcaflrUmg/v6cBhhKkq3vPlQxU2B3Jb0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/swOmY/dJMcaflrUmg/v6cBhhKkq3vPlQxU2B3Jb0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/swOmY/dJMcaflrUmg/v6cBhhKkq3vPlQxU2B3Jb0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FswOmY%2FdJMcaflrUmg%2Fv6cBhhKkq3vPlQxU2B3Jb0%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;909&quot; height=&quot;389&quot; data-origin-width=&quot;909&quot; data-origin-height=&quot;389&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;4. 로그인 확인&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정상적으로 로그인이 되는지 확인한다. 계정의 비밀번호를 변경하면 기존에 로그인되어 있던 세션이 전부 끊어지며 새로 로그인을 해야 하는 것으로 보인다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 시작--&gt;&lt;/p&gt;
&lt;h4 style=&quot;font-size: 10px; color: #1f1f1f; border-left: #ff327f 10px solid; margin: 0px 0px 10px; letter-spacing: -1px; line-height: normal; font-stretch: normal; padding: 0px 0px 0px 7px;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-size: 21px; color: #ff327f;&quot;&gt; 참고 문서&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/grafana/grafana/issues/30161&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/grafana/grafana/issues/30161&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Grafana</category>
      <category>Grafana</category>
      <author>비번변경</author>
      <guid isPermaLink="true">https://passwd.tistory.com/1497</guid>
      <comments>https://passwd.tistory.com/entry/Grafana-too-many-consecutive-incorrect-login-attempts-for-user-login-for-user-temporarily-blocked#entry1497comment</comments>
      <pubDate>Wed, 11 Mar 2026 10:34:44 +0900</pubDate>
    </item>
    <item>
      <title>[Java] generic - 2</title>
      <link>https://passwd.tistory.com/entry/Java-generic-2</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size23&quot;&gt;개요&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://passwd.tistory.com/entry/Java-generic&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;2026.03.03-[Java] generic - 1&lt;/a&gt;에서 generic이 무엇인지, 기본적인 개념 위주로 정리했다. 이번 글에서는 조금 더 세부적이고 소소한 내용을 정리한다.&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;!--헤드라인 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt; &lt;span style=&quot;font-size: 21px;&quot;&gt;타입 파라미터 할당 가능 타입&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;generic 할당은 Reference 타입만 가능하다. int, double과 같은 원시(Primitive) 타입 대신 Integer, Double을 사용해야 한다. 클래스로 지정하기 때문에 개체 지향 프로그래밍의 다형성 원리도 적용된다. 예로 들어 Apple, Banana라는 두 개 클래스가 Fruit이라는 클래스의 자식 클래스일 때, generic에 Fruit이라고 지정하면 Apple, Banana도 취급할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1772668216055&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Fruit { }
class Apple extends Fruit { }
class Banana extends Fruit { }

class FruitBox&amp;lt;T&amp;gt; {
    List&amp;lt;T&amp;gt; fruits = new ArrayList&amp;lt;&amp;gt;();

    public void add(T fruit) {
        fruits.add(fruit);
    }
}

public class Main {
    public static void main(String[] args) {
        FruitBox&amp;lt;Fruit&amp;gt; box = new FruitBox&amp;lt;&amp;gt;();
        
        // 제네릭 타입은 다형성 원리가 그대로 적용된다.
        box.add(new Fruit());
        box.add(new Apple());
        box.add(new Banana());
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;복수&amp;nbsp;타입&amp;nbsp;파라미터&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;generic에는 여러 개의 타입을 지정할 수 있다. 여러 개를 지정할 때는 다이아몬드 연산자 안에 쉼표로 구분한다.&lt;/p&gt;
&lt;pre id=&quot;code_1772668506638&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.util.ArrayList;
import java.util.List;

class Apple {}
class Banana {}

class FruitBox&amp;lt;T, U&amp;gt; {
    List&amp;lt;T&amp;gt; apples = new ArrayList&amp;lt;&amp;gt;();
    List&amp;lt;U&amp;gt; bananas = new ArrayList&amp;lt;&amp;gt;();

    public void add(T apple, U banana) {
        apples.add(apple);
        bananas.add(banana);
    }
}

public class Main {
    public static void main(String[] args) {
    	// 복수 제네릭 타입
        FruitBox&amp;lt;Apple, Banana&amp;gt; box = new FruitBox&amp;lt;&amp;gt;();
        box.add(new Apple(), new Banana());
        box.add(new Apple(), new Banana());
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;중첩 타입 파라미터&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;타입 파라미터에는 generic 객체를 지정할 수도 있다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1772670217887&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public static void main(String[] args) {
    // LinkedList&amp;lt;String&amp;gt;을 원소로서 저장하는 ArrayList
    ArrayList&amp;lt;LinkedList&amp;lt;String&amp;gt;&amp;gt; list = new ArrayList&amp;lt;LinkedList&amp;lt;String&amp;gt;&amp;gt;();

    LinkedList&amp;lt;String&amp;gt; node1 = new LinkedList&amp;lt;&amp;gt;();
    node1.add(&quot;aa&quot;);
    node1.add(&quot;bb&quot;);

    LinkedList&amp;lt;String&amp;gt; node2 = new LinkedList&amp;lt;&amp;gt;();
    node2.add(&quot;11&quot;);
    node2.add(&quot;22&quot;);

    list.add(node1);
    list.add(node2);
    System.out.println(list);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;224&quot; data-origin-height=&quot;63&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wvQ43/dJMcagkkyn3/kbk7PXNzS6A1XPYSpzg1n1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wvQ43/dJMcagkkyn3/kbk7PXNzS6A1XPYSpzg1n1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wvQ43/dJMcagkkyn3/kbk7PXNzS6A1XPYSpzg1n1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwvQ43%2FdJMcagkkyn3%2Fkbk7PXNzS6A1XPYSpzg1n1%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;224&quot; height=&quot;63&quot; data-origin-width=&quot;224&quot; data-origin-height=&quot;63&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;타입 파라미터 네이밍&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금까지 generic을 표기할 때 &amp;lt;T&amp;gt;와 같이 표현했으나, 문법적으로 정해진 값은 없다. 다만 암묵적으로 T를 많이 사용하고 여러 generic이 필요한 경우에는 S, U 등으로 표기한다. 타입 외의 요소를 표현할 때는 암묵적으로 아래와 같인 규칙을 따른다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;타입&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;설명&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&amp;lt;T&amp;gt;&lt;/td&gt;
&lt;td&gt;타입(Type)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&amp;lt;E&amp;gt;&lt;/td&gt;
&lt;td&gt;요소(Element), 예를 들어 List&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&amp;lt;K&amp;gt;&lt;/td&gt;
&lt;td&gt;키(Key), 예를 들어 Map&amp;lt;k, v&amp;gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&amp;lt;V&amp;gt;&lt;/td&gt;
&lt;td&gt;리턴 값 또는 매핑된 값(Variable)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&amp;lt;N&amp;gt;&lt;/td&gt;
&lt;td&gt;숫자(Number)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&amp;lt;S, U, V&amp;gt;&lt;/td&gt;
&lt;td&gt;2번째, 3번째, 4번째에 선언된 타입&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 시작--&gt;&lt;/p&gt;
&lt;h4 style=&quot;font-size: 10px; color: #1f1f1f; border-left: #ff327f 10px solid; margin: 0px 0px 10px; letter-spacing: -1px; line-height: normal; font-stretch: normal; padding: 0px 0px 0px 7px;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-size: 21px; color: #ff327f;&quot;&gt; 참고 문서&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a style=&quot;color: #3d62ce;&quot; href=&quot;https://inpa.tistory.com/entry/JAVA-%E2%98%95-%EC%A0%9C%EB%84%A4%EB%A6%ADGenerics-%EA%B0%9C%EB%85%90-%EB%AC%B8%EB%B2%95-%EC%A0%95%EB%B3%B5%ED%95%98%EA%B8%B0&quot;&gt;☕&amp;nbsp;자바&amp;nbsp;제네릭(Generics)&amp;nbsp;개념&amp;nbsp;&amp;amp;&amp;nbsp;문법&amp;nbsp;정복하기&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;color: #555555; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://st-lab.tistory.com/153&quot;&gt;https://st-lab.tistory.com/153&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Java</category>
      <category>Java</category>
      <author>비번변경</author>
      <guid isPermaLink="true">https://passwd.tistory.com/1496</guid>
      <comments>https://passwd.tistory.com/entry/Java-generic-2#entry1496comment</comments>
      <pubDate>Tue, 10 Mar 2026 10:29:01 +0900</pubDate>
    </item>
    <item>
      <title>[AWS] Aurora vs RDS</title>
      <link>https://passwd.tistory.com/entry/AWS-Aurora-vs-RDS</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size23&quot;&gt;개요&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;기존에는 AWS의 데이터베이스 서비스 중 RDS를 주로 사용해왔는데, 현재는 Aurora도 사용을 하고 있다. Aurora가 보다 AWS에 친화적인 서비스라는 건 알고 있지만 다른 차이점은 알고 있지않아 정리해보려고 한다.&lt;/p&gt;
&lt;p style=&quot;float: none; clear: none;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt; &lt;span style=&quot;font-size: 21px;&quot;&gt;AWS Aurora&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;300&quot; data-origin-height=&quot;300&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dlBVqS/dJMcahQ4usK/cC5AIam1wqim3VKLYri7Bk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dlBVqS/dJMcahQ4usK/cC5AIam1wqim3VKLYri7Bk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dlBVqS/dJMcahQ4usK/cC5AIam1wqim3VKLYri7Bk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdlBVqS%2FdJMcahQ4usK%2FcC5AIam1wqim3VKLYri7Bk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;300&quot; height=&quot;300&quot; data-origin-width=&quot;300&quot; data-origin-height=&quot;300&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;AWS Aurora는 데이터베이스 서비스 중 하나로 클라우드 네이티브 기반의 고성능, 고확장성 데이터베이스 서비스로 설계되어 MySQL, PostgreSQL을 제공한다. RDS와 비교하면 최대 3배의 read replicas와 MySQL 대비 5배, PostgreSQL 대비 3배의 처리량을 제공한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;RDS가 제공하는 모든 관리 기능 뿐만 아니라 서버리스 서비스도 제공하고 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Aurora는 기존의 데이터베이스 엔진을 커스트마이징해 AWS에 최적화한 게 특징으로, EBS 대시 NVMe SSD에 구축해 보다 빠른 성능 상의 이점을 갖고 있다. 또한 애플리케이션에 따라 자동을 확장되며, 6개의 데이터 복사본을 생성해 여러 위치에 배포한뒤 S3에 지속적으로 백업하는 특징을 가진다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;엔드포인트&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Aurora는 4개의 엔드포인트를 가진다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;- Cluster Endpoint : Writer 인스턴스만 접근하는 엔드포인트로, failover되면 엔드포인트에 매핑되는 인스턴스가 변경된다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;- Read Endpoint : read replica를 그룹화한 엔드포인트로 라운드로빈으로 접근한다.&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;- Instance Endpoint : 각 인스턴스에 할당된 엔드포인트&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;- Custom Endpoint : Route53와 유사한 역할을 하며 사용자가 직접 엔드포인트를 생성한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;Aurora&amp;nbsp;vs&amp;nbsp;RDS&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Aurora와 RDS의 유지 관리는 전반적으로 유사하지만 스토리지에는 큰 차이가 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Aurora는 데이터 용량이 증가할수록 클러스터 볼륨이 최대 128 TiB까지 자동으로 확장될 수 있다. 반면 RDS는 사용자가 직접 볼륨을 증설해주어야 한다. 또한 EBS를 사용하는 RDS와 달리 Aurora는 &lt;span style=&quot;color: #333333; text-align: left;&quot;&gt;Shared Storage를 사용하며, &lt;/span&gt;MySQL의 경우에는 Binlog 기반의 replication이 아니라 Storage와 Page 기반의 replication을 사용한다. 즉, 스토리지 수준에서 복제가 발생한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;640&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bRGUMG/dJMcadA4p98/EJ5SulKKirMGdZK2KIN1gK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bRGUMG/dJMcadA4p98/EJ5SulKKirMGdZK2KIN1gK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bRGUMG/dJMcadA4p98/EJ5SulKKirMGdZK2KIN1gK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbRGUMG%2FdJMcadA4p98%2FEJ5SulKKirMGdZK2KIN1gK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;640&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;640&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Aurora는 AWS가 개발해 주기적으로 버전 업그레이드를 수행하기 때문에 AWS가 mandatory, optional을 정하는 반면, RDS는 사용자가 버전 업그레이드를 한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 시작--&gt;&lt;/p&gt;
&lt;h4 style=&quot;font-size: 10px; color: #1f1f1f; border-left: #ff327f 10px solid; margin: 0px 0px 10px; letter-spacing: -1px; line-height: normal; font-stretch: normal; padding: 0px 0px 0px 7px;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #ff327f;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;참고 문서&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/CHAP_AuroraOverview.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/CHAP_AuroraOverview.html&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.cloudzero.com/blog/aurora-vs-rds/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.cloudzero.com/blog/aurora-vs-rds/&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.geeksforgeeks.org/devops/aws-rds-vs-aurora/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.geeksforgeeks.org/devops/aws-rds-vs-aurora/&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://norgb.tistory.com/22&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://norgb.tistory.com/22&lt;/a&gt;&lt;/p&gt;</description>
      <category>AWS</category>
      <category>AWS</category>
      <author>비번변경</author>
      <guid isPermaLink="true">https://passwd.tistory.com/1495</guid>
      <comments>https://passwd.tistory.com/entry/AWS-Aurora-vs-RDS#entry1495comment</comments>
      <pubDate>Mon, 9 Mar 2026 11:12:23 +0900</pubDate>
    </item>
    <item>
      <title>[Java] generic - 1</title>
      <link>https://passwd.tistory.com/entry/Java-generic</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size23&quot;&gt;개요&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://passwd.tistory.com/entry/Java-ArrayList&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;2026.02.25-[Java] ArrayList&lt;/a&gt; 등의 글에서 리스트 내 데이터 원소의 타입을 지정할 때 데이터 타입을 꺽쇠로 감싸서 지정하는데, 이는 제네릭(generic)이라는 개념이다. 뭔지 정확하게 모르고 사용을 해왔으니 이번 글에서는 generic에 대해서 조금 다뤄볼까 한다.&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;!--헤드라인 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;generic&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;generic은 사전적으로 '일반적인'이라는 의미를 가지고 있는데, Java에서는 하나의 값이 데이터 형식에 의존하지 않고 여러 데이터 타입을 가질 수 있도록 하는 방법을 의미한다. 다른 말로는 클래스 내에서 사용할 데이터 타입을 외부에서 지정하는 기법이라고 한다.&lt;/p&gt;
&lt;pre id=&quot;code_1772496000617&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ArrayList&amp;lt;String&amp;gt; list = new ArrayList&amp;lt;&amp;gt;();&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;주로 List 등에 사용되는데, List와 같은 자료구조를 직접 구현하여 배포하려고 한다. 이 자료구조는 String, Integer, Double 등 다양한 타입을 지원하고자 한다. 이때 각 데이터 타입에 대한 클래스를 별도로 구현해야 할까? 이러한 비효율을 해소하기 위해 generic을 사용한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;ArrayList 선언을 통해 확인할 수 있듯, generic은 컬렉션 내에서 사용할 내부 데이터 타입을 파라미터로 전달하듯 외부에서 지정한다. 조금 풀어서 말하면 타입을 변수화한 것이라고 생각할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;장점&lt;/span&gt;&lt;/span&gt;&lt;/h3&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;generic은 java 1.5에 추가된 기법으로, 그 전에는 여러 타입을 다루기 위해서는 Object를 사용했다. 이때 객체를 다시 원하는 타입으로 변환해주어야 했기 때문에 런타임에서 오류가 발생할 가능성이 많았다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;하지만 generic을 사용하면 컴파일 타임에 타입 오류를 확인할 수 있기 때문에 개발에 용이하다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;불필요한 캐스팅 방지&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Object를 통해 여러 타입을 다룰 때는 요소를 가져오면서 다운캐스팅이 필요했다. 하지만 generic은 사전에 데이터 타입을 지정하고 제한하기 때문에 캐스팅에 대한 번거로움과 오버헤드를 줄일 수 있다. 뿐만 아니라 타입 검사에 들어가는 메모리도 절감하며 가독성도 챙길 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;제네릭 타입 매개변수&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;generic에서 데이터 타입을 지정하는 꺽쇠는 다이아몬트 연산자라고 한다. 꺽쇠 내에 식별자 기호를 지정함으로써 파라미터화하는데, 메서드가 매개변수를 받아 사용하는 것과 비슷하기 때문에 타입 매개변수, 타입 변수라고 부른다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;758&quot; data-origin-height=&quot;211&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Ne59e/dJMcahDvFJa/TDjd0JbgK5Zkrfpi8ooQUk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Ne59e/dJMcahDvFJa/TDjd0JbgK5Zkrfpi8ooQUk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Ne59e/dJMcahDvFJa/TDjd0JbgK5Zkrfpi8ooQUk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNe59e%2FdJMcahDvFJa%2FTDjd0JbgK5Zkrfpi8ooQUk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;758&quot; height=&quot;211&quot; data-origin-width=&quot;758&quot; data-origin-height=&quot;211&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;타입 매개변수는 generic을 이용한 클래스, 메서드를 설계할 때 사용한다. 아래는 generic을 사용한 클래스 정의 코드로, 클래스 이름 옆에 &amp;lt;T&amp;gt;로 generic을 붙여주었다.&lt;/p&gt;
&lt;pre id=&quot;code_1772497267970&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class FruitBox&amp;lt;T&amp;gt; {
    List&amp;lt;T&amp;gt; fruits = new ArrayList&amp;lt;&amp;gt;();

    public void add(T fruit) {
        fruits.add(fruit);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 클래스 내에서 T를 클래스 필드와 메서드 매개변수의 타입으로 지정했다. 이를 인스턴스화하면 아래와 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1772497395087&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 제네릭 타입 매개변수에 정수 타입을 할당
FruitBox&amp;lt;Integer&amp;gt; intBox = new FruitBox&amp;lt;&amp;gt;(); 

// 제네릭 타입 매개변수에 실수 타입을 할당
FruitBox&amp;lt;Double&amp;gt; intBox = new FruitBox&amp;lt;&amp;gt;();

// 다른 클래스
FruitBox&amp;lt;Apple&amp;gt; intBox = new FruitBox&amp;lt;Apple&amp;gt;();&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생성 코드에서 다이아몬드 연산자 내에 타입을 지정하면 generic 클래스 선언 내에서 T로 지정된 부분이 모두 전달받은 타입으로 변환된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;335&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cO2XpY/dJMcafFII9J/ZOFQZPWKNwEICGHYBGbTKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cO2XpY/dJMcafFII9J/ZOFQZPWKNwEICGHYBGbTKK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cO2XpY/dJMcafFII9J/ZOFQZPWKNwEICGHYBGbTKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcO2XpY%2FdJMcafFII9J%2FZOFQZPWKNwEICGHYBGbTKK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;335&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;335&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이것을 generic 타입 전파 또는 구체화라고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 시작--&gt;&lt;/p&gt;
&lt;h4 style=&quot;font-size: 10px; color: #1f1f1f; border-left: #ff327f 10px solid; margin: 0px 0px 10px; letter-spacing: -1px; line-height: normal; font-stretch: normal; padding: 0px 0px 0px 7px;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #ff327f;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;참고 문서&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://inpa.tistory.com/entry/JAVA-%E2%98%95-%EC%A0%9C%EB%84%A4%EB%A6%ADGenerics-%EA%B0%9C%EB%85%90-%EB%AC%B8%EB%B2%95-%EC%A0%95%EB%B3%B5%ED%95%98%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;☕&amp;nbsp;자바&amp;nbsp;제네릭(Generics)&amp;nbsp;개념&amp;nbsp;&amp;amp;&amp;nbsp;문법&amp;nbsp;정복하기&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://st-lab.tistory.com/153&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://st-lab.tistory.com/153&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Java</category>
      <category>Java</category>
      <author>비번변경</author>
      <guid isPermaLink="true">https://passwd.tistory.com/1494</guid>
      <comments>https://passwd.tistory.com/entry/Java-generic#entry1494comment</comments>
      <pubDate>Fri, 6 Mar 2026 10:04:28 +0900</pubDate>
    </item>
    <item>
      <title>[Python] psycopg2.execute_values - 여러 데이터 처리</title>
      <link>https://passwd.tistory.com/entry/Python-psycopg2executevalues-%EC%97%AC%EB%9F%AC-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%B2%98%EB%A6%AC</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size23&quot;&gt;개요&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;python으로 데이터베이스 작업을 수행하다 보면 여러 데이터를 한 번에 처리할 필요가 자주 발생한다. 이때 보통 executemay 등의 이름을 가진 함수를 사용하는데, postgreSQL 연동 라이브러리인 psycopg2의 경우에는 비슷한 기능을 가진 여러 함수를 제공하고 있는 것 같다. 이번 글에서는 그중 하나인 execute_values에 대해서 조금 알아본다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt; &lt;span style=&quot;font-size: 21px;&quot;&gt;execute_values&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;execute_values는 psycopg2 2.7버전에 추가된 함수로, 매개변수를 사용해 명령문을 실행한다.&lt;/p&gt;
&lt;pre id=&quot;code_1772173971949&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;psycopg2.extras.execute_values(cur, sql, argslist, template=None, page_size=100, fetch=False)
# cur : 커서 객체
# sql : 실행 SQL
# argslist : 쿼리에 전달할 인수
# template : 쿼리를 구성하는 arglist의 템플릿. 자리표시자 또는 명명된 자리표시자에 해당한다.
# page_size : arglist의 최대 개수. 초과 시 두 개 이상의 문장 실행.
# fetch : 쿼리 결과 반환 여부. RETURNING절이 포함된 경우 유용하다.&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;사용 자체는 일반 execute와 크게 다르지 않다. 아래는 테이블에 데이터를 추가하는 예시 코드이다.&lt;/p&gt;
&lt;pre id=&quot;code_1772174790223&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import psycopg2
from psycopg2.extras import execute_values

host = 'host'
port = 5432
user = 'user'
password = 'user'
database = 'study'

# 1. 데이터 준비 (튜플의 리스트)
data = [(1, 'Alice'), (2, 'Bob'), (3, 'Charlie')]

# 2. 커넥션 및 커서 생성
with psycopg2.connect(host=host, port=port, user=user, password=password, database=database) as conn:
    cur = conn.cursor()

    # 3. execute_values 사용
    sql = &quot;INSERT INTO users (id, name) VALUES %s&quot;
    execute_values(cur, sql, data)

    conn.commit()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;284&quot; data-origin-height=&quot;224&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qGgC7/dJMcaaYFWL9/pic8esrGO0u4UD7evyJKfk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qGgC7/dJMcaaYFWL9/pic8esrGO0u4UD7evyJKfk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qGgC7/dJMcaaYFWL9/pic8esrGO0u4UD7evyJKfk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqGgC7%2FdJMcaaYFWL9%2Fpic8esrGO0u4UD7evyJKfk%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;224&quot; data-origin-width=&quot;284&quot; data-origin-height=&quot;224&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만 동작 방식에 있어서 executemany에 차이가 있다고 한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt; &lt;span style=&quot;font-size: 21px;&quot;&gt;executemany vs execute_values&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;psycopg2의 executemany는 for 반복문을 사용해 execute를 반복 실행하는 방식으로 동작한다. 때문에 대량의 데이터를 삽입할 때에는 성능 상 이점이 없다. 이러한 문제를 해소하기 위해 반복실행에 최적화된 함수로 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;execute_batch와&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;execute_values가 존재한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;execute_batch의 경우 executemany와 비슷하지만 SQL을 하나로 묶어서 전송한다는 차이가 있다. 예시로 아래의 3개 쿼리를 실행한다고 하면 executemany는 한 줄씩 전달하지만, execute_batch는 세 줄을 한 번에 전달한다는 의미이다.&lt;/p&gt;
&lt;pre id=&quot;code_1772175093916&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;INSERT INTO simple_table (a, b, c) VALUES (1, 2, 3);
INSERT INTO simple_table (a, b, c) VALUES (10, 20, 30);
INSERT INTO simple_table (a, b, c) VALUES (100, 200, 300);&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;반면 execute_values는 values에 값을 여러 개로 묶어서 전달한다. 즉, 하나의 insert만 수행한다.&lt;/p&gt;
&lt;pre id=&quot;code_1772176352707&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;INSERT INTO simple_table (a, b, c) VALUES
    ((SELECT id FROM num_table WHERE number = 1), 2, 3),
    ((SELECT id FROM num_table WHERE number = 10), 20, 30),
    ((SELECT id FROM num_table WHERE number = 100), 200, 300);&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;execute_values가 반복도 없고, 실행 쿼리도 적기 때문에 다른 함수보다 성능 상의 이점을 갖고 있다고 할 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 시작--&gt;&lt;/p&gt;
&lt;h4 style=&quot;font-size: 10px; color: #1f1f1f; border-left: #ff327f 10px solid; margin: 0px 0px 10px; letter-spacing: -1px; line-height: normal; font-stretch: normal; padding: 0px 0px 0px 7px;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-size: 21px; color: #ff327f;&quot;&gt; 참고 문서&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.psycopg.org/docs/extras.html#psycopg2.extras.execute_values&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.psycopg.org/docs/extras.html#psycopg2.extras.execute_values&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://brownbears.tistory.com/567&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://brownbears.tistory.com/567&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://int-i.github.io/python/2022-02-27/python-postgres-psycopg2-bulk-insert/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://int-i.github.io/python/2022-02-27/python-postgres-psycopg2-bulk-insert/&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Python</category>
      <author>비번변경</author>
      <guid isPermaLink="true">https://passwd.tistory.com/1493</guid>
      <comments>https://passwd.tistory.com/entry/Python-psycopg2executevalues-%EC%97%AC%EB%9F%AC-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%B2%98%EB%A6%AC#entry1493comment</comments>
      <pubDate>Thu, 5 Mar 2026 17:14:06 +0900</pubDate>
    </item>
    <item>
      <title>[Java] ArrayList</title>
      <link>https://passwd.tistory.com/entry/Java-ArrayList</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size23&quot;&gt;개요&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이번 글에서는 Java에서 매우 흔하게 사용하고 있는 ArrayList에 대해서 정리한다.&lt;/p&gt;
&lt;p style=&quot;float: none; clear: none;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;ArrayList&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;ArrayList는 Array의 불편함을 해소하기 위해 나온 개념으로, 연속적인 데이터의 리스트이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;670&quot; data-origin-height=&quot;285&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DWw1t/dJMcaaxBKsR/yOGwiYKCmiRet6kNMKJf3K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DWw1t/dJMcaaxBKsR/yOGwiYKCmiRet6kNMKJf3K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DWw1t/dJMcaaxBKsR/yOGwiYKCmiRet6kNMKJf3K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDWw1t%2FdJMcaaxBKsR%2FyOGwiYKCmiRet6kNMKJf3K%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;670&quot; height=&quot;285&quot; data-origin-width=&quot;670&quot; data-origin-height=&quot;285&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;내부적으로 Object[]을 이용하고 있으며, 인덱스를 이용해 요소에 빠르게 접근할 수 있다. 배열과 다르게 크기가 가변적(동적 할당)이지만, 배열의 크기가 가득 찰 때마다 copy 하는 방식으로 크기를 조정하기 때문에 지연이 발생할 수 있다. 데이터를 중간에 삽입하거나 삭제하는 경우에는 리스트 내 공간 조정으로 인해 요소의 위치가 앞뒤로 이동하기 때문에 동작이 느리다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;사용법&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;ArrayList를 사용할 때는 패키지를 import 해야 한다.&lt;/p&gt;
&lt;pre id=&quot;code_1772061861031&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.util.ArrayList;&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;아래 내용은 기본적인 ArrayList 사용법을 나열한 것이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;생성&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;ArrayList는 빈 리스트를 생성하거나, 길이를 사전에 지정하거나 다른 컬렉션으로 초기화하는 방식으로 생성할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1772062867557&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 타입설정 Integer 객체만 적재가능
ArrayList&amp;lt;Integer&amp;gt; members = new ArrayList&amp;lt;&amp;gt;();

// 초기 용량(capacity)지정
ArrayList&amp;lt;Integer&amp;gt; num3 = new ArrayList&amp;lt;&amp;gt;(10);

// 배열을 넣어 생성
ArrayList&amp;lt;Integer&amp;gt; list2 = new ArrayList&amp;lt;&amp;gt;(Arrays.asList(1,2,3));

// 다른 컬렉션으로부터 그대로 요소를 받아와 생성
ArrayList&amp;lt;Integer&amp;gt; list3 = new ArrayList&amp;lt;&amp;gt;(list2);&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;요소 추가&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;요소는 제네릭으로 명시한 타입의 데이터만 추가할 수 있다. 참고로 capacity는 공간 크기이고, size는 리스트 내 요소의 개수에 해당한다.&lt;/p&gt;
&lt;pre id=&quot;code_1772063677337&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 리스트의 마지막에 객체 추가
list.add(VALUE);

// 전달받은 컬렉션의 모든 객체를 저장
list.addAll(VALUES);&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;829&quot; data-origin-height=&quot;362&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dZf6B1/dJMcai3pRba/3Ky6CqrkGJwFCE9myyAQZ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dZf6B1/dJMcai3pRba/3Ky6CqrkGJwFCE9myyAQZ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dZf6B1/dJMcai3pRba/3Ky6CqrkGJwFCE9myyAQZ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdZf6B1%2FdJMcai3pRba%2F3Ky6CqrkGJwFCE9myyAQZ1%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;829&quot; height=&quot;362&quot; data-origin-width=&quot;829&quot; data-origin-height=&quot;362&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;요소 추가 - 위치 지정&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;add 나 addAll 메서드에 index를 전달하여 데이터를 저장할 위치까지 지정한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;688&quot; data-origin-height=&quot;506&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/btKFPX/dJMb99McUpP/0Hq2Rwvw03etCm8rjZGlu0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/btKFPX/dJMb99McUpP/0Hq2Rwvw03etCm8rjZGlu0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/btKFPX/dJMb99McUpP/0Hq2Rwvw03etCm8rjZGlu0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbtKFPX%2FdJMb99McUpP%2F0Hq2Rwvw03etCm8rjZGlu0%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;688&quot; height=&quot;506&quot; data-origin-width=&quot;688&quot; data-origin-height=&quot;506&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만 로직 상 다른 요소의 위치를 변경하기 때문에 성능이 좋진 않다. 또한 리스트의 크기를 초과하는 인덱스를 지정할 수는 없다.&lt;/p&gt;
&lt;pre id=&quot;code_1772064496269&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 리스트의 마지막에 객체 추가
list.add(INDEX, VALUE);

// 전달받은 컬렉션의 모든 객체를 저장
list.addAll(INDEX, VALUES);&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;807&quot; data-origin-height=&quot;365&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qKaN0/dJMcagkg1aq/GIcWgOk6SOQ9VDZskkpPWK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qKaN0/dJMcagkg1aq/GIcWgOk6SOQ9VDZskkpPWK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qKaN0/dJMcagkg1aq/GIcWgOk6SOQ9VDZskkpPWK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqKaN0%2FdJMcagkg1aq%2FGIcWgOk6SOQ9VDZskkpPWK%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;807&quot; height=&quot;365&quot; data-origin-width=&quot;807&quot; data-origin-height=&quot;365&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;요소 삭제&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터를 삭제할 때는 remove나 clear 등을 사용한다. remove는 특정 위치나 특정 객체를 지정할 수 있고, removeAll을 사용하면 전달한 컬렉션과 동일한 객체를 모두 삭제한다. clear 같은 경우에는 리스트 내 모든 요소를 삭제한다.&lt;/p&gt;
&lt;pre id=&quot;code_1772065472198&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;list.remove(INDEX);

list.remove(VALUE);

list.removeAll(VALUES);

list.clear();&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;801&quot; data-origin-height=&quot;543&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bdegnN/dJMcaf6J2lM/bs9nkNJFOkWj270y85OQQ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bdegnN/dJMcaf6J2lM/bs9nkNJFOkWj270y85OQQ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bdegnN/dJMcaf6J2lM/bs9nkNJFOkWj270y85OQQ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbdegnN%2FdJMcaf6J2lM%2Fbs9nkNJFOkWj270y85OQQ0%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;801&quot; height=&quot;543&quot; data-origin-width=&quot;801&quot; data-origin-height=&quot;543&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;요소 조회&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ArrayList는 리스트가 비어있는지, 객체가 리스트에 존재하는지, 어느 위치에 존재하는지 등을 확일할 수 있는 메서드를 제공한다.&lt;/p&gt;
&lt;pre id=&quot;code_1772065684310&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 리스트가 비었는지 확인
list.isEmpty();

// 객체의 포함 여부 확인
list.contains(VALUE);

// 객체의 위치 조회
list.indexOf(VALUE);&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;594&quot; data-origin-height=&quot;525&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2vDmc/dJMcacCcbfq/C4Z7Qo7oOgpE6ytVwfXiik/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2vDmc/dJMcacCcbfq/C4Z7Qo7oOgpE6ytVwfXiik/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2vDmc/dJMcacCcbfq/C4Z7Qo7oOgpE6ytVwfXiik/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2vDmc%2FdJMcacCcbfq%2FC4Z7Qo7oOgpE6ytVwfXiik%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;594&quot; height=&quot;525&quot; data-origin-width=&quot;594&quot; data-origin-height=&quot;525&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;요소 얻기&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요소를 얻을 때는 get 메서드를 사용한다.&lt;/p&gt;
&lt;pre id=&quot;code_1772065859994&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;list.get(INDEX);&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;586&quot; data-origin-height=&quot;429&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dLvbE9/dJMcacWtiD3/KPdXVDTvkKtkCnCClKvfZk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dLvbE9/dJMcacWtiD3/KPdXVDTvkKtkCnCClKvfZk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dLvbE9/dJMcacWtiD3/KPdXVDTvkKtkCnCClKvfZk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdLvbE9%2FdJMcacWtiD3%2FKPdXVDTvkKtkCnCClKvfZk%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;586&quot; height=&quot;429&quot; data-origin-width=&quot;586&quot; data-origin-height=&quot;429&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 시작--&gt;&lt;/p&gt;
&lt;h4 style=&quot;font-size: 10px; color: #1f1f1f; border-left: #ff327f 10px solid; margin: 0px 0px 10px; letter-spacing: -1px; line-height: normal; font-stretch: normal; padding: 0px 0px 0px 7px;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-size: 21px; color: #ff327f;&quot;&gt; 참고 문서&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a title=&quot;  자바 ArrayList 구조 &amp;amp; 사용법 정리&quot; href=&quot;https://inpa.tistory.com/entry/JAVA-%E2%98%95-ArrayList-%EA%B5%AC%EC%A1%B0-%EC%82%AC%EC%9A%A9%EB%B2%95&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt; &amp;nbsp;자바&amp;nbsp;ArrayList&amp;nbsp;구조&amp;nbsp;&amp;amp;&amp;nbsp;사용법&amp;nbsp;정리&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.w3schools.com/java/java_arraylist.asp&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.w3schools.com/java/java_arraylist.asp&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://psychoria.tistory.com/765#google_vignette&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;[Java]&amp;nbsp;자바&amp;nbsp;ArrayList&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Java</category>
      <category>Java</category>
      <author>비번변경</author>
      <guid isPermaLink="true">https://passwd.tistory.com/1492</guid>
      <comments>https://passwd.tistory.com/entry/Java-ArrayList#entry1492comment</comments>
      <pubDate>Wed, 4 Mar 2026 09:57:58 +0900</pubDate>
    </item>
    <item>
      <title>[GitHub] GitHub Actions - GITHUB_STEP_SUMMARY</title>
      <link>https://passwd.tistory.com/entry/GitHub-GitHub-Actions-GITHUBSTEPSUMMARY</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size23&quot;&gt;개요&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;GitHub Actions에는 각 Job 별 동작을 요약해서 보여줄 수 있는 GITHUB_STEP_SUMMARY을 지원한다. 사용자는 GITHUB_STEP_SUMMARY를 적절하게 사용해 동작의 진행과 결과를 간결하게 표현하고 확인할 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;GITHUB_STEP_SUMMARY&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;GITHUB_STEP_SUMMARY은 마크다운 형식을 사용하며 워크플로우 진행 중 리다이렉션 등을 사용해 내용을 입력한다.&lt;/p&gt;
&lt;pre id=&quot;code_1771894562545&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;echo &quot;{markdown content}&quot; &amp;gt;&amp;gt; $GITHUB_STEP_SUMMARY&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;GITHUB_STEP_SUMMARY는 steop에 대해 고유하고, job이 완료되면 모든 step에 대한 요약이 그룹화되어 페이지에 표시된다. 여러 job이 요약을 생성하는 경우에는 완료 시간을 기준으로 정렬된다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;GITHUB_STEP_SUMMARY는 파일이므로 rm을 사용해서 삭제할 수 있는데, 삭제 후에는 기존 콘텐츠에 대한 수정이 불가하니 주의할 필요가 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt; &lt;span style=&quot;font-size: 21px;&quot;&gt;사용 예시&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간단하게 사용법을 알아보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- 단일 행 추가&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;아래 코드는 단일 행을 요약에 추가하는 예시다.&lt;/p&gt;
&lt;pre id=&quot;code_1771895476489&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;jobs:
  somethin:
    runs-on: ubuntu-latest
    steps:
      - name: summary
        run: echo &quot;### Hello world! :rocket:&quot; &amp;gt;&amp;gt; $GITHUB_STEP_SUMMARY&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: left;&quot;&gt;파일을 수정하고 워크플로우를 트리거하면 아래처럼 추가한 내용을 확인할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1152&quot; data-origin-height=&quot;648&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0kh8a/dJMcafyT0mx/u8rXuL6ZojUZYvMLosu6B0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0kh8a/dJMcafyT0mx/u8rXuL6ZojUZYvMLosu6B0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0kh8a/dJMcafyT0mx/u8rXuL6ZojUZYvMLosu6B0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0kh8a%2FdJMcafyT0mx%2Fu8rXuL6ZojUZYvMLosu6B0%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;1152&quot; height=&quot;648&quot; data-origin-width=&quot;1152&quot; data-origin-height=&quot;648&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- 여러 줄 추가&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;아래는 여러 줄을 추가하는 예시이다. 일반 파일과 동일하게 리다이렉션으로 append하면 된다.&lt;/p&gt;
&lt;pre id=&quot;code_1771895841034&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;- name: Generate list using Markdown
  run: |
    echo &quot;This is the lead in sentence for the list&quot; &amp;gt;&amp;gt; $GITHUB_STEP_SUMMARY
    echo &quot;&quot; &amp;gt;&amp;gt; $GITHUB_STEP_SUMMARY # this is a blank line
    echo &quot;- Lets add a bullet point&quot; &amp;gt;&amp;gt; $GITHUB_STEP_SUMMARY
    echo &quot;- Lets add a second bullet point&quot; &amp;gt;&amp;gt; $GITHUB_STEP_SUMMARY
    echo &quot;- How about a third one?&quot; &amp;gt;&amp;gt; $GITHUB_STEP_SUMMARY&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;315&quot; data-origin-height=&quot;298&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/3tuMt/dJMcaaj24Be/cKntMi3uQL7AXz6Y4897b1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/3tuMt/dJMcaaj24Be/cKntMi3uQL7AXz6Y4897b1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/3tuMt/dJMcaaj24Be/cKntMi3uQL7AXz6Y4897b1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F3tuMt%2FdJMcaaj24Be%2FcKntMi3uQL7AXz6Y4897b1%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;315&quot; height=&quot;298&quot; data-origin-width=&quot;315&quot; data-origin-height=&quot;298&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- job 별 SUMMARY 추가&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;하나의 JOB에서 추가하던 내용을 다른 JOB에서 추가하도록 변경했다.&lt;/p&gt;
&lt;pre id=&quot;code_1771896117059&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;name: test_summary
on:
  workflow_dispatch:
  
jobs:
  somethin:
    runs-on: ubuntu-latest
    steps:
      - name: summary
        run: echo &quot;### Hello world! :rocket:&quot; &amp;gt;&amp;gt; $GITHUB_STEP_SUMMARY
  el:
    runs-on: ubuntu-latest
    steps:
      - name: Generate list using Markdown
        run: |
          echo &quot;This is the lead in sentence for the list&quot; &amp;gt;&amp;gt; $GITHUB_STEP_SUMMARY
          echo &quot;&quot; &amp;gt;&amp;gt; $GITHUB_STEP_SUMMARY # this is a blank line
          echo &quot;- Lets add a bullet point&quot; &amp;gt;&amp;gt; $GITHUB_STEP_SUMMARY
          echo &quot;- Lets add a second bullet point&quot; &amp;gt;&amp;gt; $GITHUB_STEP_SUMMARY
          echo &quot;- How about a third one?&quot; &amp;gt;&amp;gt; $GITHUB_STEP_SUMMARY&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이 경우에는 아래처럼 구분된 상태로 출력된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;337&quot; data-origin-height=&quot;742&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/GzAoG/dJMcaibj5uG/ELYr9X7cQiN9FDVlfkkIa0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/GzAoG/dJMcaibj5uG/ELYr9X7cQiN9FDVlfkkIa0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/GzAoG/dJMcaibj5uG/ELYr9X7cQiN9FDVlfkkIa0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGzAoG%2FdJMcaibj5uG%2FELYr9X7cQiN9FDVlfkkIa0%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;337&quot; height=&quot;742&quot; data-origin-width=&quot;337&quot; data-origin-height=&quot;742&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 시작--&gt;&lt;/p&gt;
&lt;h4 style=&quot;font-size: 10px; color: #1f1f1f; border-left: #ff327f 10px solid; margin: 0px 0px 10px; letter-spacing: -1px; line-height: normal; font-stretch: normal; padding: 0px 0px 0px 7px;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-size: 21px; color: #ff327f;&quot;&gt; 참고 문서&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.github.com/ko/actions/reference/workflows-and-actions/workflow-commands&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.github.com/ko/actions/reference/workflows-and-actions/workflow-commands&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://blog.outsider.ne.kr/1594&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://blog.outsider.ne.kr/1594&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Git | GitLab</category>
      <category>github</category>
      <author>비번변경</author>
      <guid isPermaLink="true">https://passwd.tistory.com/1491</guid>
      <comments>https://passwd.tistory.com/entry/GitHub-GitHub-Actions-GITHUBSTEPSUMMARY#entry1491comment</comments>
      <pubDate>Tue, 3 Mar 2026 11:22:51 +0900</pubDate>
    </item>
    <item>
      <title>[Github] GitHub Actions - 수동 트리거 및 입력</title>
      <link>https://passwd.tistory.com/entry/Github-GitHub-Actions-%EC%88%98%EB%8F%99-%ED%8A%B8%EB%A6%AC%EA%B1%B0-%EB%B0%8F-%EC%9E%85%EB%A0%A5</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size23&quot;&gt;개요&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;최근 GitHub Actions에 대한 기본 개념과 사용법에 대해서 간단히 알아보고 있는데, 주로 레포지터리에 push 이벤트가 발생했을 때 자동으로 트리거 되는 워크플로우를 다뤘다. 하지만 때로는 수동으로도 워크플로우를 트리거해야 하는 경우가 발생하곤 한다. 때문에 이번 글에서는 수동 트리거에 대해서 조금 정리해보려고 한다.&lt;/p&gt;
&lt;p style=&quot;float: none; clear: none;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt; &lt;span style=&quot;font-size: 21px;&quot;&gt;이벤트&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://passwd.tistory.com/entry/GitHub-GitHub-Actions-%EB%B3%80%EC%88%98&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;2026.02.05-[GitHub] GitHub Actions - 변수&lt;/a&gt;에서 지나가듯이 언급했는데, 워크플로우를 수동으로 트리거 하고 싶을 때는 on 키워드에 workflow_dispatch를 지정한다.&lt;/p&gt;
&lt;pre id=&quot;code_1771807417722&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;on: workflow_dispatch&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;트리거 이벤트로 workflow_dispatch를 지정하면 워크플로우를 트리거할 수 있도록 버튼이 제공된다. 이때 어떤 브랜치를 사용할 건지 선택할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;937&quot; data-origin-height=&quot;391&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sOY9r/dJMcabJ1Tc9/YpkmXk7zLkiV7b14zkF8v1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sOY9r/dJMcabJ1Tc9/YpkmXk7zLkiV7b14zkF8v1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sOY9r/dJMcabJ1Tc9/YpkmXk7zLkiV7b14zkF8v1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsOY9r%2FdJMcabJ1Tc9%2FYpkmXk7zLkiV7b14zkF8v1%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;937&quot; height=&quot;391&quot; data-origin-width=&quot;937&quot; data-origin-height=&quot;391&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1771808139011&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;on: [push, workflow_dispatch]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;push 이벤트와 함께 지정해 수동, 자동 혼용하는 것도 가능하다.&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;!--부제목사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt; &lt;span style=&quot;font-size: 21px;&quot;&gt;입력 제공&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;워크플로우를 수동으로 트리거할 때는 inputs를 통해 별도의 입력을 제공할 수 있다. 데이터 타입은 boolean, choice(selectBox), number, string, environment이다. 아래 예시는 tags라는 boolean 입력을 제공받도록 구성한 코드이다. 입력에는 설명, 필수 여부, 기본값 등을 함께 지정할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1771808313852&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;on:
  workflow_dispatch:
    inputs:
      tags:
        description: 'Test scenario tags'
        required: false
        type: boolean&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;예시&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;예시로 아래와 같은 코드로 github actions을 구성하자. 예시는 choice 형식의 logLevel, boolean 형식의 tags를 입력받아 step 내 환경 변수로 세팅하고 출력하는 코드이다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1771808469930&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;on:
  workflow_dispatch:
    inputs:
      logLevel:
        description: 'Log level'
        required: true
        default: 'warning'
        type: choice
        options:
        - info
        - warning
        - debug
      tags:
        description: 'Test scenario tags'
        required: false
        type: boolean
jobs:
  log-the-inputs:
    runs-on: ubuntu-latest
    steps:
      - run: |
          echo &quot;Log level: $LEVEL&quot;
          echo &quot;Tags: $TAGS&quot;
        env:
          LEVEL: ${{ inputs.logLevel }}
          TAGS: ${{ inputs.tags }}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;커밋 후 트리거를 시도하면 아래처럼 입력을 설정할 수 있도록 폼이 제공된다. 필수값 여부는 빨간 별로 구분하고, description으로 설정한 값이 표시되는 것으로 보인다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;337&quot; data-origin-height=&quot;342&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oJnaU/dJMcachQMG6/iUmaIvRQMf4G3KiUILCYk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oJnaU/dJMcachQMG6/iUmaIvRQMf4G3KiUILCYk0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oJnaU/dJMcachQMG6/iUmaIvRQMf4G3KiUILCYk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoJnaU%2FdJMcachQMG6%2FiUmaIvRQMf4G3KiUILCYk0%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;337&quot; height=&quot;342&quot; data-origin-width=&quot;337&quot; data-origin-height=&quot;342&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;원하는 값으로 설정 후 Run workflow 버튼을 누르면 설정한 값이 정상적으로 로드되어 출력되는 모습을 확인할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;680&quot; data-origin-height=&quot;506&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bXZ4Jh/dJMcaa5oN9V/AkfESDiJjkcswi6GN0p1ck/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bXZ4Jh/dJMcaa5oN9V/AkfESDiJjkcswi6GN0p1ck/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bXZ4Jh/dJMcaa5oN9V/AkfESDiJjkcswi6GN0p1ck/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbXZ4Jh%2FdJMcaa5oN9V%2FAkfESDiJjkcswi6GN0p1ck%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;680&quot; height=&quot;506&quot; data-origin-width=&quot;680&quot; data-origin-height=&quot;506&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 시작--&gt;&lt;/p&gt;
&lt;h4 style=&quot;font-size: 10px; color: #1f1f1f; border-left: #ff327f 10px solid; margin: 0px 0px 10px; letter-spacing: -1px; line-height: normal; font-stretch: normal; padding: 0px 0px 0px 7px;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-size: 21px; color: #ff327f;&quot;&gt; 참고 문서&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://deku.posstree.com/ko/github_actions/execute-github-actions-manually/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://deku.posstree.com/ko/github_actions/execute-github-actions-manually/&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.github.com/ko/enterprise-cloud@latest/actions/reference/workflows-and-actions/events-that-trigger-workflows#workflow_dispatch&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.github.com/ko/enterprise-cloud@latest/actions/reference/workflows-and-actions/events-that-trigger-workflows#workflow_dispatch&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.github.com/ko/enterprise-cloud@latest/actions/how-tos/manage-workflow-runs/manually-run-a-workflow&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.github.com/ko/enterprise-cloud@latest/actions/how-tos/manage-workflow-runs/manually-run-a-workflow&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Git | GitLab</category>
      <category>github</category>
      <author>비번변경</author>
      <guid isPermaLink="true">https://passwd.tistory.com/1490</guid>
      <comments>https://passwd.tistory.com/entry/Github-GitHub-Actions-%EC%88%98%EB%8F%99-%ED%8A%B8%EB%A6%AC%EA%B1%B0-%EB%B0%8F-%EC%9E%85%EB%A0%A5#entry1490comment</comments>
      <pubDate>Fri, 27 Feb 2026 10:43:54 +0900</pubDate>
    </item>
    <item>
      <title>[GitHub] GitHub Actions - Job/Step 간 데이터 전달</title>
      <link>https://passwd.tistory.com/entry/GitHub-GitHub-Actions-JobStep-%EA%B0%84-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%A0%84%EB%8B%AC</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size23&quot;&gt;개요&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;CI/CD 파이프라인을 생성하다 보면 설정 파일 등을 읽어 들여서 여러 Job, 여러 Step에서 사용하도록 구성하게 되는데 이때 필수적인 기능이 데이터 전달이다. 이번 글에서는 Step, Job 수준에서의 데이터 전달 방식에 대해서 정리해 둔다.&lt;/p&gt;
&lt;p style=&quot;float: none; clear: none;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;GITHUB_OUTPUT&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Github Actions 내에서 발생한 출력은 GITHUB_OUTPUT이라는 환경 파일에 저장해 두었다가 접근하여 사용할 수 있다. 저장할 때는 접근할 때 사용할 키를 함께 지정해주어야 한다.&lt;/p&gt;
&lt;pre id=&quot;code_1771459856927&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;echo &quot;{name}={value}&quot; &amp;gt;&amp;gt; &quot;$GITHUB_OUTPUT&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;참조할 때는 &quot;steps.STEP_ID.outputs.KEY&quot; 형식으로 접근한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;아래 예시는 SELECTED_COLOR를 설정하고 이후에 접근하는 모습을 보여준다.&lt;/p&gt;
&lt;pre id=&quot;code_1771460139388&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;      - name: Set color
        id: color-selector
        run: echo &quot;SELECTED_COLOR=green&quot; &amp;gt;&amp;gt; &quot;$GITHUB_OUTPUT&quot;
      - name: Get color
        env:
          SELECTED_COLOR: ${{ steps.color-selector.outputs.SELECTED_COLOR }}
        run: echo &quot;The selected color is $SELECTED_COLOR&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;789&quot; data-origin-height=&quot;318&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bS389v/dJMcahpRINT/gLUnMvua8oLEUMQQa5kIP0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bS389v/dJMcahpRINT/gLUnMvua8oLEUMQQa5kIP0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bS389v/dJMcahpRINT/gLUnMvua8oLEUMQQa5kIP0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbS389v%2FdJMcahpRINT%2FgLUnMvua8oLEUMQQa5kIP0%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;789&quot; height=&quot;318&quot; data-origin-width=&quot;789&quot; data-origin-height=&quot;318&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;기본적으로 하나의 job은 하나의 실행기 내에서 동작하므로 step 간 데이터는 별다른 설정 없이 GITHUB_OUTPUT을 통해 주고받을 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt; &lt;span style=&quot;font-size: 21px;&quot;&gt;Job 간 데이터 전달&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;반면 Job 간 데이터 전달은 Job 수준에서 output을 명시적으로 지정해주어야 한다. 이때 jobs.JOB_ID.output을 통해 어느 step의 출력을 내보낼 것인지 정의한다.&lt;/p&gt;
&lt;pre id=&quot;code_1771460797108&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;jobs:
  job1:
    runs-on: ubuntu-latest
    outputs:
      output1: ${{ steps.step1.outputs.test }}
      output2: ${{ steps.step2.outputs.test }}
    steps:
      - id: step1
        run: echo &quot;test=hello&quot; &amp;gt;&amp;gt; &quot;$GITHUB_OUTPUT&quot;
      - id: step2
        run: echo &quot;test=world&quot; &amp;gt;&amp;gt; &quot;$GITHUB_OUTPUT&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이후 이 job에서 생성된 출력을 활용할 job은 jobs.JOB_ID.needs 구문을 사용해 Job 의존성을 설정하고, needs.JOB_ID.outputs.KEY 형식으로 output에 접근한다.&lt;/p&gt;
&lt;pre class=&quot;bash&quot; style=&quot;background-color: #f6f8fa; color: #1f2328; text-align: start;&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;jobs:
  # Assume job1 is defined as above
  job2:
    runs-on: ubuntu-latest
    needs: job1
    steps:
      - env:
          OUTPUT1: ${{needs.job1.outputs.output1}}
          OUTPUT2: ${{needs.job1.outputs.output2}}
        run: echo &quot;$OUTPUT1 $OUTPUT2&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;두 Job을 그림으로보면 아래와 같은 구조가 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;640&quot; data-origin-height=&quot;271&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/caAV55/dJMcahKbkTE/jmB6WTqyRk7t8gcHHV53cK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/caAV55/dJMcahKbkTE/jmB6WTqyRk7t8gcHHV53cK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/caAV55/dJMcahKbkTE/jmB6WTqyRk7t8gcHHV53cK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcaAV55%2FdJMcahKbkTE%2FjmB6WTqyRk7t8gcHHV53cK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;640&quot; height=&quot;271&quot; data-origin-width=&quot;640&quot; data-origin-height=&quot;271&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;실제로 동작시킨 결과를 보면 job1에서 설정한 output을 job2에서 읽어 들여 사용하고 있는 것을 확인할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;704&quot; data-origin-height=&quot;394&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bzsHPb/dJMcacIR9gT/4KQ0H263MELS9DV2XmLaO1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bzsHPb/dJMcacIR9gT/4KQ0H263MELS9DV2XmLaO1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bzsHPb/dJMcacIR9gT/4KQ0H263MELS9DV2XmLaO1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbzsHPb%2FdJMcacIR9gT%2F4KQ0H263MELS9DV2XmLaO1%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;704&quot; height=&quot;394&quot; data-origin-width=&quot;704&quot; data-origin-height=&quot;394&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 시작--&gt;&lt;/p&gt;
&lt;h4 style=&quot;font-size: 10px; color: #1f1f1f; border-left: #ff327f 10px solid; margin: 0px 0px 10px; letter-spacing: -1px; line-height: normal; font-stretch: normal; padding: 0px 0px 0px 7px;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-size: 21px; color: #ff327f;&quot;&gt; 참고 문서&lt;/span&gt;&lt;span style=&quot;font-size: 21px; color: #ff327f;&quot;&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.github.com/ko/actions/how-tos/write-workflows/choose-what-workflows-do/pass-job-outputs&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.github.com/ko/actions/how-tos/write-workflows/choose-what-workflows-do/pass-job-outputs&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.github.com/ko/actions/reference/workflows-and-actions/workflow-commands&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.github.com/ko/actions/reference/workflows-and-actions/workflow-commands&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Git | GitLab</category>
      <category>github</category>
      <author>비번변경</author>
      <guid isPermaLink="true">https://passwd.tistory.com/1489</guid>
      <comments>https://passwd.tistory.com/entry/GitHub-GitHub-Actions-JobStep-%EA%B0%84-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%A0%84%EB%8B%AC#entry1489comment</comments>
      <pubDate>Thu, 26 Feb 2026 10:19:37 +0900</pubDate>
    </item>
    <item>
      <title>[Terraform] Error: failed to get shared config profile, default 해결</title>
      <link>https://passwd.tistory.com/entry/Terraform-Error-failed-to-get-shared-config-profile-default-%ED%95%B4%EA%B2%B0</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size23&quot;&gt;개요&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Github Actions 내에서 Terraform 실행 환경을 구성하고 있는데, terraform init 명령어 실행 중 아래와 같은 오류가 발생하면서 동작에 실패했다.&lt;/p&gt;
&lt;pre id=&quot;code_1770856574466&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;| - karpenter in .terraform/modules/karpenter/modules/karpenter
| ╷
| │ Error: failed to get shared config profile, default
| │
| │
| ╵&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;원인을 파악하고 문제를 해결해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt; &lt;span style=&quot;font-size: 21px;&quot;&gt;원인&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이 테라폼 코드는 AWS를 대상으로 작업을 수행하는데, 인증 시 default라는 profile을 사용하도록 지정해 둔 상태이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;그리고 로그를 보면 default 프로파일을 얻으려는 시도가 실패했음을 알리고 있다. GitHub Actions 워크플로우를 구성하면서 AWS 인증을 할 때 configure-aws-credentials 액션을 사용하도록 구성했는데, 이 액션은 명시적으로 default 프로파일을 생성하지 않고, 환경 변수를 설정하는 걸로 추측된다.&lt;/p&gt;
&lt;pre id=&quot;code_1770856882862&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;    - name: Configure AWS Credentials
      uses: aws-actions/configure-aws-credentials@v6.0.0
      with:
        aws-region: us-east-2
        role-to-assume: arn:aws:iam::123456789100:role/my-github-actions-role
        role-session-name: MySessionName&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, GitHub Action 실행 환경 내에 사용하고자 하는 AWS default 프로파일이 없어서 발생한 문제이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt; &lt;span style=&quot;font-size: 21px;&quot;&gt;해결&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;가장 간단한 해결 방법은 Terraform 코드 내에서 사용하도록 지정한 AWS 프로파일 설정을 제거하는 것이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;하지만 코드 수정이 여의치 않다면 명령어 수행 시 Terraform을 덮어씌우는 방법이 해결책이 될 수 있다. 이 글의 경우에는 terraform init을 수행할 때 오류가 발생했고, 오류가 발생한 원인은 아래 Terraform 코드이다.&lt;/p&gt;
&lt;pre id=&quot;code_1770858842076&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;terraform {
  backend &quot;s3&quot; {
    bucket         = &quot;sparrow-dw-tfstate&quot;
    region         = &quot;ap-northeast-2&quot;
    key            = &quot;tfstate/terraform.tfstate&quot;
    profile        = &quot;default&quot;
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;코드는 Terraform의 실행 결과 파일인 .tfstate를 AWS S3 버킷에 저장하도록 구성한 건데 default 프로파일을 사용하도록 지정되어 있다. 이 설정을 덮어쓸 때는 아래와 같이 -backend-config 옵션을 사용할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1770859111039&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;terraform init -backend-config=&quot;profile=&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이 글의 경우에는 profile 설정을 제거해야 하므로 값을 지정하지 않도록 하면 된다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 시작--&gt;&lt;/p&gt;
&lt;h4 style=&quot;font-size: 10px; color: #1f1f1f; border-left: #ff327f 10px solid; margin: 0px 0px 10px; letter-spacing: -1px; line-height: normal; font-stretch: normal; padding: 0px 0px 0px 7px;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #ff327f;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;참고 문서&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/aws-actions/configure-aws-credentials&quot;&gt;https://github.com/aws-actions/configure-aws-credentials&lt;/a&gt; &lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://developer.hashicorp.com/terraform/cli/commands/init&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://developer.hashicorp.com/terraform/cli/commands/init&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Terraform</category>
      <category>terraform</category>
      <author>비번변경</author>
      <guid isPermaLink="true">https://passwd.tistory.com/1488</guid>
      <comments>https://passwd.tistory.com/entry/Terraform-Error-failed-to-get-shared-config-profile-default-%ED%95%B4%EA%B2%B0#entry1488comment</comments>
      <pubDate>Wed, 25 Feb 2026 11:24:33 +0900</pubDate>
    </item>
    <item>
      <title>[Java] Stream - 사용법</title>
      <link>https://passwd.tistory.com/entry/Java-Stream-%EC%82%AC%EC%9A%A9%EB%B2%95</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size23&quot;&gt;개요&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://passwd.tistory.com/entry/Java-Stream-%EA%B0%9C%EB%85%90&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;2026.02.10-[Java] Stream 개념&lt;/a&gt;에서 Java의 Stream 개념에 대해 알아보았다. 이번 글에서는 실제로 어떻게 사용하는지에 초점을 맞춰서 내용을 정리해 본다.&lt;/p&gt;
&lt;p style=&quot;float: none; clear: none;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;생성&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Stream은 데이터 집합인 컬렉션, 다시 말해 Array, List, Set, Map 등으로부터 생성할 수 있다. 컬렉션이 제공하는 stream 메서드를 사용해 Stream을 생성한다.&lt;/p&gt;
&lt;pre id=&quot;code_1770769621750&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;List&amp;lt;String&amp;gt; list = new ArrayList&amp;lt;&amp;gt;();
list.add(&quot;Apple&quot;);
list.add(&quot;Banana&quot;);
list.add(&quot;Kiwi&quot;);

Stream&amp;lt;String&amp;gt; stream = list.stream();&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;또는 Stream에서 제공하는 generate, iterate 메서드 등을 사용해서 생성하는 것도 가능한다. generate는 무한한 값을 생성할 때, iterate는 이전 요소의 의존해서 다음 요소를 생성할 때 사용할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1770770527962&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// Hello 문자열이 5개인 스트림
Stream&amp;lt;String&amp;gt; stream1 = Stream.generate(() -&amp;gt; &quot;Hello&quot;).limit(5);

// 원소가 1부터 2배씩 커지되 값이 10 미만까지인 스트림
Stream&amp;lt;Integer&amp;gt; stream2 = Stream.iterate(1, n -&amp;gt; n &amp;lt; 10, n -&amp;gt; n * 2);&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;가공&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;데이터를 가공하는 역할로 filter, map, sorted, peek, dicstinct, limit 등이 존재한다.&lt;/p&gt;
&lt;pre id=&quot;code_1770771496996&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 필터링
integerStream.filter(n -&amp;gt; n % 2 == 0);

// map 변환
integerStream.map(n -&amp;gt; n * n);

// 정렬
integerStream.sorted();

// 중간 처리 값 확인(디버깅에 유용)
integerStream.sorted().peek(n -&amp;gt; System.out.println(n));

// 중복 제거
integerStream.map(n -&amp;gt; n % 3).distinct();&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;소비&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;결과를 생성하기 위한 최종 연산 과정이다. 일반적으로 데이터의 합계, 평균을 구하거나 다른 데이터 컬렉션 등으로 변환하는 처리가 이루어진다. 대표적인 소비 연산은 다음과 같다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 292px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style8&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 16.938%; height: 17px;&quot;&gt;메서드&lt;/td&gt;
&lt;td style=&quot;width: 13.217%; height: 17px;&quot;&gt;유형&lt;/td&gt;
&lt;td style=&quot;width: 69.8449%; height: 17px;&quot;&gt;설명&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 42px;&quot;&gt;
&lt;td style=&quot;width: 16.938%; height: 42px;&quot;&gt;&lt;span style=&quot;color: #333333; text-align: left;&quot;&gt;forEach&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 13.217%; height: 42px;&quot;&gt;출력&lt;/td&gt;
&lt;td style=&quot;width: 69.8449%; height: 42px;&quot;&gt;각 요소를 순회하며 출력 등의 처리에 사용한다&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 16.938%; height: 17px;&quot;&gt;&lt;span style=&quot;color: #333333; text-align: left;&quot;&gt;reduce&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 13.217%; height: 17px;&quot;&gt;소모&lt;/td&gt;
&lt;td style=&quot;width: 69.8449%; height: 17px;&quot;&gt;&lt;span&gt;Stream의 요소를 줄여나가면서 연산을 수행한다. 처음 두 요소를 가지고 연산환 결과로 다음 요소와 연산하여 최종 결과값을 구한다.&lt;/span&gt;&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 16.938%; height: 17px;&quot;&gt;findFirst&lt;/td&gt;
&lt;td style=&quot;width: 13.217%; height: 17px;&quot;&gt;검색&lt;/td&gt;
&lt;td style=&quot;width: 69.8449%; height: 17px;&quot;&gt;특정 조건에 맞는 요소 검색. 시퀀셜 처리&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 16.938%; height: 17px;&quot;&gt;&lt;span style=&quot;color: #333333; text-align: left;&quot;&gt;findAny&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 13.217%; height: 17px;&quot;&gt;검색&lt;/td&gt;
&lt;td style=&quot;width: 69.8449%; height: 17px;&quot;&gt;특정 조건에 맞는 요소 검색. 병렬 처리&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 16.938%; height: 17px;&quot;&gt;anyMatch&lt;/td&gt;
&lt;td style=&quot;width: 13.217%; height: 17px;&quot;&gt;검사&lt;/td&gt;
&lt;td style=&quot;width: 69.8449%; height: 17px;&quot;&gt;조건 만족 여부 확인&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 16.938%; height: 17px;&quot;&gt;allMatch&lt;/td&gt;
&lt;td style=&quot;width: 13.217%; height: 17px;&quot;&gt;검사&lt;/td&gt;
&lt;td style=&quot;width: 69.8449%; height: 17px;&quot;&gt;조건 만족 여부 확인&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 16.938%; height: 17px;&quot;&gt;&lt;span style=&quot;color: #333333; text-align: left;&quot;&gt;noneMatch&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 13.217%; height: 17px;&quot;&gt;검사&lt;/td&gt;
&lt;td style=&quot;width: 69.8449%; height: 17px;&quot;&gt;조건 만족 여부 확인&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 16.938%; height: 17px;&quot;&gt;&lt;span style=&quot;color: #333333; text-align: left;&quot;&gt; count &lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 13.217%; height: 17px;&quot;&gt;통계&lt;/td&gt;
&lt;td style=&quot;width: 69.8449%; height: 17px;&quot;&gt;개수&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 16.938%; height: 17px;&quot;&gt;&lt;span style=&quot;color: #333333; text-align: left;&quot;&gt; min &lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 13.217%; height: 17px;&quot;&gt;통계&lt;/td&gt;
&lt;td style=&quot;width: 69.8449%; height: 17px;&quot;&gt;최소값&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 16.938%; height: 17px;&quot;&gt;&lt;span style=&quot;color: #333333; text-align: left;&quot;&gt;max&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 13.217%; height: 17px;&quot;&gt;통계&lt;/td&gt;
&lt;td style=&quot;width: 69.8449%; height: 17px;&quot;&gt;최대값&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;width: 16.938%; height: 21px;&quot;&gt;&lt;span style=&quot;color: #333333; text-align: left;&quot;&gt;sum&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 13.217%; height: 21px;&quot;&gt;연산&lt;/td&gt;
&lt;td style=&quot;width: 69.8449%; height: 21px;&quot;&gt;합계&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;width: 16.938%; height: 21px;&quot;&gt;&lt;span style=&quot;color: #333333; text-align: left;&quot;&gt;average&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 13.217%; height: 21px;&quot;&gt;연산&lt;/td&gt;
&lt;td style=&quot;width: 69.8449%; height: 21px;&quot;&gt;평균&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;width: 16.938%; height: 21px;&quot;&gt;collect&lt;/td&gt;
&lt;td style=&quot;width: 13.217%; height: 21px;&quot;&gt;수집&lt;/td&gt;
&lt;td style=&quot;width: 69.8449%; height: 21px;&quot;&gt;Stream 요소를 수집해 원하는 형태로 변환. Collector 인터페이스를 매개변수로 호출하며 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;Collectors 클래스에서 기정의한 메서드를 사용한다.&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;최종 연산 수행 후에는 더 이상 Stream으로 처리할 수 없다. 즉, 다시 데이터를 처리하기 위해서는 Stream을 새로 생성해야 한다.&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 시작--&gt;&lt;/p&gt;
&lt;h4 style=&quot;font-size: 10px; color: #1f1f1f; border-left: #ff327f 10px solid; margin: 0px 0px 10px; letter-spacing: -1px; line-height: normal; font-stretch: normal; padding: 0px 0px 0px 7px;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-size: 21px; color: #ff327f;&quot;&gt; 참고 문서&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.elancer.co.kr/blog/detail/255&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.elancer.co.kr/blog/detail/255&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.daleseo.com/java9-stream-iterate/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.daleseo.com/java9-stream-iterate/&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Java</category>
      <category>Java</category>
      <author>비번변경</author>
      <guid isPermaLink="true">https://passwd.tistory.com/1487</guid>
      <comments>https://passwd.tistory.com/entry/Java-Stream-%EC%82%AC%EC%9A%A9%EB%B2%95#entry1487comment</comments>
      <pubDate>Tue, 24 Feb 2026 10:43:04 +0900</pubDate>
    </item>
    <item>
      <title>[Java] Stream 개념</title>
      <link>https://passwd.tistory.com/entry/Java-Stream-%EA%B0%9C%EB%85%90</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size23&quot;&gt;개요&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;최근 기본적인 반복문과 조건문을 활용한 Java 코드를 AI에게 개선해달라 요청했더니 Stream이라는 개념을 가진 코드를 제안해주었다. 사용하고 유지보수를 하기 위해서는 관련 개념을 이해하고 있어야 할 것 같아 정리해보려고 한다.&lt;/p&gt;
&lt;p style=&quot;float: none; clear: none;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;Stream&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;프로그래밍 개발에서 Stream이란 '일련의 데이터 흐름'을 의미한다. 위키피디아의 경우에는 시간 상에 나타나는 일련의 데이터 요소로 정의하며 연속적인 데이터 흐름에 초점을 맞추고 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Java의 Stream은 이러한 데이터 흐름을 표준화된 방법으로 쉽게 처리할 수 있도록 지원하는 클래스 집합이다. 경우에 따라, 요소의 Stream에 함수형 연산을 지원하는 클래스라 정의하기도 한다. 다시 말해 Java Stream을 이용하여 데이터를 함수형 연산을 통해 표준화된 방법으로 쉽게 가공하고 처리할 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt; &lt;span style=&quot;font-size: 21px;&quot;&gt;장점&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;가독성&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Java Stream을 활용하면 명령형 방식이 아닌 선언적 방식으로 프로그래밍이 가능하고, 체이닝을 활용해 필터링, 매핑 정렬을 연속적으로 수행할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1770687673084&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 기존 방식
List&amp;lt;String&amp;gt; result = new ArrayList&amp;lt;&amp;gt;();
for (String userNumber : userNumbers) {
    if (userNumber.equals(targetNumber)) {
        result.add(userNumber);
    }
}

// Stream
userNumbers.stream()
           .filter(userNumber -&amp;gt; userNumber.equals(targetNumber))
           .collect(Collectors.toList());&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;예시 코드의 경우에는 코드 자체가 간략해서 크게 차이가 없지만 보다 복잡한 논리가 들어가게되면 많은 차이가 발생하게 된다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;유지보수성&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;복잡한 반복문과 조건문을 필연적으로 불필요하게 긴 코드를 유발하는데, 이로 인해 가독성이 현저하게 떨어지게 된다. Java Stream의 경우에는 같은 작업도 보다 간결하고 명확하게 표현할 수 있어 가독성을 확보하고 자연스럽게 유지보수성을 향상시킨다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;병렬 처리&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터 흐름을 나눠 멀티 스레드로 병렬로 처리하고 처리 후 합치는 과정을 통해 대량의 데이터를 좀더 빠르게 처리할 수 있다. Java Stream의 경우 parallel, parallelStream이라는 연산을 추가하는 것만으로 병렬처리를 가능하게 한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;구조와 특징&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Java Stream은 데이터 처리 과정과 동일하게 '생성 -&amp;gt; 가공 -&amp;gt; 소비'의 구조로 이루어져 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;624&quot; data-origin-height=&quot;348&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uubdF/dJMcahQRqxE/IU4kILkpRPcmwgB49o2NJk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uubdF/dJMcahQRqxE/IU4kILkpRPcmwgB49o2NJk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uubdF/dJMcahQRqxE/IU4kILkpRPcmwgB49o2NJk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuubdF%2FdJMcahQRqxE%2FIU4kILkpRPcmwgB49o2NJk%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;624&quot; height=&quot;348&quot; data-origin-width=&quot;624&quot; data-origin-height=&quot;348&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;생성&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;데이터 컬렉션을 Stream으로 변환하는 과정을 통해 데이터 스트림을 생성하는 것을 의미한다. Stream을 사용해 가공하기 위해서 수행된다. 모든 데이터가 한 번에 메모리에 로드되지 않고 필요할 때만 로드하기 때문에 효율적인 메모리 사용이 가능하다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;가공&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터 집합을 원하는 형태로 가공하는 중간 처리를 뜻하는데 필터링, 변형, 정렬 등이 해당된다. 중간 연산은 입력도 Stream이고 수행 결과도 Stream이라는 특징이 있다. 이 특징을 활용해 중간 연산을 연결함으로써 연속해서 수행할 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;소비&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Stream에 대한 최종 연산을 통해 최종 목적물을 얻는 처리 과정을 의미하다. 수행 후 데이터 컬렉션이나 하나의 값을 얻을 수 있다. 결과값을 얻기 위한 1회 수행되고, 이후 Stream은 닫히게 된다. 데이터에 대한 추가 가공이 필요한 경우에느 신규 Stream을 생성하여야 한다. 즉, Stream을 일회성으로 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Stream 처리는 모든 데이터에 대해 한 함수 실행이 끝나고 다른 함수가 수행되는 것이 아니라, 데이터가 나타난 흐름 순서대로 처리된다. 다시 말해 앞선 데이터가 먼저 처리되고 뒤의 데이터가 나중에 처리된다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 시작--&gt;&lt;/p&gt;
&lt;h4 style=&quot;font-size: 10px; color: #1f1f1f; border-left: #ff327f 10px solid; margin: 0px 0px 10px; letter-spacing: -1px; line-height: normal; font-stretch: normal; padding: 0px 0px 0px 7px;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #ff327f;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;참고 문서&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.elancer.co.kr/blog/detail/255&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.elancer.co.kr/blog/detail/255&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Java</category>
      <category>Java</category>
      <author>비번변경</author>
      <guid isPermaLink="true">https://passwd.tistory.com/1486</guid>
      <comments>https://passwd.tistory.com/entry/Java-Stream-%EA%B0%9C%EB%85%90#entry1486comment</comments>
      <pubDate>Mon, 23 Feb 2026 10:19:22 +0900</pubDate>
    </item>
    <item>
      <title>[Java] HashSet</title>
      <link>https://passwd.tistory.com/entry/Java-HashSet-1</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size23&quot;&gt;개요&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://passwd.tistory.com/entry/Java-HashMap&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;2026.02.06-[Java] HashMap&lt;/a&gt;에서 HashMap에 대해서 살펴보았는데, 이번 글에서는 Set을 구현한 HashSet에 대해서 살펴본다.&lt;/p&gt;
&lt;p style=&quot;float: none; clear: none;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;HashSet&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이름에서 추측할 수 있듯, HashSet은 Set 인터페이스를 구현한 클래스이다. 객체를 중복 저장할 수 없고 저장 순서를 유지하지 않는다는 Set의 성질을 그대로 이어받는다. 만약 순서를 유지해야 하거나 자동 정렬이 필요한 경우에는 LinkedHashSet, TreeSet과 같은 다른 구현 클래스를 사용하면 된다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Set은 중복을 허용하지 않기 때문에 보통 중복을 제거하기 위해 많이 활용한다. 또한 비선형 구조로 인덱스가 존재하지 않기 때문에 값을 추가하거나 삭제할 때에는 Set에 값이 있는지 확인할 필요가 있기 때문에 List에 비해 다소 느리다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;중복 제거 방법&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;1. 객체를 저장하기 전 객체의 hashCode 메서드를 호출해 해시코드를 얻은 후 저장되어 있는 객체의 해시코드와 비교한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;2. 같은 해시코드가 있다면 equals 메서드로 두 객체를 비교하여 true이면 동일한 객체로 판단하여 저장하지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt; &lt;span style=&quot;font-size: 21px;&quot;&gt;사용법&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;선언&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #555555; text-align: left;&quot;&gt;인자로 키와 값 타입을 전달하며 기본생성자를 호출한다. 저장공간보다 값이 추가로 들어오면 공간을 늘리는데, 두 배씩 늘리기 때문에 저장할 데이터의 개수를 알고 있다면 초기 용량을 지정하는 것이 좋다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1770614513957&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.util.HashSet;

HashSet&amp;lt;Integer&amp;gt; set = new HashSet&amp;lt;Integer&amp;gt;();
HashSet&amp;lt;Integer&amp;gt; set = new HashSet&amp;lt;&amp;gt;();

# 초기 용량 지정
HashSet&amp;lt;Integer&amp;gt; set = new HashSet&amp;lt;Integer&amp;gt;(10);&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;값 추가&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;add 메서드를 사용해 Set에 값을 추가한다. 만약 기존재하는 값을 추가하려고 시도하면 false를 반환한다.&lt;/p&gt;
&lt;pre id=&quot;code_1770614779413&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;set.add(VALUE);&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;값 삭제&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;remove 메서드를 사용해 특정 값을 Set에서 삭제할 수 있다. 만약 없는 값을 삭제하려고 시도하면 false를 반환한다. Set 내 모든 값을 제거할 때는 clear를 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1770616200334&quot; class=&quot;java&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;set.remove(VALUE);

# 비우기
set.clear();&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;522&quot; data-origin-height=&quot;324&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/buVhR2/dJMcabXoLak/8mU8V5TkK7ir3qV2rdEtw1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/buVhR2/dJMcabXoLak/8mU8V5TkK7ir3qV2rdEtw1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/buVhR2/dJMcabXoLak/8mU8V5TkK7ir3qV2rdEtw1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbuVhR2%2FdJMcabXoLak%2F8mU8V5TkK7ir3qV2rdEtw1%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;522&quot; height=&quot;324&quot; data-origin-width=&quot;522&quot; data-origin-height=&quot;324&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;Set 크기&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Set의 크기를 확인할 때는 size 메서드를 사용한다.&lt;/p&gt;
&lt;pre id=&quot;code_1770616692124&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;set.size();&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;536&quot; data-origin-height=&quot;340&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cBeIrl/dJMcagqR2iz/GnYk4jD3JCKv6aRQru8rn1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cBeIrl/dJMcagqR2iz/GnYk4jD3JCKv6aRQru8rn1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cBeIrl/dJMcagqR2iz/GnYk4jD3JCKv6aRQru8rn1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcBeIrl%2FdJMcagqR2iz%2FGnYk4jD3JCKv6aRQru8rn1%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;536&quot; height=&quot;340&quot; data-origin-width=&quot;536&quot; data-origin-height=&quot;340&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;값 존재 여부 확인&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;원하는 값이 Set 내에 존재하는지 확인하고 싶다면 contains 메서드를 사용한다. 존재하면 true를, 그렇지 않다면 false를 반환한다.&lt;/p&gt;
&lt;pre id=&quot;code_1770616837985&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;set.contains(VALUE);&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;528&quot; data-origin-height=&quot;345&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lJXDj/dJMcahi2Wlt/S3aZ4ZyxqHSkPyKhFeHQHK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lJXDj/dJMcahi2Wlt/S3aZ4ZyxqHSkPyKhFeHQHK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lJXDj/dJMcahi2Wlt/S3aZ4ZyxqHSkPyKhFeHQHK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlJXDj%2FdJMcahi2Wlt%2FS3aZ4ZyxqHSkPyKhFeHQHK%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;528&quot; height=&quot;345&quot; data-origin-width=&quot;528&quot; data-origin-height=&quot;345&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;순회&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Set을 순회할 때는 반복자(iterator)를 활용한다. iterator 객체를 생성한 후, hasNext, next 메서드를 사용해 하나씩 값의 존재 여부를 확인하고 값을 가져올 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1770617116971&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;HashSet&amp;lt;Integer&amp;gt; set = new HashSet&amp;lt;&amp;gt;();
Iterator iterator = set.iterator();
while (iterator.hasNext()) {
    System.out.println(iterator.next());
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;528&quot; data-origin-height=&quot;497&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cvbmju/dJMcahwzzLO/GoOrsCiMI1ixc81Vgh9eK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cvbmju/dJMcahwzzLO/GoOrsCiMI1ixc81Vgh9eK0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cvbmju/dJMcahwzzLO/GoOrsCiMI1ixc81Vgh9eK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcvbmju%2FdJMcahwzzLO%2FGoOrsCiMI1ixc81Vgh9eK0%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;528&quot; height=&quot;497&quot; data-origin-width=&quot;528&quot; data-origin-height=&quot;497&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 시작--&gt;&lt;/p&gt;
&lt;h4 style=&quot;font-size: 10px; color: #1f1f1f; border-left: #ff327f 10px solid; margin: 0px 0px 10px; letter-spacing: -1px; line-height: normal; font-stretch: normal; padding: 0px 0px 0px 7px;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #ff327f;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;참고 문서&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://coding-factory.tistory.com/554&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://coding-factory.tistory.com/554&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Java</category>
      <category>Java</category>
      <author>비번변경</author>
      <guid isPermaLink="true">https://passwd.tistory.com/1485</guid>
      <comments>https://passwd.tistory.com/entry/Java-HashSet-1#entry1485comment</comments>
      <pubDate>Fri, 13 Feb 2026 16:01:43 +0900</pubDate>
    </item>
    <item>
      <title>[Java] HashMap</title>
      <link>https://passwd.tistory.com/entry/Java-HashMap</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size23&quot;&gt;개요&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;개발하고 있는 Java 애플리케이션에서 HashMap을 사용하는데, Java를 놓은지 오래 되었다보니 기본 개념만 겨우 기억하고 있다. 개발 진행에 필요한 개념을 다시 돌아보자.&lt;/p&gt;
&lt;p style=&quot;float: none; clear: none;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt; &lt;span style=&quot;font-size: 21px;&quot;&gt;HashMap&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Map 인터페이스를 구현한 대표적인 Map 컬렉션이다. Map 인터페이스를 상속하고 있어 키와 값으로 구성된 Entry 객체를 저장하는 구조라는 Map의 성질를 그대로 갖고 있다. 키와 값은 모두 객체이며, 값은 중복을 허용하지만 키는 허용하지 않는다. 특히 HashMap의 경우에는 Hashing을 사용해 많은 양의 데이터를 검색하는 성능이 뛰어나다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;989&quot; data-origin-height=&quot;379&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bpdIeW/dJMcacBZTwa/unbWYGSsrEcHoXVtBMJSw0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bpdIeW/dJMcacBZTwa/unbWYGSsrEcHoXVtBMJSw0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bpdIeW/dJMcacBZTwa/unbWYGSsrEcHoXVtBMJSw0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbpdIeW%2FdJMcacBZTwa%2FunbWYGSsrEcHoXVtBMJSw0%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;989&quot; height=&quot;379&quot; data-origin-width=&quot;989&quot; data-origin-height=&quot;379&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;내부에 키와 값을 저장하는 자료 구조를 가지며, 해시 함수를 통해 키, 값이 저장되는 위치를 결정하므로 사용자는 그 위치를 알 수 없다. 또한 삽입 순서와 저장 위치와 관련도 없다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;기본 사용법&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;선언&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;인자로 키와 값 타입을 전달하며 기본생성자를 호출한다. 저장공간보다 값이 추가로 들어오면 공간을 늘리는데, 두 배씩 늘리기 때문에 저장할 데이터의 개수를 알고 있다면 초기 용량을 지정하는 것이 좋다.&lt;/p&gt;
&lt;pre id=&quot;code_1770353045334&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.util.HashMap;

HashMap&amp;lt;String,String&amp;gt; map = new HashMap&amp;lt;String,String&amp;gt;();
HashMap&amp;lt;String,String&amp;gt; map = new HashMap&amp;lt;&amp;gt;();

# 초기 용량 지정
HashMap&amp;lt;String,String&amp;gt; map = new HashMap&amp;lt;&amp;gt;(10);&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;값 추가&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;pub 메서드를 사용하여 값을 추가한다. 동일 키에 값을 중복으로 지정하면 새 값으로 갱신된다.&lt;/p&gt;
&lt;pre id=&quot;code_1770353270288&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;map.put(&quot;key&quot;, &quot;value&quot;);&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;550&quot; data-origin-height=&quot;384&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/91ljO/dJMcad1UYpK/OUXUccvi5xcd9ukfya3cK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/91ljO/dJMcad1UYpK/OUXUccvi5xcd9ukfya3cK0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/91ljO/dJMcad1UYpK/OUXUccvi5xcd9ukfya3cK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F91ljO%2FdJMcad1UYpK%2FOUXUccvi5xcd9ukfya3cK0%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;550&quot; height=&quot;384&quot; data-origin-width=&quot;550&quot; data-origin-height=&quot;384&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;값 삭제&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;값을 삭제할 때는 remove 함수를 사용한다. 모든 값을 삭제할 때는 clear를 사용한다.&lt;/p&gt;
&lt;pre id=&quot;code_1770353820832&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;map.remove(&quot;key&quot;);

# 모든 값 삭제
map.clear();&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; 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;676&quot; data-origin-height=&quot;380&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cgsopB/dJMcagLaX7t/aUTHrk9ouNSkoBONIBGC1K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cgsopB/dJMcagLaX7t/aUTHrk9ouNSkoBONIBGC1K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cgsopB/dJMcagLaX7t/aUTHrk9ouNSkoBONIBGC1K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcgsopB%2FdJMcagLaX7t%2FaUTHrk9ouNSkoBONIBGC1K%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;676&quot; height=&quot;380&quot; data-origin-width=&quot;676&quot; data-origin-height=&quot;380&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;특정 키의 값 조회&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;지정한 키의 값을 조회할 때는 get을 사용한다.&lt;/p&gt;
&lt;pre id=&quot;code_1770354386256&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;map.get(&quot;key&quot;);&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;537&quot; data-origin-height=&quot;477&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SByBX/dJMcahwydc7/M646LWqHUkrkQYiUyiPP01/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SByBX/dJMcahwydc7/M646LWqHUkrkQYiUyiPP01/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SByBX/dJMcahwydc7/M646LWqHUkrkQYiUyiPP01/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSByBX%2FdJMcahwydc7%2FM646LWqHUkrkQYiUyiPP01%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;537&quot; height=&quot;477&quot; data-origin-width=&quot;537&quot; data-origin-height=&quot;477&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;순회&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;HashMap을 순회할 때는 주로 keySet, entrySet을 사용한다. keySet은 HashMap의 키만 반환받아 사용하는 것이고, entrySet은 키와 값을 한 번에 받는다.&lt;/p&gt;
&lt;pre id=&quot;code_1770355009840&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.util.Map.Entry;

public class Main {
    public static void main(String[] args) {
        HashMap&amp;lt;String, String&amp;gt; map = new HashMap&amp;lt;&amp;gt;();

        map.put(&quot;1&quot;, &quot;사과&quot;); //값 추가
        map.put(&quot;2&quot;, &quot;바나나&quot;);

        for (Entry&amp;lt;String, String&amp;gt; entry : map.entrySet()) {
            System.out.println(entry.getKey() + &quot; : &quot; + entry.getValue());
        }

    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;673&quot; data-origin-height=&quot;462&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nCES4/dJMcagxBD17/yZTE3EvI3Mhhaq7UR0B2HK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nCES4/dJMcagxBD17/yZTE3EvI3Mhhaq7UR0B2HK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nCES4/dJMcagxBD17/yZTE3EvI3Mhhaq7UR0B2HK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnCES4%2FdJMcagxBD17%2FyZTE3EvI3Mhhaq7UR0B2HK%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;673&quot; height=&quot;462&quot; data-origin-width=&quot;673&quot; data-origin-height=&quot;462&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 시작--&gt;&lt;/p&gt;
&lt;h4 style=&quot;font-size: 10px; color: #1f1f1f; border-left: #ff327f 10px solid; margin: 0px 0px 10px; letter-spacing: -1px; line-height: normal; font-stretch: normal; padding: 0px 0px 0px 7px;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-size: 21px; color: #ff327f;&quot;&gt; 참고 문서&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://coding-factory.tistory.com/556&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://coding-factory.tistory.com/556&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.w3schools.com/java/java_hashmap.asp&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.w3schools.com/java/java_hashmap.asp&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://kadosholy.tistory.com/120&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://kadosholy.tistory.com/120&lt;/a&gt;&lt;/p&gt;</description>
      <category>Java</category>
      <category>Java</category>
      <author>비번변경</author>
      <guid isPermaLink="true">https://passwd.tistory.com/1482</guid>
      <comments>https://passwd.tistory.com/entry/Java-HashMap#entry1482comment</comments>
      <pubDate>Thu, 12 Feb 2026 14:57:54 +0900</pubDate>
    </item>
    <item>
      <title>[GitHub] GitHub Actions - on</title>
      <link>https://passwd.tistory.com/entry/GitHub-GitHub-Actions-on</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size23&quot;&gt;개요&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GitHub Actions은 &lt;span style=&quot;color: #555555; text-align: left;&quot;&gt;PR을 만들거나 이슈를 열거나 커밋을 푸시하는 행위가 발생할 때 트리거될 수 있는데, 이 트리거 조건은 on 키워드를 통해 설정할 수 있다. 이번 글에서는 on 키워드를 통해 Github Actions 트리거 조건을 어떻게 설정할 수 있는지 정리해두려고 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;float: none; clear: none;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt; &lt;span style=&quot;font-size: 21px;&quot;&gt;on&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Workflow는 on 키워드를 통해 트리거 이벤트를 정의할 수 있다. 이벤트는 하나 또는 여러 개 정의하거나 스케쥴을 설정할 수 있다. 또는 특정 파일이나 태그, 브랜치에 변경이 있을 때만 실행되도록 제한할 수도 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;단일 이벤트&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1770596125869&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;on: push&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;조건 없이 push로 지정하면 어떤 브랜치든 push가 발생하면 실행하겠다는 의미이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;여러 이벤트&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이벤트를 여럿 지정할 때는 대괄호로 감싼다.&lt;/p&gt;
&lt;pre id=&quot;code_1770596183119&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;on: [push, fork]&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;사용 예시&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; &lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;on.&amp;lt;event_name&amp;gt;.types&lt;/span&gt; &lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;types를 사용하면 트리거 이벤트의 유형을 정의할 수 있다. &lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;예로 들어, issue_comment 이벤트에는 생성, 편집, 삭제 유형이 존재하는데, type을 별도로 지정하지 않고 &lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;issue_comment로만 지정하게 되면, &lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;issue_comment가 생성이 되든 삭제가 되든 &lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;Worflow&lt;/span&gt;가 실행된다. 하지만 type으로 유형을 지정하게 되면 지정한 유형의 이벤트가 발생한 경우에만 Worflow가 실행된다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1770597025881&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;on:
  label:
    types:
      - created&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;필터링&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;일부 이벤트에는 Worflow 실행 시기를 보다 명확하게 지정할 수 있도록 하는 필터가 존재하는데, 바로 push 이벤트의 branches가 대표적인 예시이다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1770597586269&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;on:
  push:
    branches:
      - main
      - 'releases/**'&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;branches 필터를 사용하는 임의 브랜치에 push 이벤트가 발생했을 때가 아니라, 원하는 브랜치에 push 이벤트가 발생했을 때만 workflow가 동작하도록 지정할 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 시작--&gt;&lt;/p&gt;
&lt;h4 style=&quot;font-size: 10px; color: #1f1f1f; border-left: #ff327f 10px solid; margin: 0px 0px 10px; letter-spacing: -1px; line-height: normal; font-stretch: normal; padding: 0px 0px 0px 7px;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-size: 21px; color: #ff327f;&quot;&gt; 참고 문서&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.github.com/ko/actions/how-tos/write-workflows/choose-when-workflows-run/trigger-a-workflow&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.github.com/ko/actions/how-tos/write-workflows/choose-when-workflows-run/trigger-a-workflow&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.github.com/ko/actions/reference/workflows-and-actions/workflow-syntax#on&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.github.com/ko/actions/reference/workflows-and-actions/workflow-syntax#on&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.github.com/ko/actions/reference/workflows-and-actions/events-that-trigger-workflows&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.github.com/ko/actions/reference/workflows-and-actions/events-that-trigger-workflows&lt;/a&gt;&lt;/p&gt;</description>
      <category>Git | GitLab</category>
      <category>github</category>
      <author>비번변경</author>
      <guid isPermaLink="true">https://passwd.tistory.com/1484</guid>
      <comments>https://passwd.tistory.com/entry/GitHub-GitHub-Actions-on#entry1484comment</comments>
      <pubDate>Wed, 11 Feb 2026 10:46:40 +0900</pubDate>
    </item>
    <item>
      <title>[GitHub] GitHub Actions - Context와 Expression</title>
      <link>https://passwd.tistory.com/entry/GitHub-GitHub-Actions-Context%EC%99%80-Expression</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size23&quot;&gt;개요&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://passwd.tistory.com/entry/GitHub-GitHub-Actions-%EB%B3%80%EC%88%98&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;2026.02.05-[GitHub] GitHub Actions - 변수&lt;/a&gt;에서 GitHub Actions 내의 변수에 대해서 알아보았다. 이번 글에서는 관련해서 설명 없이 지나갔던 컨텍스트(&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;Context&lt;/span&gt;) 개념과 식(Expression)에 대해서 정리해 본다.&lt;/p&gt;
&lt;p style=&quot;float: none; clear: none;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt; &lt;span style=&quot;font-size: 21px;&quot;&gt;Contexts&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;GitHub Actions에서 Contexts란 Workflow 실행, 변수, 실행 환경, job, step에 접근하는 방법으로, 문자열 또는 속성을 포함한 객체 일 수 있다. Contexts, 객체, 속성은 실행 조건에 의해 크게 달라지게 되며, 접근할 때는 Expression 구문을 사용한다.&lt;/p&gt;
&lt;pre id=&quot;code_1770336515382&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;${{ &amp;lt;context&amp;gt; }}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;기본 환경 변수와 Context 간&amp;nbsp; 차이점은 존재 범위에 있다. 기본 환경 변수는 작업을 수행하는 실행기에서만 존재하는 반면, Context는 Workflow의 모든 지점에서 사용할 수 있다. 이를 활용에 작업이 실행기로 라우팅 하기 전에 초기 처리를 수행할 수 있다. 아래 코드는 if 키워드와 컨텍스트를 사용해 단계 실행 여부를 결정하는 예시이다.&lt;/p&gt;
&lt;pre id=&quot;code_1770336837140&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;name: CI
on: push
jobs:
  prod-check:
    if: ${{ github.ref == 'refs/heads/main' }}
    runs-on: ubuntu-latest
    steps:
      - run: echo &quot;Deploying to production server on branch $GITHUB_REF&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;사용할 수 있는 컨텍스트는 굉장히 다양하니 아래 링크를 참고하면 좋을 것 같다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;문서: &lt;a href=&quot;https://docs.github.com/en/actions/reference/workflows-and-actions/contexts&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.github.com/en/actions/reference/workflows-and-actions/contexts&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt; &lt;span style=&quot;font-size: 21px;&quot;&gt;Expressions&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Expressions은 Workflow에서 환경 변수를 프로그래밍적으로 설정하고 컨텍스트에 접근하는 방식이다. Expressions 은 문자열, 컨텍스트 참조, 합수 조합일 수 있는데, 일반적으로 워크플로우 파일에서 if 키워드와 함께 사용해 단계 실행 여부를 결정하는 방식으로 활용할 수 있다. Expressions을 사용할 때는 아래와 같은 형식을 통해 문자열로 처리되지 않도록 해야 한다. 예외적으로 if 절에서 식을 사용할 때는 ${{}}을 생략할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1770337561222&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;${{ &amp;lt;expression&amp;gt; }}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 시작--&gt;&lt;/p&gt;
&lt;h4 style=&quot;font-size: 10px; color: #1f1f1f; border-left: #ff327f 10px solid; margin: 0px 0px 10px; letter-spacing: -1px; line-height: normal; font-stretch: normal; padding: 0px 0px 0px 7px;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-size: 21px; color: #ff327f;&quot;&gt; 참고 문서&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.github.com/ko/actions/concepts/workflows-and-actions/contexts&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.github.com/ko/actions/concepts/workflows-and-actions/contexts&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.github.com/ko/actions/concepts/workflows-and-actions/expressions&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.github.com/ko/actions/concepts/workflows-and-actions/expressions&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Git | GitLab</category>
      <category>github</category>
      <author>비번변경</author>
      <guid isPermaLink="true">https://passwd.tistory.com/1481</guid>
      <comments>https://passwd.tistory.com/entry/GitHub-GitHub-Actions-Context%EC%99%80-Expression#entry1481comment</comments>
      <pubDate>Tue, 10 Feb 2026 10:15:58 +0900</pubDate>
    </item>
    <item>
      <title>[GitHub] GitHub Actions - 변수</title>
      <link>https://passwd.tistory.com/entry/GitHub-GitHub-Actions-%EB%B3%80%EC%88%98</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size23&quot;&gt;개요&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://passwd.tistory.com/entry/GitHub-GitHub-Actions-Workflow&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;2026.02.04-[GitHub] GitHub Actions - Workflow&lt;/a&gt;에서 Workflow 자체 대한 개념과 간단한 예시를 살펴보았다. 이번 글에서는 Workflow 내 변수에 대해서 살펴본다.&lt;/p&gt;
&lt;p style=&quot;float: none; clear: none;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt; &lt;span style=&quot;font-size: 21px;&quot;&gt;변수&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;여느 도구와 비슷하게 GitHub Actions에서의 변수도 민감하지 않은 구성 정보를 저장해 재사용하기 위한 방법을 제공한다. 주로 컴파일러 플래그, 사용자 이름, 서버 이름과 같은 데이터를 변수로 저장해 사용하며, Workflow를 실행하는 Runner에서 보간( interpollation)된다. Action, Step에서 실행되는 명령은 변수를 읽고, 생성하고, 갱신할 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;사용자는 사용자 필요에 의해 변수를 만들어서 사용하거나 GitHub 기본 설정 변수를 활용할 수 있다. 사용자 정의 변수는 크게 workflow 정의 파일 내 env 키를 사용하여 만들거나, organization, repository 수준에서 정의할 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;env&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Worflow에서는 크게 최상위, Job, Step 수준에서 환경 변수를 구성하고 사용할 수 있다. 생성할 때는 env 키를 사용한다.&lt;/p&gt;
&lt;pre id=&quot;code_1770254388090&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;env: VALUE&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;참조할 때는 아래와 같이 참조한다.&lt;/p&gt;
&lt;pre id=&quot;code_1770254483413&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 최상위
env.MY_VARIABLE 

# JOB
jobs.&amp;lt;job_id&amp;gt;.env.MY_VARIABLE 

# STEP
jobs.&amp;lt;job_id&amp;gt;.steps[*].env.MY_VARIABLE&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;아래 예시는 각 수준에서 정의한 환경변수를 Step에서 참조하여 출력하는 코드이다.&lt;/p&gt;
&lt;pre id=&quot;code_1770254517430&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;name: Greeting on variable day

on:
  workflow_dispatch # 수동 실행 지정

env:
  DAY_OF_WEEK: Monday

jobs:
  greeting_job:
    runs-on: ubuntu-latest
    env:
      Greeting: Hello
    steps:
      - name: &quot;Say Hello Mona it's Monday&quot;
        run: echo &quot;$Greeting $First_Name. Today is $DAY_OF_WEEK!&quot;
        env:
          First_Name: Mona&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;on 키를 보면 workflow_dispatch로 지정되어 있는데, 이는 수동으로 실행하여 트리거하겠다는 의미이다. 때문에 레포지터리에 파일을 생성하고 트리거하면 아래와 같이 값이 잘 보간 되어 완전한 문자열이 출력되는 모습을 확인할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;827&quot; data-origin-height=&quot;432&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mCmqt/dJMcadU9lVb/iVeErwljQRkiKKwfVKwmc1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mCmqt/dJMcadU9lVb/iVeErwljQRkiKKwfVKwmc1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mCmqt/dJMcadU9lVb/iVeErwljQRkiKKwfVKwmc1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmCmqt%2FdJMcadU9lVb%2FiVeErwljQRkiKKwfVKwmc1%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;827&quot; height=&quot;432&quot; data-origin-width=&quot;827&quot; data-origin-height=&quot;432&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;사용자 정의 변수&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;사용자는 레포지터리 또는 조직 수준에서 기본적인 변수나 환경 변수를 생성하여 사용할 수 있다. 생성 방법은 공식 문서에 잘 안내되어 있어서 따로 적어두진 않겠다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;문서 : &lt;a href=&quot;https://docs.github.com/en/actions/how-tos/write-workflows/choose-what-workflows-do/use-variables#defining-configuration-variables-for-multiple-workflows&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.github.com/en/actions/how-tos/write-workflows/choose-what-workflows-do/use-variables#defining-configuration-variables-for-multiple-workflows&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 유형의 변수는 참조하는 방법이 조금 다른데 아래와 같은 형식으로 참조해야 한다.&lt;/p&gt;
&lt;pre id=&quot;code_1770254764431&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;${{ var.MY_VARIABLE }}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예로 들어 이 글의 경우에는 아래와 같이 TEST_VAR이라는 이름의 변수를 생성했다고 하자.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1445&quot; data-origin-height=&quot;837&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5743J/dJMcabQBnH3/sZcMsk8fhqRhT2O9ChuUx0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5743J/dJMcabQBnH3/sZcMsk8fhqRhT2O9ChuUx0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5743J/dJMcabQBnH3/sZcMsk8fhqRhT2O9ChuUx0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5743J%2FdJMcabQBnH3%2FsZcMsk8fhqRhT2O9ChuUx0%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;1445&quot; height=&quot;837&quot; data-origin-width=&quot;1445&quot; data-origin-height=&quot;837&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;그리고 생성한 변수를 참조하기 위해 Workflow 정의 파일을 아래처럼 수정했다.&lt;/p&gt;
&lt;pre id=&quot;code_1770254834528&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;jobs:
  greeting_job:
    runs-on: ubuntu-latest
    env:
      Greeting: Hello
    steps:
      - name: &quot;Say Hello Mona it's Monday&quot;
        run: echo &quot;$Greeting $First_Name. Today is $DAY_OF_WEEK!&quot;
        env:
          First_Name: ${{ vars.TEST_VAR }} # 수정부&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;트리거해보면 First_Name이 기존과 달라진 모습을 확인할 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; 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;834&quot; data-origin-height=&quot;433&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ciXUCu/dJMb99L0nPH/DZI5ZGwEPerCAHd5TzzWFK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ciXUCu/dJMb99L0nPH/DZI5ZGwEPerCAHd5TzzWFK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ciXUCu/dJMb99L0nPH/DZI5ZGwEPerCAHd5TzzWFK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FciXUCu%2FdJMb99L0nPH%2FDZI5ZGwEPerCAHd5TzzWFK%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;834&quot; height=&quot;433&quot; data-origin-width=&quot;834&quot; data-origin-height=&quot;433&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;GitHub 자체 제공 변수&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GitHub에서 자체적으로 설정하고 제공하는 변수는 아무래도 GitHub 레포지터리와 관련된 정보에 해당한다. 빌드나 배포 작업을 수행하다보면 레포지터리 정보를 참조해야 하는 경우가 왕왕 있는데, 사용할 수 있는 변수는 공식 문서에 나열되어 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문서 : &lt;a href=&quot;https://docs.github.com/ko/actions/reference/workflows-and-actions/variables#default-environment-variables&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.github.com/ko/actions/reference/workflows-and-actions/variables#default-environment-variables&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참조할 때는 아래 형식을 사용한다.&lt;/p&gt;
&lt;pre id=&quot;code_1770255287714&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$GITHUB_NAME

# 또는
${{ github.NAME }}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;테스트를 위해 Workflow 정의 파일을 아래와 같이 수정했다.&lt;/p&gt;
&lt;pre id=&quot;code_1770255389808&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;jobs:
  greeting_job:
    runs-on: ubuntu-latest
    env:
      Greeting: Hello
    steps:
      - name: &quot;Say Hello Mona it's Monday&quot;
        # 수정부
        run: |
          echo &quot;$Greeting $GITHUB_REPOSITORY. Today is $DAY_OF_WEEK!&quot;
          echo &quot;$Greeting ${{ github.repository }}. Today is $DAY_OF_WEEK!&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;참고로 GITHUB_REPOSITORY는 레포지터리의 소유자와 레포지터리 이름을 확인할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;894&quot; data-origin-height=&quot;468&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/o6fRg/dJMcajujb1o/2BMXuLHH6B60sa1AQgnec1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/o6fRg/dJMcajujb1o/2BMXuLHH6B60sa1AQgnec1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/o6fRg/dJMcajujb1o/2BMXuLHH6B60sa1AQgnec1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fo6fRg%2FdJMcajujb1o%2F2BMXuLHH6B60sa1AQgnec1%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;894&quot; height=&quot;468&quot; data-origin-width=&quot;894&quot; data-origin-height=&quot;468&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이번엔 레포지터리 이름으로 잘 출력된 모습을 확인할 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 시작--&gt;&lt;/p&gt;
&lt;h4 style=&quot;font-size: 10px; color: #1f1f1f; border-left: #ff327f 10px solid; margin: 0px 0px 10px; letter-spacing: -1px; line-height: normal; font-stretch: normal; padding: 0px 0px 0px 7px;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #ff327f;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;참고 문서&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.github.com/ko/actions/concepts/workflows-and-actions/variables&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.github.com/ko/actions/concepts/workflows-and-actions/variables&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Git | GitLab</category>
      <category>github</category>
      <author>비번변경</author>
      <guid isPermaLink="true">https://passwd.tistory.com/1480</guid>
      <comments>https://passwd.tistory.com/entry/GitHub-GitHub-Actions-%EB%B3%80%EC%88%98#entry1480comment</comments>
      <pubDate>Mon, 9 Feb 2026 10:52:48 +0900</pubDate>
    </item>
    <item>
      <title>[GitHub] GitHub Actions - Workflow</title>
      <link>https://passwd.tistory.com/entry/GitHub-GitHub-Actions-Workflow</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size23&quot;&gt;개요&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://passwd.tistory.com/entry/GitHub-github-actions-%EA%B0%9C%EB%85%90&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;2026.02.03-[GitHub] github-actions - 개념&lt;/a&gt;에서 GitHub Actions과 관련된 기본적인 개념에 대해서 익혀보았다. 이번 글에서는 Worflow에 초점을 두어서 살펴본다.&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;!--헤드라인 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;Workflow&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Workflow는 하나 이상의 Job을 실행하는 구성 가능하고 자동화된 프로세스이다. 레포지터리 내 .github/workflows 경로에서 YAML 파일 형식으로 정의하며, 이벤트로 트리거 되거나 수동 트리거. 또는 스케쥴링에 의해 트리거 될 수 있다. 하나의 레포지터리는 여러 Workflow을 가질 수 있고, Workflow는 정의에 의해 다양한 작업을 수행할 수 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Pull Request를 빌드하고 테스트한다.&lt;/li&gt;
&lt;li&gt;릴리즈가 생성될 때마다 애플리케이션을 배포한다.&lt;/li&gt;
&lt;li&gt;새 문제가 보고될 때마다 레이블을 추가한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Workflow는 다음과 같은 기본 요소가 포함되어 있어야 한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;448&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dO0PvQ/dJMcac20u5s/5sW2c0i9V18SKYjVwREOdK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dO0PvQ/dJMcac20u5s/5sW2c0i9V18SKYjVwREOdK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dO0PvQ/dJMcac20u5s/5sW2c0i9V18SKYjVwREOdK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdO0PvQ%2FdJMcac20u5s%2F5sW2c0i9V18SKYjVwREOdK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;448&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;448&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;트리거 이벤트&lt;/li&gt;
&lt;li&gt;하나 이상의 Job. 각 Job은 Runner에서 실행되고 하나 이상의 Step을 실행한다.&lt;/li&gt;
&lt;li&gt;각 Step은 Action 또는 쉘 스크립트를 실행할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt; &lt;span style=&quot;font-size: 21px;&quot;&gt;트리거&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;트리거는 Workflow을 실행하게 하는 이벤트다. 트리거는 다음과 같은 이벤트가 해당된다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Workflow 레포지터리에서 발생하는 이벤트&lt;/li&gt;
&lt;li&gt;Github 외부에서 발생해 Github repository_dispatch 이벤트를 트리거하는 이벤트&lt;/li&gt;
&lt;li&gt;스케쥴링&lt;/li&gt;
&lt;li&gt;수동&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 이벤트를 활용해 사용자는 레포지터리의 특정 브랜치에 푸식가 발생하거나 릴리즈가 생성되거나, 이슈가 열리면 실행되는 Workflow를 구성할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Workflow 실행을 트리거할 때는 아래의 과정이 수행된다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;레포지터리에 이벤트 발생. 이벤트는 커밋 해시나 git refs와 연결되어 있다.&lt;/li&gt;
&lt;li&gt;Github가 레포지터리 내 .github/workflows 디렉터리에서 이벤트와 연결된 커밋 해시나 git refs와 관련된 workflow 정의 파일을 확인한다.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;on: 에 설정된 값이 &lt;/span&gt;트리거 이벤트와 일치하는 모든 Workflow에 대해 실행이 트리거 된다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Workflow는 이벤트와 연결된 커밋 해시나 git refs에 존재하는 workflow 정의 파일을 사용해 실행된다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;예시&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시로 공식 문서에서 제공하는 예시 Workflow를 생성해 본다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문서 : &lt;a href=&quot;https://docs.github.com/ko/actions/tutorials/create-an-example-workflow&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.github.com/ko/actions/tutorials/create-an-example-workflow&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;테스트로 생성한 레포지터리에 파일을 생성해 보겠다. 아래 코드는 레포지터리를 pull 하고, bats 프레임워크를 설치한 뒤 bats 버전을 출력하는 예시이다.&lt;/p&gt;
&lt;pre id=&quot;code_1770165138271&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;name: learn-github-actions
run-name: ${{ github.actor }} is learning GitHub Actions
on: [push] # 이벤트
jobs:
  check-bats-version: # job 이름
    runs-on: ubuntu-latest # 실행기
    steps:
      - uses: actions/checkout@v5 # 실행 actions 지정
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
      - run: npm install -g bats # 실행 스크립트 지정
      - run: bats -v&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;572&quot; data-origin-height=&quot;496&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cxGTgo/dJMcahXA3t4/dwXKJ8zDGyLNkfTBl96Gu0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cxGTgo/dJMcahXA3t4/dwXKJ8zDGyLNkfTBl96Gu0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cxGTgo/dJMcahXA3t4/dwXKJ8zDGyLNkfTBl96Gu0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcxGTgo%2FdJMcahXA3t4%2FdwXKJ8zDGyLNkfTBl96Gu0%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;572&quot; height=&quot;496&quot; data-origin-width=&quot;572&quot; data-origin-height=&quot;496&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;예시 코드의 경우 on에 push가 지정되어 있어 푸시을 하면 바로 Worflow가 실행되는데, Actions 탭에서 확인할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;942&quot; data-origin-height=&quot;451&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bb9X8P/dJMcadt4hlU/fZ9qJNqOVaikyCZICHiZuK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bb9X8P/dJMcadt4hlU/fZ9qJNqOVaikyCZICHiZuK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bb9X8P/dJMcadt4hlU/fZ9qJNqOVaikyCZICHiZuK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbb9X8P%2FdJMcadt4hlU%2FfZ9qJNqOVaikyCZICHiZuK%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;942&quot; height=&quot;451&quot; data-origin-width=&quot;942&quot; data-origin-height=&quot;451&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;실행 이력을 클릭하면 구성된 Job과 실행 상태를 확인 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;941&quot; data-origin-height=&quot;452&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cQ0Wx6/dJMcahDgjij/S9ybKarSftJeebVOGo9pr0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cQ0Wx6/dJMcahDgjij/S9ybKarSftJeebVOGo9pr0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cQ0Wx6/dJMcahDgjij/S9ybKarSftJeebVOGo9pr0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcQ0Wx6%2FdJMcahDgjij%2FS9ybKarSftJeebVOGo9pr0%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;941&quot; height=&quot;452&quot; data-origin-width=&quot;941&quot; data-origin-height=&quot;452&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;그리고 Job을 클릭하면 Step 단위의 실행 이력을 확인할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;932&quot; data-origin-height=&quot;499&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bC087Y/dJMcacWgrFi/FO2mAkfLJ54fdraNpuT3NK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bC087Y/dJMcacWgrFi/FO2mAkfLJ54fdraNpuT3NK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bC087Y/dJMcacWgrFi/FO2mAkfLJ54fdraNpuT3NK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbC087Y%2FdJMcacWgrFi%2FFO2mAkfLJ54fdraNpuT3NK%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;932&quot; height=&quot;499&quot; data-origin-width=&quot;932&quot; data-origin-height=&quot;499&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Step을 클릭하면 어떤 명령어가 실행되었는지, 무슨 출력이 발생했는지도 확인할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;287&quot; data-origin-height=&quot;138&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bYTnTX/dJMcadnjxrj/hTiflcI46lPGekaIB1U6jk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bYTnTX/dJMcadnjxrj/hTiflcI46lPGekaIB1U6jk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bYTnTX/dJMcadnjxrj/hTiflcI46lPGekaIB1U6jk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbYTnTX%2FdJMcadnjxrj%2FhTiflcI46lPGekaIB1U6jk%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;287&quot; height=&quot;138&quot; data-origin-width=&quot;287&quot; data-origin-height=&quot;138&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 시작--&gt;&lt;/p&gt;
&lt;h4 style=&quot;font-size: 10px; color: #1f1f1f; border-left: #ff327f 10px solid; margin: 0px 0px 10px; letter-spacing: -1px; line-height: normal; font-stretch: normal; padding: 0px 0px 0px 7px;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-size: 21px; color: #ff327f;&quot;&gt; 참고 문서&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.github.com/ko/actions/concepts/workflows-and-actions/workflows&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.github.com/ko/actions/concepts/workflows-and-actions/workflows&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.github.com/ko/actions/tutorials/create-an-example-workflow&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.github.com/ko/actions/tutorials/create-an-example-workflow&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Git | GitLab</category>
      <category>github</category>
      <author>비번변경</author>
      <guid isPermaLink="true">https://passwd.tistory.com/1479</guid>
      <comments>https://passwd.tistory.com/entry/GitHub-GitHub-Actions-Workflow#entry1479comment</comments>
      <pubDate>Fri, 6 Feb 2026 10:43:08 +0900</pubDate>
    </item>
    <item>
      <title>[GitHub] GitHub Actions - 개념</title>
      <link>https://passwd.tistory.com/entry/GitHub-github-actions-%EA%B0%9C%EB%85%90</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size23&quot;&gt;개요&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;기존에 업무하고 테스트하기 바빠서 GitHub Actions에 대한 개념 정리도 없이 GitHub&amp;nbsp;Actions 테스트 도구인 act에 대한 글을 작성했었다. 이번 글에서는 그 공백을 좀 메꿔보고자 공식 문서를 참조해 개념 정리를 해보려고 한다.&lt;/p&gt;
&lt;p style=&quot;float: none; clear: none;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt; &lt;span style=&quot;font-size: 21px;&quot;&gt;Github Actions&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1400&quot; data-origin-height=&quot;378&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dofr6l/dJMcafk99Fu/UcQVIpfcaOZ91fGHV8Z1Kk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dofr6l/dJMcafk99Fu/UcQVIpfcaOZ91fGHV8Z1Kk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dofr6l/dJMcafk99Fu/UcQVIpfcaOZ91fGHV8Z1Kk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdofr6l%2FdJMcafk99Fu%2FUcQVIpfcaOZ91fGHV8Z1Kk%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;1400&quot; height=&quot;378&quot; data-origin-width=&quot;1400&quot; data-origin-height=&quot;378&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;GitHub Actions은 빌드, 테스트, 배포 파이프라인을 자동화할 수 있는 CI/CD 플랫폼으로, 레포지터리에서 이벤트가 발생할 때 워크플로우를 실행할 수 있도록 한다. Linux, Windows, macOS, 또는 사용자 정의 실행기에서 실행할 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Github 버전의 gitlab cicd라고 이해하면 될 것 같다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt; &lt;span style=&quot;font-size: 21px;&quot;&gt;구성 요소&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;워크플로우 (&lt;span style=&quot;color: #333333; text-align: left;&quot;&gt;Workflow&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;하나 이상의 작업을 실행할 구성 가능한 자동화된 프로세스. 레포지터리 내 YAML 파일에서 정의되며, 레포지터리 이벤트로 트리거 되어 실행되거나 수동, 또는 스케줄에 의해 트리거 될 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;워크플로우는 레포지터리 내 .github/workflows 디렉터리에 정의되며 하나의 레포지터리는 여러 개의 워크플로우를 가질 수 있다. 또한 워크플로우는 다른 워크플로우를 참조할 수도 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;이벤트 (Event)&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;워크플로우 실행을 트리거하는 레포지터리 활동. PR을 만들거나 이슈를 열거나 커밋을 푸시하는 행위가 될 수 있다. 또는 일정에 따라, 수동으로 트리거할 수 있기도 하다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;작업 (Job)&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;동일한 실행 환경에서 실행되는 워크플로우 단계(step)의 집합. 단계는 실행 쉘 스크립트나 action으로 순서대로 실행된다. 또한 단계는 동일한 실행 환경에서 실행되기 때문에 데이터 공유가 가능하다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;작업은 기본적으로 종속성이 없으나 필요 시 종속성을 구성할 수 있다. 작업이 다른 작업에 종속되면, 대상 작업이 완료되기를 대기하게 된다.&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;액션 (Action)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;미리 정의되어 재사용 가능한 작업 또는 코드 집합이다. 워크플로우 파일에 작성하는 반복 코드의 양을 줄일 수 있다. 일반적으로 GitHub 레포지터리 풀, 빌드 환경에 툴 세팅, CSP 인증 등의 작업 등이 필요할 때 사용한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;실행기 (Runner)&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;워크플로우를 실행하는 서버. 한 번에 하나의 작업(Job)을 실행할 수 있다. Github은 기본적으로 &lt;span style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot;&gt;Ubuntu Linux, Microsoft Windows, macOS 실행기를 제공한다. 필요시 사용자가 직업 실행기를 호스팅 하여 구성할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 시작--&gt;&lt;/p&gt;
&lt;h4 style=&quot;font-size: 10px; color: #1f1f1f; border-left: #ff327f 10px solid; margin: 0px 0px 10px; letter-spacing: -1px; line-height: normal; font-stretch: normal; padding: 0px 0px 0px 7px;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #ff327f;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;참고&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.github.com/ko/actions&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.github.com/ko/actions&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.github.com/ko/actions/get-started/understand-github-actions&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.github.com/ko/actions/get-started/understand-github-actions&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Git | GitLab</category>
      <category>github</category>
      <author>비번변경</author>
      <guid isPermaLink="true">https://passwd.tistory.com/1478</guid>
      <comments>https://passwd.tistory.com/entry/GitHub-github-actions-%EA%B0%9C%EB%85%90#entry1478comment</comments>
      <pubDate>Thu, 5 Feb 2026 14:38:34 +0900</pubDate>
    </item>
    <item>
      <title>[Terraform] for_each - 값 참조 시 기본값 지정</title>
      <link>https://passwd.tistory.com/entry/Terraform-foreach-%EA%B0%92-%EC%B0%B8%EC%A1%B0-%EC%8B%9C-%EA%B8%B0%EB%B3%B8%EA%B0%92-%EC%A7%80%EC%A0%95</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size23&quot;&gt;개요&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://passwd.tistory.com/entry/Terraform-foreach-map-set-%EC%88%9C%ED%9A%8C%ED%95%98%EB%A9%B0-%EB%A6%AC%EC%86%8C%EC%8A%A4-%EC%83%9D%EC%84%B1&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;2026.01.30-[Terraform] for_each - map, set 순회하며 리소스 생성&lt;/a&gt;에서 map과 같은 형식의 데이터를 순회하면서 리소스를 생성하는 방법을 알아보았는데, 간혹 순회하는 키의 값이 없는 경우도 발생하지 싶다. 보통 프로그래밍 언어에서는 이런 경우를 대비해 기본값을 설정할 수 있는 기능을 제공하는데 Terraform에도 비슷한 기능이 있는지 확인해보고자 한다.&lt;/p&gt;
&lt;p style=&quot;float: none; clear: none;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;try&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Terraform에서 try 함수는 인자 표현식을 순차적으로 평가해 오류가 발생하지 않는 첫 번째 표현식의 결과를 반환한다. try는 인수를 평가할 때 발생할 수 있는 오류를 특수 함수로 구현 시점에 형태를 정확히 알 수 없는 복잡한 형태의 데이터 구조를 다룰 때 유용하다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;특히 외부 시스템에서 JSON 또는 YAML 형식의 데이터를 가져와 디코딩하는 경우, 설정 여부가 보장되지 않는 속성이 포함되어 있을 수 있다. 이 경우 try를 사용해 예측 가능한 유형을 가진 정규화된 데이터 구조를 생성해 구성의 다른 부분에서 더 편리하게 사용할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1769990533459&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;locals {
  example_map = { foo = &quot;foo&quot;, bar = &quot;bar&quot; }
  keys        = [&quot;foo&quot;, &quot;bar&quot;, &quot;baz&quot;]
}

output &quot;nomalize_map&quot; {
  value = { for k in local.keys : k =&amp;gt; try(local.example_map[k], null) }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;621&quot; data-origin-height=&quot;365&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bihUrj/dJMcahXAiM2/Wv7lYoG0uGw7DnjLpd1n50/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bihUrj/dJMcahXAiM2/Wv7lYoG0uGw7DnjLpd1n50/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bihUrj/dJMcahXAiM2/Wv7lYoG0uGw7DnjLpd1n50/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbihUrj%2FdJMcahXAiM2%2FWv7lYoG0uGw7DnjLpd1n50%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;621&quot; height=&quot;365&quot; data-origin-width=&quot;621&quot; data-origin-height=&quot;365&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt; &lt;span style=&quot;font-size: 21px;&quot;&gt;lookup&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;lookup 함수는 주어진 키를 사용해 map에서 해당 요소의 값을 가져온다. 만약 키가 존재하지 않으면 기본값이 반환된다.&lt;/p&gt;
&lt;pre id=&quot;code_1769991082600&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;lookup(map, key, default)&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;try와는 다르게 map 데이터에 대해서만 사용할 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;예시)&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1769991195231&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;locals {
  example_map = { foo = &quot;foo&quot;, bar = &quot;bar&quot; }
  keys        = [&quot;foo&quot;, &quot;bar&quot;, &quot;baz&quot;]
}

output &quot;nomalize_map&quot; {
  value = { for k in local.keys : k =&amp;gt; lookup(local.example_map, k, null) }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;673&quot; data-origin-height=&quot;367&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cpkD1E/dJMcadt3AgS/9w7Uamm3nQN6tk8fRDQYyK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cpkD1E/dJMcadt3AgS/9w7Uamm3nQN6tk8fRDQYyK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cpkD1E/dJMcadt3AgS/9w7Uamm3nQN6tk8fRDQYyK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcpkD1E%2FdJMcadt3AgS%2F9w7Uamm3nQN6tk8fRDQYyK%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;673&quot; height=&quot;367&quot; data-origin-width=&quot;673&quot; data-origin-height=&quot;367&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 시작--&gt;&lt;/p&gt;
&lt;h4 style=&quot;font-size: 10px; color: #1f1f1f; border-left: #ff327f 10px solid; margin: 0px 0px 10px; letter-spacing: -1px; line-height: normal; font-stretch: normal; padding: 0px 0px 0px 7px;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #ff327f;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;참고 문서&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://developer.hashicorp.com/terraform/language/functions/try&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://developer.hashicorp.com/terraform/language/functions/try&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://developer.hashicorp.com/terraform/language/functions/lookup&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://developer.hashicorp.com/terraform/language/functions/lookup&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Terraform</category>
      <category>terraform</category>
      <author>비번변경</author>
      <guid isPermaLink="true">https://passwd.tistory.com/1477</guid>
      <comments>https://passwd.tistory.com/entry/Terraform-foreach-%EA%B0%92-%EC%B0%B8%EC%A1%B0-%EC%8B%9C-%EA%B8%B0%EB%B3%B8%EA%B0%92-%EC%A7%80%EC%A0%95#entry1477comment</comments>
      <pubDate>Wed, 4 Feb 2026 10:03:13 +0900</pubDate>
    </item>
    <item>
      <title>[Terraform] for_each - map, set 순회하며 리소스 생성</title>
      <link>https://passwd.tistory.com/entry/Terraform-foreach-map-set-%EC%88%9C%ED%9A%8C%ED%95%98%EB%A9%B0-%EB%A6%AC%EC%86%8C%EC%8A%A4-%EC%83%9D%EC%84%B1</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size23&quot;&gt;개요&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://passwd.tistory.com/entry/Terraform-yamldecode-YAML%EC%9D%84-HCL%EB%A1%9C-%ED%8C%8C%EC%8B%B1%ED%95%98%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;2026.01.20-[Terraform] yamldecode - YAML을 HCL로 파싱하기&lt;/a&gt;에서 YAML 데이터를 hcl이 인식할 수 있는 형태로 파싱 했다. 이제는 이 데이터를 순회하면서 리소스를 만들기 위한 방법을 작성한다.&lt;/p&gt;
&lt;p style=&quot;float: none; clear: none;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt; &lt;span style=&quot;font-size: 21px;&quot;&gt;for_each&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본적으로 resource 블록은 하나의 인프라 객체를 생성한다. module 블록도 자식 모듈의 콘텐츠를 한 번 include 하고, action도 정의된 작업도 한 번 수행한다. for_each 블록은 이러한 블록이 유사한 형태로 여럿 필요할 때 활용할 수 있는데 resource, 모듈, map 블록에 for_each 인수가 포함되면 지정된 list, map 내 각 요소에 대해 작업을 한 번씩 호출한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;for_each 메타 인자는 map 또는 문자열 set을 헐용하고, 각 항목에 대한 객체를 생성한다. 각 객체는 고유한 인프라와 연결되고 구성 변경 사항을 적용할 때마다 인스턴스를 생성, 갱신, 삭제한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용자는 toset(), tomap()과 같은 함수를 사용해 for_each에 사용할 값을 생성할 수 있다. for_each가 반복할 값은 테라폼이 원격 리소스 작업을 수행하기 전에 알고 있어야 하기 때문에 객체 생성 시 구성이 적용된 후 알 수 있는 리소스 속성에 대한 참조를 지정하면 오류가 발생한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 예시는 tomap 함수를 통해 생성된 map을 참조해 두 개의 azurerm_resource_group 리소스를 생성한다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1769737246294&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;resource &quot;azurerm_resource_group&quot; &quot;rg&quot; {
  for_each = tomap({
    a_group       = &quot;eastus&quot;
    another_group = &quot;westus2&quot;
  })
  name     = each.key
  location = each.value
}&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;아래 예시는 toset()으로 생성된 set을 사용해 4개의 aws_iam_user를 생성한다.&lt;/p&gt;
&lt;pre id=&quot;code_1769737386842&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;resource &quot;aws_iam_user&quot; &quot;the-accounts&quot; {
  for_each = toset([&quot;Todd&quot;, &quot;James&quot;, &quot;Alice&quot;, &quot;Dottie&quot;])
  name     = each.key
}&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;특이한 점이 있다면 for_each는 민감 정보를 입력으로 전달하면 오류를 발생시킨다. for_each 값을 리소스 객체로 식별하고 출력하기 때문에 허용되지 않는다고 하니 참고할 필요가 있겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;for_each에 map이 전달된 경우, 각 개체는 키와 값을 참조할 수 있는 each.key, each.value 속성을 가진다. set이 전달되는 경우 each.key로 참조한다. 그리고 count와 마찬가지로 블록 자체는 TYPE.NAME으로 가리키는데, 각 객체는 TYPE.NAME[KEY]로 가리킨다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;사용 사례&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;for_each의 특징 중 하나는 for_each로 생성한 블록을 다른 블록의 for_each에 전달할 수 있다는 점이다. 이를 체인 패턴이라고 부르는데, aws 내 여러 vpc를 생성하고 각 vpc에 인터넷 게이트웨이를 생성해야 하는 경우 활용할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1769738210290&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;variable &quot;vpcs&quot; {
  type = map(object({
    cidr_block = string
  }))
}

resource &quot;aws_vpc&quot; &quot;example&quot; {
  # One VPC for each element of var.vpcs
  for_each = var.vpcs

  # each.value here is a value from var.vpcs
  cidr_block = each.value.cidr_block
}

resource &quot;aws_internet_gateway&quot; &quot;example&quot; {
  # One Internet Gateway per VPC
  for_each = aws_vpc.example

  # each.value here is a full aws_vpc object
  vpc_id = each.value.id
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 시작--&gt;&lt;/p&gt;
&lt;h4 style=&quot;font-size: 10px; color: #1f1f1f; border-left: #ff327f 10px solid; margin: 0px 0px 10px; letter-spacing: -1px; line-height: normal; font-stretch: normal; padding: 0px 0px 0px 7px;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-size: 21px; color: #ff327f;&quot;&gt; 참고 문서&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://developer.hashicorp.com/terraform/language/meta-arguments/for_each&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://developer.hashicorp.com/terraform/language/meta-arguments/for_each&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Terraform</category>
      <category>terraform</category>
      <author>비번변경</author>
      <guid isPermaLink="true">https://passwd.tistory.com/1476</guid>
      <comments>https://passwd.tistory.com/entry/Terraform-foreach-map-set-%EC%88%9C%ED%9A%8C%ED%95%98%EB%A9%B0-%EB%A6%AC%EC%86%8C%EC%8A%A4-%EC%83%9D%EC%84%B1#entry1476comment</comments>
      <pubDate>Tue, 3 Feb 2026 11:52:11 +0900</pubDate>
    </item>
    <item>
      <title>[Terraform] for - 요소 반복을 통한 값 생성</title>
      <link>https://passwd.tistory.com/entry/Terraform-for-%EC%9A%94%EC%86%8C-%EB%B0%98%EB%B3%B5%EC%9D%84-%ED%86%B5%ED%95%9C-%EA%B0%92-%EC%83%9D%EC%84%B1</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size23&quot;&gt;개요&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://passwd.tistory.com/entry/Terraform-yamldecode-YAML%EC%9D%84-HCL%EB%A1%9C-%ED%8C%8C%EC%8B%B1%ED%95%98%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;2026.01.20-[Terraform] yamldecode - YAML을 HCL로 파싱하기&lt;/a&gt;에서 yamldecode로 yaml 파일을 map 형식의 데이터를 파싱 했는데, 조건에 따른 필터링 등의 작업이 필요해졌다. 확인해 보니 for 문을 사용하면 되는 것으로 보여 문법을 알아보고자 한다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;for&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;테라폼에서 for 문은 복합 타입을 다른 복합 타입의 데이터로 변환할 수 있게 한다. 예시로 아래 코드의 경우 var.list가 문자열 목록일 때 대문자 문자열 tuple을 생성한다. var.list의 각 요소에 대해 반복되며, 각 요소를 s로 칭하고 upper를 수행한 tuple 값을 생성한다는 의미이다.&lt;/p&gt;
&lt;pre id=&quot;code_1769643909026&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[for s in var.list : upper(s)]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;515&quot; data-origin-height=&quot;360&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dLMDh7/dJMcac9IQd1/QFdJWi5Vs4yAP6Y2mJkZCK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dLMDh7/dJMcac9IQd1/QFdJWi5Vs4yAP6Y2mJkZCK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dLMDh7/dJMcac9IQd1/QFdJWi5Vs4yAP6Y2mJkZCK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdLMDh7%2FdJMcac9IQd1%2FQFdJWi5Vs4yAP6Y2mJkZCK%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;515&quot; height=&quot;360&quot; data-origin-width=&quot;515&quot; data-origin-height=&quot;360&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;입력&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;for 문의 입력은 in 키워드 뒤에 위치하며 list, set, tuple, 맵, object 타입의 데이터가 올 수 있다. 아래 코드의 경우에는 k가 map의 키, v가 map의 값이 된다.&lt;/p&gt;
&lt;pre id=&quot;code_1769644431835&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[for k, v in var.map : length(k) + length(v)]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;537&quot; data-origin-height=&quot;429&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bOJ50K/dJMcabC1Obj/fUKkK0JCqyByH7GRSUkvOK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bOJ50K/dJMcabC1Obj/fUKkK0JCqyByH7GRSUkvOK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bOJ50K/dJMcabC1Obj/fUKkK0JCqyByH7GRSUkvOK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbOJ50K%2FdJMcabC1Obj%2FfUKkK0JCqyByH7GRSUkvOK%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;537&quot; height=&quot;429&quot; data-origin-width=&quot;537&quot; data-origin-height=&quot;429&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;입력이 list나 tuple인 경우에는 인덱스와 값을 대상으로 순회할 수도 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1769644801092&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[for i, v in var.list : &quot;${i} is ${v}&quot;]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;448&quot; data-origin-height=&quot;388&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/du1mlm/dJMcaia5Rjy/wDDPVBqCmrYaIF1pKKOnxK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/du1mlm/dJMcaia5Rjy/wDDPVBqCmrYaIF1pKKOnxK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/du1mlm/dJMcaia5Rjy/wDDPVBqCmrYaIF1pKKOnxK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdu1mlm%2FdJMcaia5Rjy%2FwDDPVBqCmrYaIF1pKKOnxK%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;448&quot; height=&quot;388&quot; data-origin-width=&quot;448&quot; data-origin-height=&quot;388&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;다만 키나 인덱스는 선택적인 요소로, 만약 for 키워드 뒤에 단일 기호만 지정하면 해당 기호는 항상 값을 나타낸다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;출력&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;for 문은 for 문을 감싼 괄호의 유형에 따라 생성하는 결과를 결정한다. tuple을 생성하는 경우에는 대괄호를 사용하고, object를 생성하는 경우에는 중괄호를 사용한다. 또한 =&amp;gt; 기호를 사용해 결과 표현식을 제공해주어야 한다.&lt;/p&gt;
&lt;pre id=&quot;code_1769645673273&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{for s in var.list : s =&amp;gt; upper(s)}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;예로 들어 위의 표현식은 key가 원래 값이고 값이 대문자 값인 object를 생성한다.&lt;/p&gt;
&lt;pre id=&quot;code_1769645755826&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{
  foo = &quot;FOO&quot;
  bar = &quot;BAR&quot;
  baz = &quot;BAZ&quot;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;for은 기본적으로 tuple, object만 생성할 수 있지만 테라폼의 자동 타입 변환 규칙에 의해 list, map, set이 예상되는 위치에서 for 문에 의한 결과를 사용할 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;활용 예시&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;필터링&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;for 문으로 데이터를 만들 때는 원하는 데이터만 필터링할 수 있도록 if 절을 사용할 수 있다. 이를 활용해 하나의 데이터를 특정 기준에 따라 구분한 여러 개의 데이터로 나눌 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1769646202522&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[for s in var.list : upper(s) if s != &quot;&quot;]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;508&quot; data-origin-height=&quot;411&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ogPzv/dJMcaaqAsqY/5tMFfZknn3pj5MTJnUJhmK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ogPzv/dJMcaaqAsqY/5tMFfZknn3pj5MTJnUJhmK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ogPzv/dJMcaaqAsqY/5tMFfZknn3pj5MTJnUJhmK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FogPzv%2FdJMcaaqAsqY%2F5tMFfZknn3pj5MTJnUJhmK%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;508&quot; height=&quot;411&quot; data-origin-width=&quot;508&quot; data-origin-height=&quot;411&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;정렬&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;for 문을 사용하면 정렬되지 않은 데이터(map, object, set)를 정렬되는 유형으로(list, tuple)로 변환할 수 있는데 이때 정렬 기준을 지정해주어야 한다. map, object의 경우 요소의 키나 속성이 기준이 될 수 있고, 문자열 set의 경우 값이 기준이 된다. 다른 타입의 set의 경우에는 임의 기준으로 정렬이 이뤄진다.&lt;/p&gt;
&lt;pre id=&quot;code_1769647003996&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;toset([for e in var.set : e.example])&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 시작--&gt;&lt;/p&gt;
&lt;h4 style=&quot;font-size: 10px; color: #1f1f1f; border-left: #ff327f 10px solid; margin: 0px 0px 10px; letter-spacing: -1px; line-height: normal; font-stretch: normal; padding: 0px 0px 0px 7px;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #ff327f;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;참고 문서&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://developer.hashicorp.com/terraform/language/expressions/for&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://developer.hashicorp.com/terraform/language/expressions/for&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Terraform</category>
      <category>terraform</category>
      <author>비번변경</author>
      <guid isPermaLink="true">https://passwd.tistory.com/1475</guid>
      <comments>https://passwd.tistory.com/entry/Terraform-for-%EC%9A%94%EC%86%8C-%EB%B0%98%EB%B3%B5%EC%9D%84-%ED%86%B5%ED%95%9C-%EA%B0%92-%EC%83%9D%EC%84%B1#entry1475comment</comments>
      <pubDate>Mon, 2 Feb 2026 10:18:53 +0900</pubDate>
    </item>
    <item>
      <title>[Terraform] count - 리소스 반복 생성</title>
      <link>https://passwd.tistory.com/entry/Terraform-count-%EB%B0%98%EB%B3%B5-%EC%88%98%ED%96%89%ED%95%98</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size23&quot;&gt;개요&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Terraform 코드를 작성하던 중 조건에 따라 리소스 생성 여부를 결정하고 싶다고 했더니 count 문법을 제안해 왔다. 제안은 채택하더라고 어떤 기능인지는 알고 사용해야 할 것 같아 내용을 정리한다.&lt;/p&gt;
&lt;p style=&quot;float: none; clear: none;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;count&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;기본적으로 리소스 블록은 하나의 인프라 개체를 구성한다. 다만 count 메타 인수를 사용하면 유사한 개체를 별도 블록으로 작성하지 않고 하나의 블록으로 작성할 수 있다. count 메타 인수는 data, ephemeral, module, resource, list에서 사용할 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;예로 들어 아래와 같은 data 블록이 있다고 하자.&lt;/p&gt;
&lt;pre id=&quot;code_1769558358047&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;data &quot;http&quot; &quot;user_1&quot; {
  url = &quot;https://jsonplaceholder.typicode.com/users/1&quot;
  request_headers = {
    # Authorization = &quot;&quot;
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이에 더해 user_2, user_3이 필요하다면 기본적으로 user_1과 비슷한 블록을 별도로 작성해야 한다.&lt;/p&gt;
&lt;pre id=&quot;code_1769558537239&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;data &quot;http&quot; &quot;user_1&quot; {
  url = &quot;https://jsonplaceholder.typicode.com/users/1&quot;
  request_headers = {
    # Authorization = &quot;&quot;
  }
}

data &quot;http&quot; &quot;user_2&quot; {
  url = &quot;https://jsonplaceholder.typicode.com/users/2&quot;
  request_headers = {
    # Authorization = &quot;&quot;
  }
}

data &quot;http&quot; &quot;user_3&quot; {
  url = &quot;https://jsonplaceholder.typicode.com/users/3&quot;
  request_headers = {
    # Authorization = &quot;&quot;
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;즉, 반복이 발생하는데 data 블록에 count 메타 인수를 활용함으로써 반복 코드를 줄일 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt; &lt;span style=&quot;font-size: 21px;&quot;&gt;용법&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;사용법은 아주 간단하다. 반복 수행이 필요한 블록에 count 인자만 추가해주면 된다. 아래 예시는 동일한 ami, 타입의 aws ec2 인스턴스를 4개 생성하는 코드이다.&lt;/p&gt;
&lt;pre id=&quot;code_1769559140644&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;resource &quot;aws_instance&quot; &quot;server&quot; {
  count = 4 # create four similar EC2 instances

  ami           = &quot;ami-a1b2c3d4&quot;
  instance_type = &quot;t2.micro&quot;

  tags = {
    Name = &quot;Server ${count.index}&quot;
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;count 값은 일반적으로 숫자 값을 허용한다. 다만 원격 리소스 작업을 수행하기 전에 값을 알고 있어야 하기 때문에 구성이 적용된 이후에 알 수 있는 리소스 속성은 사용할 수 없다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;count는 개별 개체를 식별하기 위해 인덱스를 사용하는데 count.index 형식으로 참조할 수 있고, 값은 0부터 시작한다. 이를 활용해 블록 자체는 TYPE.NAME / MODULE.NAME으로, 개별 리소스는 TYPE.NAME[INDEX] / MODULE.NAME[INDEX] 형식으로 가리킬 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;위에서 작성했던 예시 코드의 경우에는 같은 작업을 아래 코드로 변경할 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1769559662995&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;data &quot;http&quot; &quot;user&quot; {
  count = 3

  url = &quot;https://jsonplaceholder.typicode.com/users/${count.index}&quot;
  request_headers = {
    # Authorization = &quot;&quot;
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;645&quot; data-origin-height=&quot;126&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bViHYB/dJMcadHzlBZ/QzqxclhJBeDUtrskKJvzD1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bViHYB/dJMcadHzlBZ/QzqxclhJBeDUtrskKJvzD1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bViHYB/dJMcadHzlBZ/QzqxclhJBeDUtrskKJvzD1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbViHYB%2FdJMcadHzlBZ%2FQzqxclhJBeDUtrskKJvzD1%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;645&quot; height=&quot;126&quot; data-origin-width=&quot;645&quot; data-origin-height=&quot;126&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;사용 사례&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;count 메타 인수를 활용하는 몇 가지 사례에 대해서 알아보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;여러 모듈 리소스 생성&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;아래 예시는 instance_names 로컬 변수를 사용해 ec2_instance 모듈읠 여러 개 생성하는 것이다. 이름은 &lt;span style=&quot;color: #333333; text-align: left;&quot;&gt;instance_names를 활용하는데, count.index로 접근하여 활용한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1769560160809&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;locals { 
  instance_names = [ &quot;web&quot; , &quot;api&quot; , &quot;batch&quot; ] 
} 

module &quot;ec2_instance&quot; { 
  source   = &quot;terraform-aws-modules/ec2-instance/aws&quot; 
  version = &quot;6.0.2&quot; 
  count    = length(local . instance_names) 

  name            = local.instance_names[count.index] 
  ami             = data.aws_ami.latest_amazon_linux.id 
  instance_type   = &quot;t2.micro&quot; 

  depends_on = [aws_s3_bucket.example] 
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;리소스 생성 조건으로 활용&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;count 메타 인수는 삼항 연산자를 허용하고 있어 리소스 생성의 조건으로 활용할 수 있기도 하다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;아래 예시의 경우 creator 라는 변수가 있으면 리소스를 3개 생성하고, 그렇지 않으면 생성하지 않는다는 코드이다.&lt;/p&gt;
&lt;pre id=&quot;code_1769560429960&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;data &quot;http&quot; &quot;user&quot; {
  count = var.creator ? 3 : 0

  url = &quot;https://jsonplaceholder.typicode.com/users/${count.index}&quot;
  request_headers = {
    # Authorization = &quot;&quot;
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 시작--&gt;&lt;/p&gt;
&lt;h4 style=&quot;font-size: 10px; color: #1f1f1f; border-left: #ff327f 10px solid; margin: 0px 0px 10px; letter-spacing: -1px; line-height: normal; font-stretch: normal; padding: 0px 0px 0px 7px;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-size: 21px; color: #ff327f;&quot;&gt; 참고 문서&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://developer.hashicorp.com/terraform/language/meta-arguments/count&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://developer.hashicorp.com/terraform/language/meta-arguments/count&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://kimjingo.tistory.com/220&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://kimjingo.tistory.com/220&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Terraform</category>
      <category>terraform</category>
      <author>비번변경</author>
      <guid isPermaLink="true">https://passwd.tistory.com/1474</guid>
      <comments>https://passwd.tistory.com/entry/Terraform-count-%EB%B0%98%EB%B3%B5-%EC%88%98%ED%96%89%ED%95%98#entry1474comment</comments>
      <pubDate>Fri, 30 Jan 2026 10:27:41 +0900</pubDate>
    </item>
    <item>
      <title>[YAML] 명시적 데이터 타입 선언</title>
      <link>https://passwd.tistory.com/entry/YAML-%EB%AA%85%EC%8B%9C%EC%A0%81-%EB%8D%B0%EC%9D%B4%ED%84%B0-%ED%83%80%EC%9E%85-%EC%84%A0%EC%96%B8</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size23&quot;&gt;개요&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;YAML이라는 데이터 형식은 꾸준히 사용하고 있는데, 기본적인 문법만 익히고 사용하다 보니 한 번씩 모르던 문법이 튀어나오기 십상인 것 같다. 이번에는 YAML에 데이터 형식을 지정할 수 있다는 사실을 최근에 확인하여 내용을 정리한다.&lt;/p&gt;
&lt;p style=&quot;float: none; clear: none;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt; &lt;span style=&quot;font-size: 21px;&quot;&gt;데이터 타입&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;YAML의 데이터 타입은 크게 Scalar, List, Mapping이라는 3가지 종류가 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Scalar&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Scalar는 String, Integer, Boolean과 같이 한 가지 값으로 분류될 수 있는 데이터를 의미한다.&lt;/p&gt;
&lt;pre id=&quot;code_1769471698318&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;items: 30
price: 50
overwrite: true&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;List&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;YAML에서 리스트는 하이픈과 개행, 또는 대괄호와 쉼표를 사용하여 표현할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1769471749517&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;list:
 - first
 - second
 - third
 
# 또는
list: [ first, second, third ]&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Mappings&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;정렬되지 않은 key-value 쌍의 시퀀스다. 아래의 경우 name과 code가 key이고 kim과 yaml이 value이다. Mappings에서 key는 유일해야 한다.&lt;/p&gt;
&lt;pre id=&quot;code_1769472184117&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;character:
 name: kim
 code: yaml
 
 # 또는
character: { name: kim, code: yaml }&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;YAML에서는 List와 Mapping이 결합된 형태도 많이 사용한다.&lt;/p&gt;
&lt;pre id=&quot;code_1769472234798&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;characters:
 - name: kim
   code: yaml
 - name: cho
   code: java
 - name: han
   code: python

# 또는
characters:
 - { name : kim, code: yaml}
 - { name : cho, code: java}
 - { name : han, code: python}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이 경우 보통 위의 형식으로 많이 기재하는 것 같다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt; &lt;span style=&quot;font-size: 21px;&quot;&gt;명시적 타입 선언&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;YAML에서 데이터 타입을 명시적으로 지정할 땐 태그(!!)를 사용한다.&lt;/p&gt;
&lt;pre id=&quot;code_1769472684716&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;key: !!datatype value

# 예시
str_items: !!str 30
bool : !!bool &quot;true&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;확인해 보면 30이라는 값에 데이터타입을 지정한 것과 지정하지 않은 것 간 차이가 존재하는 것을 확인할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1004&quot; data-origin-height=&quot;202&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bgnuWv/dJMcafZHya1/X1SZVb6Fx1q9NE71a3kcmK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bgnuWv/dJMcafZHya1/X1SZVb6Fx1q9NE71a3kcmK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bgnuWv/dJMcafZHya1/X1SZVb6Fx1q9NE71a3kcmK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbgnuWv%2FdJMcafZHya1%2FX1SZVb6Fx1q9NE71a3kcmK%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;1004&quot; height=&quot;202&quot; data-origin-width=&quot;1004&quot; data-origin-height=&quot;202&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 시작--&gt;&lt;/p&gt;
&lt;h4 style=&quot;font-size: 10px; color: #1f1f1f; border-left: #ff327f 10px solid; margin: 0px 0px 10px; letter-spacing: -1px; line-height: normal; font-stretch: normal; padding: 0px 0px 0px 7px;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-size: 21px; color: #ff327f;&quot;&gt; 참고 문서&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a style=&quot;text-align: center;&quot; href=&quot;https://siloam72761.tistory.com/entry/YAML-YAML%EC%9D%B4%EB%9E%80-%EA%B8%B0%EB%B3%B8-%ED%8A%B9%EC%A7%95-%EB%8D%B0%EC%9D%B4%ED%84%B0-%ED%83%80%EC%9E%85-%EB%AC%B8%EB%B2%95&quot;&gt;[YAML] YAML이란? 기본 특징, 데이터 타입, 문법&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>데이터 교환 형식</category>
      <author>비번변경</author>
      <guid isPermaLink="true">https://passwd.tistory.com/1473</guid>
      <comments>https://passwd.tistory.com/entry/YAML-%EB%AA%85%EC%8B%9C%EC%A0%81-%EB%8D%B0%EC%9D%B4%ED%84%B0-%ED%83%80%EC%9E%85-%EC%84%A0%EC%96%B8#entry1473comment</comments>
      <pubDate>Thu, 29 Jan 2026 10:13:32 +0900</pubDate>
    </item>
    <item>
      <title>[작업 기록] 서비스 이전 (Docker -&amp;gt; EKS)</title>
      <link>https://passwd.tistory.com/entry/%EC%9E%91%EC%97%85-%EA%B8%B0%EB%A1%9D-%EC%84%9C%EB%B9%84%EC%8A%A4-%EC%9D%B4%EC%A0%84-Docker-EKS</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;!--헤드라인시작--&gt;&lt;/b&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size23&quot;&gt;배경&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;현재 운영 중인 서비스에는 Kafka 브로커의 메시지를 처리하는 ETL Handler(Consumer)가 존재한다. 초기에는 트래픽이 많지 않아 단일 EC2 인스턴스 위에 Docker 컨테이너를 띄워 운영하는 것만으로 충분했다.&lt;br /&gt;하지만 서비스 규모가 커지며 문제가 발생했다. 패키지 저장소와 취약점 DB가 확대되면서 핸들러 수가 증가했고, 결국 단일 호스트의 물리적 리소스 한계에 부딪혔다. 빈번한 CPU 사용량 과다로 인스턴스가 죽는 현상이 잦아졌고, 이는 곧 단일 장애점(SPOF)이 되어 서비스 전체의 안정성을 위협했다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;간단한 해결 방법은 인스턴스 타입 변경이지만, 이는 근본적인 해결책이 되지 못했다. 때문에 보다 안정적인 운영 환경인 EKS로의 이전을 꾀하게 되었다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt; &lt;span style=&quot;font-size: 21px;&quot;&gt;목표&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;업무를 진행하기 전에 목표로 해야하는 부분을 먼저 점검했다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;안정성 확보 (Stability): 단일 EC2를 벗어나 EKS 환경으로 이전함으로써 SPOF를 제거하고, 리소스 부족 시 유연하게 확장 가능한 구조를 만든다.&lt;/li&gt;
&lt;li&gt;IaC 기반 관리 (Terraform): 기존 EKS 인프라 관리 방식에 맞춰, 핸들러 서비스 또한 Terraform으로 관리되도록 한다.&lt;/li&gt;
&lt;li&gt;배포 자동화 (CI/CD): Github Actions를 통해 PR 머지 시 빌드와 배포가 자동으로 이루어지는 프로세스를 유지하되, 더욱 고도화한다.&lt;/li&gt;
&lt;li&gt;[추가] 비용 최적화 (Cost Efficiency): 외부 통신(NLB)을 K8s 내부 통신으로 전환하여 불필요한 네트워크 비용을 제거한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;작업을 진행하면서 이러한 부분을 유념할 수 있도록 노력했다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt; &lt;span style=&quot;font-size: 21px;&quot;&gt;작업 내용&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;작업한 내용은 다음과 같다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1. 기존&amp;nbsp;배포&amp;nbsp;프로세스&amp;nbsp;분석&amp;nbsp;및&amp;nbsp;벤치마킹&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;먼저 사내에 의도하는 배포 방식과 유사한 배포 프로세스가 있는지 먼저 확인하고 분석했다. 검증된 기존 아키텍처를 벤치마킹하여 시행착오를 줄이고 운영 일관성을 유지하기 위함이었다. &lt;br /&gt;확인한 결과, Terraform으로 인프라(Deployment, Service)를 정의하고 GitHub Actions로 이를 실행하는 구조가 이미 잡혀 있는 서비스가 존재해서 이 구현을 기반으로 작업하기로 결정했다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2. Terraform 코드 작성&lt;/b&gt;&lt;/h4&gt;
&lt;p data-path-to-node=&quot;3&quot; data-ke-size=&quot;size16&quot;&gt;Terraform 코드는 리소스 생성을 넘어, 운영의 안정성과 확장성을 고려했다. 구체적인 구현은 다음과 같다.&lt;/p&gt;
&lt;p data-path-to-node=&quot;3&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-path-to-node=&quot;3&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1) 리소스 격리 전략 (Isolation) &lt;/b&gt;&lt;/p&gt;
&lt;p data-path-to-node=&quot;3&quot; data-ke-size=&quot;size16&quot;&gt;가장 먼저 고려한 것은 '안정성'이다. 핸들러 서비스는 대량의 데이터를 처리하며 리소스 사용량이 급증할 수 있다. 이 부하가 기존 웹 API 서버 등 타 서비스에 영향을 주지 않도록 물리적/논리적 격리를 적용했다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-path-to-node=&quot;5&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Namespace: etl-handler 전용 네임스페이스를 생성하여 논리적으로 영역을 분리했다.&lt;/li&gt;
&lt;li&gt;NodePool: 핸들러 전용 Karpenter 노드풀을 지정하여, 물리적으로 독립된 노드에서만 파드가 실행되도록 자원 경합을 원천 차단했다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-path-to-node=&quot;6&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2) 설정 기반의 동적 생성 (Dynamic Resource Creation) &lt;/b&gt;&lt;/p&gt;
&lt;p data-path-to-node=&quot;6&quot; data-ke-size=&quot;size16&quot;&gt;운영 효율을 위해 코드 중복을 제거했다. 운영할 핸들러가 여러 개였지만, 모두 'Kafka 메시지를 소비하는 데몬'이라는 동일한 배포 패턴을 가지고 있었다. 따라서 Deployment 리소스를 일일이 하드코딩하지 않고, GitHub 저장소에 있는 설정 파일(handlers-deploy.yml)을 읽어와 Terraform의 for_each 구문으로 반복 생성하도록 구조화했다.&lt;/p&gt;
&lt;p data-path-to-node=&quot;6&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-path-to-node=&quot;7&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3) 내부 통신을 위한 환경 변수 주입 (Cost Optimization)&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1158&quot; data-origin-height=&quot;156&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bwzTqB/dJMcaioABZX/daYjCX0KbO53UunEQ8Kqc1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bwzTqB/dJMcaioABZX/daYjCX0KbO53UunEQ8Kqc1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bwzTqB/dJMcaioABZX/daYjCX0KbO53UunEQ8Kqc1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbwzTqB%2FdJMcaioABZX%2FdaYjCX0KbO53UunEQ8Kqc1%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;1158&quot; height=&quot;156&quot; data-origin-width=&quot;1158&quot; data-origin-height=&quot;156&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-path-to-node=&quot;7&quot; data-ke-size=&quot;size16&quot;&gt;이번 이전 작업에서 LB를 통한 통신을 'EKS 내부 통신'으로 전환하면 불필요한 네트워킹을 줄일 수 있을 거란 판단이 있었다. 따라서 Deployment 생성 시점에 브로커 주소를 환경 변수로 주입하도록 구성했다. 먼저 애플리케이션에서 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;KAFKA_BOOTSTRAP_SERVERS&lt;/span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;가 하드코딩되어 있어 이를 환경 변수로 주입할 수 있게 변경했고, &lt;/span&gt;환경 변수에 외부 도메인이 아닌 EKS 내부 도메인(broker... svc.cluster.local)을 할당했다.&lt;/p&gt;
&lt;pre id=&quot;code_1769432353928&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# (예시 코드) deployment 리소스 정의 중 일부
resource &quot;kubernetes_deployment&quot; &quot;handler&quot; {
  for_each = local.active_handlers # 설정 파일 기반 반복 생성
  
  spec {
    template {
      spec {
        # ... (중략) ...
        # [Isolation] 전용 노드풀 지정
        node_selector = { &quot;karpenter.sh/provisioner-name&quot; = &quot;etl-handler&quot; }
        
        container {
          env {
            # [Cost Optimization] 내부 DNS 주소 주입
            name  = &quot;KAFKA_BOOTSTRAP_SERVERS&quot;
            value = &quot;broker.c-kafka.svc.cluster.local:9092&quot;
          }
        }
      }
    }
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-path-to-node=&quot;8&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-path-to-node=&quot;8&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;4) OS 제약 없는 하이브리드 인증 (Hybrid Authentication)&lt;/b&gt;&lt;/p&gt;
&lt;p data-path-to-node=&quot;3&quot; data-ke-size=&quot;size16&quot;&gt;핸들러 배포에 필수적인 설정 파일이 GitHub Private 저장소에 위치해 있어, Terraform 실행 시 이를 읽어오기 위한 인증 토큰이 반드시 필요했다.&lt;/p&gt;
&lt;p data-path-to-node=&quot;4&quot; data-ke-size=&quot;size16&quot;&gt;난관은 실행 환경과 보안 정책의 충돌이었다. 이 코드는 인프라 관리자의 로컬 환경(Windows)과 CI/CD 파이프라인인 GitHub Actions(Linux) 양쪽에서 모두 수행되어야 했다. 기존에는 tfvars 파일을 통해 토큰을 전달했으나, 최근 배포 프로세스가 고도화되면서 민감 정보를 파일(tfvars) 형태가 아닌 방식으로 처리하도록 정책이 변경되었다.&lt;/p&gt;
&lt;p data-path-to-node=&quot;5&quot; data-ke-size=&quot;size16&quot;&gt;이러한 환경적 차이와 제약을 해소하기 위해, 실행 환경을 감지하고 인증 방식을 자동 전환하는 이원화된 인증 로직을 구현했다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-path-to-node=&quot;9&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Linux (CI/CD): 환경 변수(TF_VAR_github_token)를 우선 사용.&lt;/li&gt;
&lt;li&gt;Windows (Local): 환경 변수가 없으면 external 데이터 소스를 통해 PowerShell 스크립트를 호출하여 로컬 자격 증명을 획득.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1769431621976&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 1. 환경 변수(CI/CD) 또는 PowerShell(Windows)을 통한 토큰 획득
variable &quot;github_token&quot; {
  default = null # 값이 없으면 로컬 환경(Windows)으로 간주
}

data &quot;external&quot; &quot;github-auth&quot; {
  # github_token 변수가 없을 때만 PowerShell 스크립트 실행
  count   = var.github_token == null ? 1 : 0
  program = [&quot;Powershell.exe&quot;, &quot;-ExecutionPolicy&quot;, &quot;Bypass&quot;, &quot;-File&quot;, &quot;./password.ps1&quot;]
}

locals {
  # 최종 토큰: 환경변수 우선, 없으면 스크립트 결과 사용
  final_token = var.github_token != null ? var.github_token : data.external.github-auth[0].result.password
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-path-to-node=&quot;10&quot; data-ke-size=&quot;size16&quot;&gt;이로써 운영체제 제약 없이 어디서든 동일한 코드로 인프라를 제어할 수 있는 유연한 환경이 구축되었다.&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-path-to-node=&quot;10&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;3. GitHub Actions 작성 &lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;마지막 단계는 이 모든 준비 작업을 하나로 엮는 CI/CD 파이프라인 구축이다. 단순히 코드를 배포하는 스크립트가 아니라, 설정 파일과 현재 인프라 상태를 비교하여 최적의 행동을 결정하는 '상태 기반(State-based) 파이프라인'을 구현했다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-path-to-node=&quot;5&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1) 목표 상태 vs 실제 상태 비교&lt;/b&gt;&lt;/p&gt;
&lt;p data-path-to-node=&quot;5&quot; data-ke-size=&quot;size16&quot;&gt;파이프라인이 트리거 되면 먼저 설정 파일(handlers-deploy.yml)이 정의하는 '목표 상태'와 현재 클러스터의 '실제 상태(Active Pods)'를 대조한다. 이 결과에 따라 다음 세 가지 액션 중 하나가 자동으로 결정된다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-path-to-node=&quot;6&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;START (신규 생성): 설정은 켜져(enabled: true) 있는데 파드가 없다면, Terraform을 실행하여 리소스를 생성한다.&lt;/li&gt;
&lt;li&gt;STOP (리소스 회수): 설정이 꺼져(enabled: false) 있는데 파드가 돌고 있다면, Terraform을 실행하여 리소스를 삭제(Destroy)한다.&lt;/li&gt;
&lt;li&gt;REDEPLOY (재배포): 설정도 켜져 있고 파드도 정상 동작 중이라면, Terraform을 거치지 않고 kubectl rollout restart를 수행해 이미지를 최신화한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-path-to-node=&quot;7&quot; data-ke-size=&quot;size16&quot;&gt;리소스의 생성과 삭제 같은 '무거운 작업'은 Terraform에 맡기되, 빈번하게 발생하는 단순 배포는 Kubectl로 처리하여 배포 속도와 효율을 모두 챙겼다.&lt;/p&gt;
&lt;p data-path-to-node=&quot;7&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-path-to-node=&quot;9&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2) 정교한 스케일링(Scaling)&lt;/b&gt;&lt;/p&gt;
&lt;p data-path-to-node=&quot;9&quot; data-ke-size=&quot;size16&quot;&gt;시퀀스 특히 재배포(Redeploy) 과정에서 파드의 개수(Replicas) 변경이 동반될 경우, 가용성 확보를 위해 실행 순서를 동적으로 조정하는 로직을 심었다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-path-to-node=&quot;10&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Scale Down (현재 &amp;gt; 목표): Scale Down &amp;rarr; Restart
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이유: 불필요한 파드를 먼저 정리하여 유휴 리소스를 확보한 뒤 재시작한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Scale Up (현재 &amp;lt; 목표): Restart &amp;rarr; Scale Up
&lt;ul style=&quot;list-style-type: disc;&quot; data-path-to-node=&quot;10,1,1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이유: 최신 이미지를 먼저 적용한 후 인스턴스를 늘려야 한다. 순서가 바뀌면 구버전(Buggy) 코드가 확장되는 문제가 발생할 수 있기 때문이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-path-to-node=&quot;11&quot; data-ke-size=&quot;size16&quot;&gt;이러한 로직을 GitHub Actions 워크플로우(github-action.yml)에 녹여냄으로써, 개발자는 복잡한 쿠버네티스 명령어를 몰라도 설정 파일만 관리하면 안전하게 서비스를 배포할 수 있게 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 시작--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>기타</category>
      <category>github</category>
      <category>k8s</category>
      <category>terraform</category>
      <author>비번변경</author>
      <guid isPermaLink="true">https://passwd.tistory.com/1471</guid>
      <comments>https://passwd.tistory.com/entry/%EC%9E%91%EC%97%85-%EA%B8%B0%EB%A1%9D-%EC%84%9C%EB%B9%84%EC%8A%A4-%EC%9D%B4%EC%A0%84-Docker-EKS#entry1471comment</comments>
      <pubDate>Wed, 28 Jan 2026 23:02:04 +0900</pubDate>
    </item>
    <item>
      <title>[Airflow] Connections에 옵션 추가</title>
      <link>https://passwd.tistory.com/entry/Airflow-Connections%EC%97%90-%EC%98%B5%EC%85%98-%EC%B6%94%EA%B0%80</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size23&quot;&gt;개요&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://passwd.tistory.com/entry/Airflow-Connections%EC%9D%B4%EB%9E%80&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;2025.08.25-[Airflow] Connections이란&lt;/a&gt;에서 Airflow와 외부 시스템 간의 연동을 위한 연결정보를 저장하는 Connection에 대해서 알아보았다. 평소에는 연결에 필요한 필수 정보 정도만 지정하고 사용하지만, 필요시에는 기타 추가적인 옵션도 지정할 필요가 있을 수 있다. 이번 글에서는 그런 부분에 대해 추가로 작성한다.&lt;/p&gt;
&lt;p style=&quot;float: none; clear: none;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt; &lt;span style=&quot;font-size: 21px;&quot;&gt;extra&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이전 글에서 extra가 하는 역할이 무엇인가 싶었는데, 이 extra가 바로 추가적인 구성 정보를 지정하는 속성이었다. extra는 json 형식으로 지정하려는 속성의 키와 값을 넣어주면 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;962&quot; data-origin-height=&quot;802&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/elfHcW/dJMcafZG69Y/Ek9tKZnEhXhGLRKhd0RuW1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/elfHcW/dJMcafZG69Y/Ek9tKZnEhXhGLRKhd0RuW1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/elfHcW/dJMcafZG69Y/Ek9tKZnEhXhGLRKhd0RuW1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FelfHcW%2FdJMcafZG69Y%2FEk9tKZnEhXhGLRKhd0RuW1%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;962&quot; height=&quot;802&quot; data-origin-width=&quot;962&quot; data-origin-height=&quot;802&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이 연결 정보는 URI 형식으로 확인할 수도 있는데 아래와 같은 형식이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1909&quot; data-origin-height=&quot;49&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cNQhyM/dJMcagYAPZO/JAHP0RP2eTOX3xV6eJPV5K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cNQhyM/dJMcagYAPZO/JAHP0RP2eTOX3xV6eJPV5K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cNQhyM/dJMcagYAPZO/JAHP0RP2eTOX3xV6eJPV5K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcNQhyM%2FdJMcagYAPZO%2FJAHP0RP2eTOX3xV6eJPV5K%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;1909&quot; height=&quot;49&quot; data-origin-width=&quot;1909&quot; data-origin-height=&quot;49&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1769387090639&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[
  {
    &quot;id&quot;: &quot;5&quot;,
    &quot;conn_id&quot;: &quot;test&quot;,
    &quot;conn_type&quot;: &quot;postgres&quot;,
    &quot;description&quot;: &quot;&quot;,
    &quot;host&quot;: &quot;127.0.0.1&quot;,
    &quot;schema&quot;: &quot;test&quot;,
    &quot;login&quot;: &quot;postgres&quot;,
    &quot;password&quot;: &quot;postgres&quot;,
    &quot;port&quot;: &quot;5432&quot;,
    &quot;is_encrypted&quot;: &quot;False&quot;,
    &quot;is_extra_encrypted&quot;: &quot;False&quot;,
    &quot;extra_dejson&quot;: {
      &quot;param1&quot;: &quot;val1&quot;,
      &quot;param2&quot;: &quot;val2&quot;
    },
    &quot;get_uri&quot;: &quot;postgres://postgres:postgres@127.0.0.1:5432/test?param1=val1&amp;amp;param2=val2&quot;
  }
]&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이런 점을 활용해 PostgreSQL과 같은 데이터베이스에 연결하는 경우, extra를 사용해 연결 타임아웃 등을 설정할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1769386525235&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{
  &quot;options&quot;: &quot;-c statement_timeout=2400000 -c lock_timeout=300000 -c idle_in_transaction_session_timeout=12h&quot;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt; &lt;span style=&quot;font-size: 21px;&quot;&gt;CLI 등으로 지정하기&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Airflow는 웹 UI가 생각보다 잘 되어 있어서 CLI를 사용할 일이 그렇게 잦지는 않은 것 같다. 하지만 Connections도 Connections.extra도 CLI나 환경 변로 관리할 수 있다는 점도 일단 기재해 둔다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;환경 변수&lt;/p&gt;
&lt;pre id=&quot;code_1769387355747&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;export AIRFLOW_CONN_MY_PROD_DATABASE='{
    &quot;conn_type&quot;: &quot;my-conn-type&quot;,
    &quot;login&quot;: &quot;my-login&quot;,
    &quot;password&quot;: &quot;my-password&quot;,
    &quot;host&quot;: &quot;my-host&quot;,
    &quot;port&quot;: 1234,
    &quot;schema&quot;: &quot;my-schema&quot;,
    &quot;extra&quot;: {
        &quot;param1&quot;: &quot;val1&quot;,
        &quot;param2&quot;: &quot;val2&quot;
    }
}'

# 또는
export AIRFLOW_CONN_MY_PROD_DATABASE='my-conn-type://login:password@host:port/schema?param1=val1&amp;amp;param2=val2'&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;CLI&lt;/p&gt;
&lt;pre id=&quot;code_1769387406067&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;airflow connections add 'my_prod_db' \
    --conn-json '{
        &quot;conn_type&quot;: &quot;my-conn-type&quot;,
        &quot;login&quot;: &quot;my-login&quot;,
        &quot;password&quot;: &quot;my-password&quot;,
        &quot;host&quot;: &quot;my-host&quot;,
        &quot;port&quot;: 1234,
        &quot;schema&quot;: &quot;my-schema&quot;,
        &quot;extra&quot;: {
            &quot;param1&quot;: &quot;val1&quot;,
            &quot;param2&quot;: &quot;val2&quot;
        }
    }'
    
# 또는
airflow connections add 'my_prod_db' \
    --conn-uri '&amp;lt;conn-type&amp;gt;://&amp;lt;login&amp;gt;:&amp;lt;password&amp;gt;@&amp;lt;host&amp;gt;:&amp;lt;port&amp;gt;/&amp;lt;schema&amp;gt;?param1=val1&amp;amp;param2=val2&amp;amp;...'
    
# 또는
airflow connections add 'my_prod_db' \
    --conn-type 'my-conn-type' \
    --conn-login 'login' \
    --conn-password 'password' \
    --conn-host 'host' \
    --conn-port 'port' \
    --conn-schema 'schema' \
    ...&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 시작--&gt;&lt;/p&gt;
&lt;h4 style=&quot;font-size: 10px; color: #1f1f1f; border-left: #ff327f 10px solid; margin: 0px 0px 10px; letter-spacing: -1px; line-height: normal; font-stretch: normal; padding: 0px 0px 0px 7px;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-size: 21px; color: #ff327f;&quot;&gt; 참고 문서&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://airflow.apache.org/docs/apache-airflow/2.8.4/howto/connection.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://airflow.apache.org/docs/apache-airflow/2.8.4/howto/connection.html&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Apache Airflow</category>
      <category>airflow</category>
      <author>비번변경</author>
      <guid isPermaLink="true">https://passwd.tistory.com/1472</guid>
      <comments>https://passwd.tistory.com/entry/Airflow-Connections%EC%97%90-%EC%98%B5%EC%85%98-%EC%B6%94%EA%B0%80#entry1472comment</comments>
      <pubDate>Tue, 27 Jan 2026 10:32:22 +0900</pubDate>
    </item>
    <item>
      <title>[Kafka] API로 커넥터 관리하기</title>
      <link>https://passwd.tistory.com/entry/Kafka-API%EB%A1%9C-%EC%BB%A4%EB%84%A5%ED%84%B0-%EA%B4%80%EB%A6%AC%ED%95%98%EA%B8%B0</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size23&quot;&gt;개요&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://passwd.tistory.com/entry/Kafka-Debezium-%EC%9D%B4%EB%9E%80&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;2025.12.29-[Kafka] debezium 이란&lt;/a&gt; 에서 Kafka 클러스터에 Debezium을 얹어보았는데, 실제로 커넥터를 생성하고 관리하는 방법에 대해서 정리가 좀 필요한 것 같아서 기록해 둔다.&lt;/p&gt;
&lt;p style=&quot;float: none; clear: none;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--헤드라인 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt; &lt;span style=&quot;font-size: 21px;&quot;&gt;Connectors 조회&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;커넥터 목록은 Kafka Connect API 엔드포인트에 GET 요청을 보내면 된다.&lt;/p&gt;
&lt;pre id=&quot;code_1769127309187&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;http://localhost:8083/connectors&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; 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;336&quot; data-origin-height=&quot;106&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Fa7Pe/dJMcafk5A5O/YZAnWxEa9f2e5r5ZtaKWok/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Fa7Pe/dJMcafk5A5O/YZAnWxEa9f2e5r5ZtaKWok/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Fa7Pe/dJMcafk5A5O/YZAnWxEa9f2e5r5ZtaKWok/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFa7Pe%2FdJMcafk5A5O%2FYZAnWxEa9f2e5r5ZtaKWok%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;336&quot; height=&quot;106&quot; data-origin-width=&quot;336&quot; data-origin-height=&quot;106&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아직 아무 커넥터를 만들지 않아 응답이 비어있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 시작--&gt;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt; &lt;span style=&quot;font-size: 21px;&quot;&gt;Conenctors 생성&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Kafka Connect API 엔드포인트에 POST 요청을 보낸다. request body에 생성할 커넥터의 정보를 전달해야 한다.&lt;/p&gt;
&lt;pre id=&quot;code_1769128062511&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;curl -i -X POST -H &quot;Accept:application/json&quot; -H  &quot;Content-Type:application/json&quot; http://localhost:8083/connectors/ -d @register-postgres.json&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;642&quot; data-origin-height=&quot;317&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bLDrff/dJMcadndvoS/H9Lvt3wGmm0h8CjtejBY5K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bLDrff/dJMcadndvoS/H9Lvt3wGmm0h8CjtejBY5K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bLDrff/dJMcadndvoS/H9Lvt3wGmm0h8CjtejBY5K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbLDrff%2FdJMcadndvoS%2FH9Lvt3wGmm0h8CjtejBY5K%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;642&quot; height=&quot;317&quot; data-origin-width=&quot;642&quot; data-origin-height=&quot;317&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--부제목사용1 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;Conenctors 상세 조회&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특정 커넥터의 정보를 조회하고 싶을 때는 Kafka Connect API 엔드포인트에 조회할 커넥터의 이름을 붙이면 된다.&lt;/p&gt;
&lt;pre id=&quot;code_1769128726426&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;curl http://localhost:8083/connectors/CONNECTOR_NAME&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;587&quot; data-origin-height=&quot;171&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/n3Ak5/dJMcaa49syt/nNWuDlJdzjn4NDRGn2wv11/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/n3Ak5/dJMcaa49syt/nNWuDlJdzjn4NDRGn2wv11/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/n3Ak5/dJMcaa49syt/nNWuDlJdzjn4NDRGn2wv11/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fn3Ak5%2FdJMcaa49syt%2FnNWuDlJdzjn4NDRGn2wv11%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;587&quot; height=&quot;171&quot; data-origin-width=&quot;587&quot; data-origin-height=&quot;171&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;커넥터를 구성하고 있는 설정 정보를 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;Conenctors 상태&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;특정 커넥터의 정보를 조회하고 싶을 때는&lt;span&gt;&amp;nbsp;&lt;/span&gt;Kafka Connect API 엔드포인트에 조회할 커넥터의 이름에 status로 접근한다.&lt;/p&gt;
&lt;pre id=&quot;code_1769128768486&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;curl http://localhost:8083/connectors/CONNECTOR_NAME/status&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;618&quot; data-origin-height=&quot;313&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5MRzk/dJMcahiUyHa/jNFOCsWb14KmOSN6pr53vk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5MRzk/dJMcahiUyHa/jNFOCsWb14KmOSN6pr53vk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5MRzk/dJMcahiUyHa/jNFOCsWb14KmOSN6pr53vk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5MRzk%2FdJMcahiUyHa%2FjNFOCsWb14KmOSN6pr53vk%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;618&quot; height=&quot;313&quot; data-origin-width=&quot;618&quot; data-origin-height=&quot;313&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;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;Conenctors 중지&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특정 커넥터의 동작을 중지하고 싶을 때는 pause 경로로 &lt;b&gt;PUT 요청&lt;/b&gt;을 보낸다.&lt;/p&gt;
&lt;pre id=&quot;code_1769129201949&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;curl -X PUT http://localhost:8083/connectors/CONNECTOR_NAME/pause&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요청 후 다시 상태를 확인하면 정상적으로 중지된 것을 확인할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;621&quot; data-origin-height=&quot;307&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/GwaOn/dJMcadHxnKp/sn58tIJGtdoaIoKiPVEp91/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/GwaOn/dJMcadHxnKp/sn58tIJGtdoaIoKiPVEp91/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/GwaOn/dJMcadHxnKp/sn58tIJGtdoaIoKiPVEp91/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGwaOn%2FdJMcadHxnKp%2Fsn58tIJGtdoaIoKiPVEp91%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;621&quot; height=&quot;307&quot; data-origin-width=&quot;621&quot; data-origin-height=&quot;307&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;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;Conenctors 재시작&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;중지한 커넥터를 재시작할 때는 resume로 PUT 요청을 보낸다.&lt;/p&gt;
&lt;pre id=&quot;code_1769129697650&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;curl -X PUT http://localhost:8083/connectors/CONNECTOR_NAME/resume&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;614&quot; data-origin-height=&quot;307&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zbPVM/dJMcadAKvPB/PYFRH21YU2aZdjyd4hKFZK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zbPVM/dJMcadAKvPB/PYFRH21YU2aZdjyd4hKFZK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zbPVM/dJMcadAKvPB/PYFRH21YU2aZdjyd4hKFZK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzbPVM%2FdJMcadAKvPB%2FPYFRH21YU2aZdjyd4hKFZK%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;614&quot; height=&quot;307&quot; data-origin-width=&quot;614&quot; data-origin-height=&quot;307&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다시 RUNNING 상태로 돌아왔다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #cccccc; padding: 3px 5px; border-left-style: solid; border-left-color: #55555b; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #5d5d5d;&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;Conenctors 삭제&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;커넥터를 삭제할 때는 커넥터 URL에 DELETE 요청을 보낸다.&lt;/p&gt;
&lt;pre id=&quot;code_1769130104600&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;curl -X DELETE http://localhost:8083/connectors/CONNECTOR_NAME&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;555&quot; data-origin-height=&quot;351&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yVywK/dJMb99SInHI/knkLHFAoTSf5rnXPhnF1b1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yVywK/dJMb99SInHI/knkLHFAoTSf5rnXPhnF1b1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yVywK/dJMb99SInHI/knkLHFAoTSf5rnXPhnF1b1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyVywK%2FdJMb99SInHI%2FknkLHFAoTSf5rnXPhnF1b1%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;555&quot; height=&quot;351&quot; data-origin-width=&quot;555&quot; data-origin-height=&quot;351&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 시작--&gt;&lt;/p&gt;
&lt;h4 style=&quot;font-size: 10px; color: #1f1f1f; border-left: #ff327f 10px solid; margin: 0px 0px 10px; letter-spacing: -1px; line-height: normal; font-stretch: normal; padding: 0px 0px 0px 7px;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-size: 21px; color: #ff327f;&quot;&gt; 참고 문서&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.confluent.io/kafka-connectors/debezium-postgres-source/current/overview.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.confluent.io/kafka-connectors/debezium-postgres-source/current/overview.html&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--문단 마지막 사용 끝--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Apache Kafka</category>
      <category>Kafka</category>
      <author>비번변경</author>
      <guid isPermaLink="true">https://passwd.tistory.com/1470</guid>
      <comments>https://passwd.tistory.com/entry/Kafka-API%EB%A1%9C-%EC%BB%A4%EB%84%A5%ED%84%B0-%EA%B4%80%EB%A6%AC%ED%95%98%EA%B8%B0#entry1470comment</comments>
      <pubDate>Mon, 26 Jan 2026 11:05:13 +0900</pubDate>
    </item>
  </channel>
</rss>