<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>아주그냥</title>
    <link>https://nikeisme827.tistory.com/</link>
    <description>(positive)</description>
    <language>ko</language>
    <pubDate>Sun, 9 Aug 2026 16:13:23 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>p퐝유p</managingEditor>
    <item>
      <title>RedisTemplate 없이 Jedis로 직접 Redis 연결해보기</title>
      <link>https://nikeisme827.tistory.com/104</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;☆ 기존 Redis 쓰는 방식&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;less&quot;&gt;&lt;code&gt;@Autowired
private RedisTemplate&amp;lt;String, String&amp;gt; redisTemplate;

redisTemplate.opsForValue().set(&quot;key&quot;, &quot;value&quot;);
redisTemplate.opsForValue().get(&quot;key&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;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;code&gt;application.yml&lt;/code&gt;에 host랑 port만 적으면 연결됐다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;spring:
  data:
    redis:
      host: localhost
      port: 6379&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;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;여기에 대한 내부 동작을 알아보고 싶어 직접 Redis를 연결해봤다.&lt;/span&gt;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;☆&lt;span&gt; &amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Jedis란?&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Jedis는 Java에서 Redis에 명령어를 직접 보낼 수 있게 해주는 클라이언트 라이브러리다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;사실 Spring Data Redis도 내부적으로 Jedis(또는 Lettuce)를 쓰고 있다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;우리가 &lt;code&gt;RedisTemplate&lt;/code&gt;을 쓸 때 그 아래에서 Jedis가 실제로 Redis 서버에 명령어를 보내고 있었던 거다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;armasm&quot;&gt;&lt;code&gt;입력한 코드
  &amp;rarr; RedisTemplate (Spring Data Redis가 감싸줌)
    &amp;rarr; Jedis / Lettuce
      &amp;rarr; Redis 서버&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;오늘은 중간 단계 RedisTemplate 를 건너뛰고 Jedis를 직접 쓴 거다.&lt;/span&gt;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;☆&lt;span&gt; &amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Redis 단일 연결해보기&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;arduino&quot;&gt;&lt;code&gt;public class UrlRepository {

    private final Jedis jedis;

    public UrlRepository() {
        this.jedis = new Jedis(&quot;localhost&quot;, 6379);
    }

    public void save(String code, String originalUrl) {
        jedis.set(&quot;url:&quot; + code, originalUrl);
    }

    public String findByCode(String code) {
        return jedis.get(&quot;url:&quot; + code);
    }
}&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;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;code&gt;jedis.set()&lt;/code&gt; = Redis &lt;code&gt;SET&lt;/code&gt; 명령어&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;code&gt;jedis.get()&lt;/code&gt; = Redis &lt;code&gt;GET&lt;/code&gt; 명령어&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;그냥 Redis 명령어가 그대로 보인다. &lt;code&gt;RedisTemplate&lt;/code&gt;이 숨겨주던 게 이거였구나 싶었다.&lt;/span&gt;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;☆ &lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Connection Pool로 연결해보기&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;요청 1 &amp;rarr; Jedis 연결 생성 &amp;rarr; 사용 중...
요청 2 &amp;rarr; 같은 Jedis 연결 사용 시도 &amp;rarr; 충돌!&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;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;더 심각한 건 이거다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;동시 요청 1000개
&amp;rarr; 연결 1000개 생성 시도
&amp;rarr; Redis 서버 부하 폭발!!&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;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;이를 해결하고자 Connection Pool을 연결해보았다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Connection Pool은 이렇게 동작한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;excel&quot;&gt;&lt;code&gt;미리 연결 N개 만들어놓고
요청 오면 &amp;rarr; 놀고 있는 연결 빌려줌 &amp;rarr; 다 쓰면 반납&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;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;code&gt;JedisPool&lt;/code&gt;을 적용했다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;arduino&quot;&gt;&lt;code&gt;public class UrlRepository {

    private final JedisPool jedisPool;

    public UrlRepository() {
        JedisPoolConfig poolConfig = new JedisPoolConfig();

        // 최대 연결 수: 동시에 Redis에 접근할 수 있는 최대 연결 개수
        poolConfig.setMaxTotal(10);

        // 최대 대기 연결 수: Pool에서 놀고 있는 연결 최대 개수
        poolConfig.setMaxIdle(5);

        // 최소 대기 연결 수: 항상 유지할 최소 연결 개수
        poolConfig.setMinIdle(2);

        // 연결 고갈 시 대기 여부
        poolConfig.setBlockWhenExhausted(true);

        this.jedisPool = new JedisPool(poolConfig, &quot;localhost&quot;, 6379);
    }

    public void save(String code, String originalUrl) {
        // try-with-resources: 사용 후 자동으로 Pool에 반납
        try (Jedis jedis = jedisPool.getResource()) {
            jedis.set(&quot;url:&quot; + code, originalUrl);
        }
    }

    public String findByCode(String code) {
        try (Jedis jedis = jedisPool.getResource()) {
            return jedis.get(&quot;url:&quot; + code);
        }
    }
}&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;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;code&gt;try-with-resources&lt;/code&gt;로 Jedis를 감싼 게 포인트다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;블록이 끝나면 자동으로 Pool에 반납된다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;반납 안 하면 연결이 고갈돼서 새 요청이 무한 대기하게 된다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;☆&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Spring Data Redis의 역할&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;직접 구현하고 나니 &lt;code&gt;RedisTemplate&lt;/code&gt; 뒤에 뭐가 있는지 보였다.&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;height: 118px;&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;thead&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;th style=&quot;height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;직접 구현&lt;/span&gt;&lt;/th&gt;
&lt;th style=&quot;height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Spring Data Redis&lt;/span&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;code&gt;new JedisPool(poolConfig, &quot;localhost&quot;, 6379)&lt;/code&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;code&gt;application.yml&lt;/code&gt;에 host, port만 작성&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;code&gt;jedisPool.getResource()&lt;/code&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;자동으로 연결 가져옴&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;code&gt;try-with-resources&lt;/code&gt;로 반납&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;자동으로 반납&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;code&gt;jedis.set(key, value)&lt;/code&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;code&gt;redisTemplate.opsForValue().set(key, value)&lt;/code&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;code&gt;jedis.get(key)&lt;/code&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;code&gt;redisTemplate.opsForValue().get(key)&lt;/code&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;i&gt;backend-labs 레포: &lt;a href=&quot;https://github.com/nikeisme/backend-labs&quot;&gt;https://github.com/nikeisme/backend-labs&lt;/a&gt;&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;</description>
      <author>p퐝유p</author>
      <guid isPermaLink="true">https://nikeisme827.tistory.com/104</guid>
      <comments>https://nikeisme827.tistory.com/104#entry104comment</comments>
      <pubDate>Sun, 31 May 2026 00:40:20 +0900</pubDate>
    </item>
    <item>
      <title>순수 Java로 HTTP 서버 구현해보기</title>
      <link>https://nikeisme827.tistory.com/103</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;순수 소켓으로 HTTP 서버를 구현해보았다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;AI와 함께 같이 살아가면서 깊은 사고를 하지 않는다. 아니 사고조차 하지 않으려한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;진짜 귀찮으면 AI가 써준 코드를 이유를 알아보려 하지도 않고 화이트박스 형식으로 기능만 구현이 되면 커밋을 때린다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;SpringBooot 없이, JPA 없이, 외부 웹 프레임워크 부재를 느끼면서 &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;계속 사고하는 방식으로 습관을 들이고자 위와 같은 것을 시도해보았다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;앞으로 이렇게 많이 까보는 호두까기가 될 것이다. 그래야 내가 시야가 넓어질 것 같기 때문.&lt;/span&gt;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;오늘 만든 것&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;xl&quot;&gt;&lt;code&gt;POST /shorten -&amp;gt; 긴 단축 URL을 단축 코드로 변환
GET /{code} -&amp;gt; 단축 코드로 원본 URL에 301 리다이렉트&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;프로젝트 구조&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;reasonml&quot;&gt;&lt;code&gt;url-shortener/
├── Main.java
├── server/
│   └── HttpServer.java
├── handler/
│   └── RequestHandler.java
├── service/
│   └── UrlShortenerService.java
├── repository/
│   └── UrlRepository.java
└── util/
    └── Base62.java&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;핵심 개념 1 - Base62 인코딩&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;URL 단축의 핵심은 긴 URL을 짧은 코드로 바꾸는 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;숫자를 62진수로 변환하는 방식을 쓴다. 0~9, a~&lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;z, A~Z 총 62개 문자를 사용한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;예를 들어, DB의 ID 값 '12345'를 Base62로 인코딩하면 'dnh' 같은 짧은 문자열이 된다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;arduino&quot;&gt;&lt;code&gt;public class Base62 {

    private static final String CHARACTERS = 
        &quot;0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ&quot;;
    private static final int BASE = 62;

    public static String encode(long id) {
        StringBuilder sb = new StringBuilder();
        while (id &amp;gt; 0) {
            sb.append(CHARACTERS.charAt((int) (id % BASE)));
            id /= BASE;
        }
        return sb.reverse().toString();
    }

    public static long decode(String code) {
        long result = 0;
        for (char c : code.toCharArray()) {
            result = result * BASE + CHARACTERS.indexOf(c);
        }
        return result;
    }
}&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;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;&amp;lt;실행 화면&amp;gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;- Base62로 인코딩 완료&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;338&quot; data-origin-height=&quot;206&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cFqK5P/dJMcagr8oqb/5A1VL99gbcfJ4wIAGKluIk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cFqK5P/dJMcagr8oqb/5A1VL99gbcfJ4wIAGKluIk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cFqK5P/dJMcagr8oqb/5A1VL99gbcfJ4wIAGKluIk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcFqK5P%2FdJMcagr8oqb%2F5A1VL99gbcfJ4wIAGKluIk%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;338&quot; height=&quot;206&quot; data-origin-width=&quot;338&quot; data-origin-height=&quot;206&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;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;- &lt;b&gt;Base62로 디코딩 완료&lt;/b&gt;&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;346&quot; data-origin-height=&quot;212&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/L1s5C/dJMcaijbs4W/G2471iFOFHGzK4KuSw9dU0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/L1s5C/dJMcaijbs4W/G2471iFOFHGzK4KuSw9dU0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/L1s5C/dJMcaijbs4W/G2471iFOFHGzK4KuSw9dU0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FL1s5C%2FdJMcaijbs4W%2FG2471iFOFHGzK4KuSw9dU0%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;346&quot; height=&quot;212&quot; data-origin-width=&quot;346&quot; data-origin-height=&quot;212&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;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;-&amp;nbsp;&lt;b&gt;Base62로 인코딩 &amp;rarr; 디코딩 &lt;b&gt;&lt;b&gt;&amp;rarr; &lt;b&gt;&lt;b&gt;인코딩&amp;nbsp;&lt;/b&gt;&lt;/b&gt;&lt;/b&gt;&lt;/b&gt;왕복 완료&lt;/b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;355&quot; data-origin-height=&quot;104&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9ffEc/dJMcaaFvgIx/IECTJnMQHd0QCa7MRCqhk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9ffEc/dJMcaaFvgIx/IECTJnMQHd0QCa7MRCqhk0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9ffEc/dJMcaaFvgIx/IECTJnMQHd0QCa7MRCqhk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9ffEc%2FdJMcaaFvgIx%2FIECTJnMQHd0QCa7MRCqhk0%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;355&quot; height=&quot;104&quot; data-origin-width=&quot;355&quot; data-origin-height=&quot;104&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;핵심 개념 2 - 순수 소켓 HTTP 서버&lt;/span&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;font-family: 'Noto Serif KR';&quot;&gt;Tomcat을 사용하면 아래와 같이 수행된다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;armasm&quot;&gt;&lt;code&gt;클라이언트 &amp;rarr; Spring Boot (Tomcat이 다 처리) &amp;rarr; 코드&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;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Tomcat 께서 해주셨던 것을 직접 구현하면 이렇게 된다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;클라이언트 &amp;rarr; ServerSocket &amp;rarr; RequestHandler &amp;rarr; 코드&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;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;HTTP 요청이 실제로 어떻게 생겼는지 처음 알았는데, 그냥 텍스트다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;http&quot;&gt;&lt;code&gt;POST /shorten HTTP/1.1
Host: localhost:8080
Content-Type: application/json
Content-Length: 37

{&quot;url&quot;:&quot;https://www.naver.com&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;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;이걸 직접 읽고 파싱해서 처리하는 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;java&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;public class HttpServer {

    private final int port; // 서버가 열릴 포트 번호 (8080)
    private final UrlShortenerService service; // URL 단축 비즈니스 로직
    private final ExecutorService threadPool; // 동시 요청 처리용 스레드 폴

    public HttpServer(int port) {
        this.port = port;
        this.service = new UrlShortenerService(); 
        // Java 21 - 기존 스레드보다 가볍고 수천 개 동시 처리 기능
        this.threadPool = Executors.newVirtualThreadPerTaskExecutor(); 

    public void start() throws IOException {
        // 지정한 포트를 열고, 클라이언트 연결 대기 시작
        ServerSocket serverSocket = new ServerSocket(port);
        System.out.println(&quot;서버 시작! 포트: &quot; + port);

        while (true) {
            // 클라이언트가 연결될 때까지 여기서 블로킹 대기
            Socket clientSocket = serverSocket.accept();

            // 연결된 클라이언트를 RequestHandler에게 위임
            // 스레드 폴이 처리하므로 메인 루프는 바로 다음 연결 대기로 복귀
            threadPool.submit(new RequestHandler(clientSocket, service));
        }
    }
}&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;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;여기서 &lt;code&gt;Executors.newVirtualThreadPerTaskExecutor()&lt;/code&gt;를 쓴 게 포인트다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Java 21의 Virtual Thread를 활용했는데, 기존 스레드보다 훨씬 가볍다. 동시 요청이 많아져도 버틸 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;핵심 개념 3 - RequestHandler&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;HttpServer가 클라이언트 연결을 받으면 RequestHandler한테 넘긴다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;RequestHandler가 하는 일은 딱 4가지다.&lt;/span&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;HTTP 요청 읽기&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;파싱 (메서드,경로 추출)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;라우팅&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;응답전송&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&quot;cs&quot;&gt;&lt;code&gt;@Override
public void run() {
    try (
        // 클라이언트가 보낸 데이터를 읽는 스트림
        BufferedReader in = new BufferedReader(
            new InputStreamReader(clientSocket.getInputStream()));
        // 클라이언트에게 데이터를 보내는 스트림
        PrintWriter out = new PrintWriter(clientSocket.getOutputStream())
    ) {
        // HTTP의 첫번째 줄을 읽기
        // ex) &quot;POST /shorten HTTP/1.1&quot; or &quot;GET /abc123 HTTP/1.1&quot;
        String requestLine = in.readLine(); // 연결은 됐지만 요청이 없는 경우 종료

        if (requestLine == null) return;

        // 공백으로 분리
        // parts[0] &amp;rarr; 메서드 (GET, POST)
        // parts[1] &amp;rarr; 경로 (/shorten, /abc123)
        // parts[2] &amp;rarr; HTTP 버전 (HTTP/1.1)
        String[] parts = requestLine.split(&quot; &quot;);
        String method = parts[0];
        String path = parts[1];

        // 라우팅 - 메서드 + 경로 조합으로 핸들러 결정
        // Spring Boot의 @PostMapping, @GetMapping 이 내부에서 하는 것과 동일
        if (method.equals(&quot;POST&quot;) &amp;amp;&amp;amp; path.equals(&quot;/shorten&quot;)) {
            handleShorten(in, out);
        } else if (method.equals(&quot;GET&quot;) &amp;amp;&amp;amp; !path.equals(&quot;/&quot;)) {
            handleRedirect(path, out);
        } else {
            sendResponse(out, &quot;404 Not Found&quot;, &quot;text/plain&quot;, &quot;Not Found&quot;);
        }

    } catch (IOException e) {
        e.printStackTrace();
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Spring Boot에서 &lt;code&gt;@PostMapping(&quot;/shorten&quot;)&lt;/code&gt;, &lt;code&gt;@GetMapping(&quot;/{code}&quot;)&lt;/code&gt; 이렇게 달았던 게 내부에서 이런 식으로 동작하고 있었던 거다.&lt;/span&gt;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Spring Boot와 비교해보기&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;직접 구현한 코드가 Spring Boot에서는 어떤 어노테이션으로 대체되는지 비교해보면 이렇다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;서버 시작 - &lt;code&gt;ServerSocket&lt;/code&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;// 우리가 직접 구현한 것
ServerSocket serverSocket = new ServerSocket(8080);

// Spring Boot에서는
@SpringBootApplication  // 내장 Tomcat이 자동으로 포트 열어줌
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}&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;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;&amp;lt;실행 화면&amp;gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;506&quot; data-origin-height=&quot;178&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bijY4T/dJMcahExNu9/sY7uFTZD7cQQCn6LsOY4sk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bijY4T/dJMcahExNu9/sY7uFTZD7cQQCn6LsOY4sk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bijY4T/dJMcahExNu9/sY7uFTZD7cQQCn6LsOY4sk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbijY4T%2FdJMcahExNu9%2FsY7uFTZD7cQQCn6LsOY4sk%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;227&quot; height=&quot;178&quot; data-origin-width=&quot;506&quot; data-origin-height=&quot;178&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;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;라우팅 - &lt;code&gt;method.equals(&quot;POST&quot;) &amp;amp;&amp;amp; path.equals(&quot;/shorten&quot;)&lt;/code&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;reasonml&quot;&gt;&lt;code&gt;// 우리가 직접 구현한 것
int contentLength = 0;
while (!(line = in.readLine()).isEmpty()) {
    if (line.startsWith(&quot;Content-Length:&quot;)) {
        contentLength = Integer.parseInt(line.split(&quot;: &quot;)[1].trim());
    }
}
char[] body = new char[contentLength];
in.read(body);

// Spring Boot에서는
@RequestBody Map&amp;lt;String, String&amp;gt; body  // 알아서 파싱해줌&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;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;응답 전송 - &lt;code&gt;out.print(&quot;HTTP/1.1 200 OK\r\n...&quot;)&lt;/code&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;stata&quot;&gt;&lt;code&gt;// 우리가 직접 구현한 것
out.print(&quot;HTTP/1.1 200 OK\r\n&quot;);
out.print(&quot;Content-Type: application/json\r\n&quot;);
out.print(&quot;Content-Length: &quot; + body.length() + &quot;\r\n&quot;);
out.print(&quot;\r\n&quot;);
out.print(body);
out.flush();

// Spring Boot에서는
return ResponseEntity.ok().body(Map.of(&quot;code&quot;, code));&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;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;301 리다이렉트&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;less&quot;&gt;&lt;code&gt;// 우리가 직접 구현한 것
out.print(&quot;HTTP/1.1 301 Moved Permanently\r\n&quot;);
out.print(&quot;Location: &quot; + originalUrl + &quot;\r\n&quot;);

// Spring Boot에서는
return ResponseEntity.status(HttpStatus.MOVED_PERMANENTLY)
        .location(URI.create(originalUrl))
        .build();&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Spring Boot가 편한 건 맞다. 근데 이걸 직접 짜보고 나니 어노테이션 뒤에 뭐가 있는지가 보인다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;실제 동작 확인&lt;/span&gt;&lt;/h2&gt;
&lt;pre class=&quot;vala&quot;&gt;&lt;code&gt;# URL 단축 요청
curl -X POST http://localhost:8080/shorten \
  -H &quot;Content-Type: application/json&quot; \
  -d '{&quot;url&quot;:&quot;https://www.naver.com&quot;}'

# 응답
{&quot;code&quot;:&quot;1&quot;}

# 리다이렉트 확인
curl -v http://localhost:8080/1

# 응답
HTTP/1.1 301 Moved Permanently
Location: https://www.naver.com&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;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;&amp;lt;실행 화면&amp;gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;- URL 단축 요청 &amp;rarr; code : 1 로 응답 확인&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;354&quot; data-origin-height=&quot;57&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/crtmMK/dJMcag6JF9W/VoEhIPs33kr6c95r26QSc0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/crtmMK/dJMcag6JF9W/VoEhIPs33kr6c95r26QSc0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/crtmMK/dJMcag6JF9W/VoEhIPs33kr6c95r26QSc0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcrtmMK%2FdJMcag6JF9W%2FVoEhIPs33kr6c95r26QSc0%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;354&quot; height=&quot;57&quot; data-origin-width=&quot;354&quot; data-origin-height=&quot;57&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;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;- 301 리다이렉트 확인&amp;nbsp;&amp;rarr;&amp;nbsp; 응답 확인&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;665&quot; data-origin-height=&quot;321&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bMONcg/dJMcaciVsks/IpYGm7uoua8iNURdtu4GzK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bMONcg/dJMcaciVsks/IpYGm7uoua8iNURdtu4GzK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bMONcg/dJMcaciVsks/IpYGm7uoua8iNURdtu4GzK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbMONcg%2FdJMcaciVsks%2FIpYGm7uoua8iNURdtu4GzK%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;466&quot; height=&quot;225&quot; data-origin-width=&quot;665&quot; data-origin-height=&quot;321&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;아니 그래가지구 결국&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;HTTP는 결국 텍스트 프로토콜이다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;그동안 Tomcat이 다 해줬기 때문에 HTTP 요청/응답이 어떻게 생겼는지도 몰랐다. 직접 파싱해보니 그냥 줄바꿈으로 구분된 텍스트라는 게 체감됐다.&lt;/span&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;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;Tomcat이 하는 일이 보였다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;포트 열고, 연결 받고, 요청 파싱하고, 응답 전송하고. 이걸 Tomcat이 다 해줬던 거다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;이제 &lt;code&gt;spring-boot-starter-web&lt;/code&gt; 의존성 추가하면 어떤 일이 일어나는지 머릿속에 그려진다.&lt;/span&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;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;AtomicLong의 필요성을 이해했다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;멀티스레드 환경에서 일반 &lt;code&gt;long&lt;/code&gt;을 쓰면 동시 요청 시 같은 코드가 두 개 생길 수 있다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;code&gt;AtomicLong&lt;/code&gt;의 &lt;code&gt;getAndIncrement()&lt;/code&gt;는 원자적으로 처리되기 때문에 이 문제가 없다.&lt;/span&gt;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;다음 단계&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;지금은 In-Memory (HashMap)에 저장하고 있어서 서버 재시작하면 데이터가 날아간다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;다음에는 Redis를 연결해서 영속성을 추가할 예정이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;계속 업데이트할 예정!&lt;/span&gt;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;i&gt;backend-labs 레포: &lt;a href=&quot;https://github.com/nikeisme/backend-labs&quot;&gt;https://github.com/nikeisme/backend-labs&lt;/a&gt;&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;</description>
      <author>p퐝유p</author>
      <guid isPermaLink="true">https://nikeisme827.tistory.com/103</guid>
      <comments>https://nikeisme827.tistory.com/103#entry103comment</comments>
      <pubDate>Thu, 28 May 2026 22:56:22 +0900</pubDate>
    </item>
    <item>
      <title>인프라 엔지니어가 매일 실행하는 리눅스 명령어들</title>
      <link>https://nikeisme827.tistory.com/102</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;일 평균 500만 건 로그를 수집하며 원활히 운영 중인 시스템에 문제가 생기면, &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;제일 먼저 드는 생각이 &quot;원래 아무 문제 없었는데&quot; 이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;근데 이런 생각을 하는 내가 싫다. 어디선가 잘못되었으니까 생기는 문제이기 때문이다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;어쩌면 회피형 + 불안형에서 비롯된 대사일지도... ㅎㅎ&lt;/span&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;text-align: start; color: #333333; font-family: 'Noto Serif KR';&quot;&gt;디버깅을 해보면 서버 환경 문제인 경우가 대다수였다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;text-align: start; color: #333333; font-family: 'Noto Serif KR';&quot;&gt;인프라 쪽을 의심하려고 해도 증거를 갖고 의심해야 하고, 이제 서버도 항상 모니터링이 필요하다고 생각이 들어&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;text-align: start; color: #333333; font-family: 'Noto Serif KR';&quot;&gt;인프라 엔지니어가 매일 실행하는 리눅스 명령어를 눈에 익혀보려고 한다.&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;text-align: start; color: #333333; font-family: 'Noto Serif KR';&quot;&gt;★ 서버 상태 확인&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1779020808173&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;uptime  #서버 가동 시간 + 부하 평균 (load average)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1779020870674&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;top  # 실시간 프로세스 및 CPU/메모리 사용률
htop # top의 컬러 개선판 (별도 설치 필요)&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; background-color: #9feec3;&quot;&gt;&lt;b&gt;★ 디스크 / 메모리&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1779020949075&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;df -h  # 디스크 파티션별 사용량(human-readable)
free -h # 메모리 및 스왑 사용량&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;★ 네트워크&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1779021029746&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ip a # 네트워크 인터페이스 및 IP 주소 목록
ip r # 라우팅 테이블
ss -tlnp # 리스닝 중인 포트 및 해당 프로세스&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; background-color: #9feec3;&quot;&gt;&lt;b&gt;★ 서비스 관리&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1779021133101&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;systemctl status &amp;lt;서비스명&amp;gt; # 특정 서비스 상태 확인
systemctl --failed # 실패한 서비스 전체 목록
jouranlctl -u &amp;lt;서비스명&amp;gt; -f #실시간 서비스 로그 스트리밍&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; background-color: #9feec3;&quot;&gt;&lt;b&gt;★ 커널 / 보안&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1779021207031&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;dmesg | tail # 최근 커널 메시지 (하드웨어 오류, 네트워크 이슈 등)
last # 최근 로그인 기록 (누가 언제 접속했는지)&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;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;★ 정리&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- 서버 응답이 느릴 때 &amp;rarr; uptime으로 load average 확인 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&amp;rarr; top으로 범인 프로세스 찾기&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start; font-family: 'Noto Serif KR';&quot;&gt;- 디스크 꽉 찼다는 추측이 들 때 &amp;rarr; df -h 로 어느 파티션인지 확인&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start; font-family: 'Noto Serif KR';&quot;&gt;- 서비스 갑자기 안될 때 &amp;rarr; systemctl --failed 먼저, 그 다음 journalctil -u &amp;lt;서비스명&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start; font-family: 'Noto Serif KR';&quot;&gt;- 외부에서 접속이 안될 때 &amp;rarr; ss -tnlp 로 포트 열려있는지 확인&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;실시간 대용량 처리는 많은 범위의 공부가 필요하다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;앞으로 하나하나씩 익혀가며 성장하자&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;화이티잉&lt;/span&gt;&lt;/p&gt;</description>
      <category>차곡차곡/dev-log</category>
      <author>p퐝유p</author>
      <guid isPermaLink="true">https://nikeisme827.tistory.com/102</guid>
      <comments>https://nikeisme827.tistory.com/102#entry102comment</comments>
      <pubDate>Sun, 17 May 2026 21:43:04 +0900</pubDate>
    </item>
    <item>
      <title>SELECT 쿼리에 ORDER BY를 꼭 써야 하는 이유 (+ 페이징까지)</title>
      <link>https://nikeisme827.tistory.com/101</link>
      <description>&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;업무 중에 거래로그를 적재하는 테이블에서&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;데이터를 감지(폴링)하는 SELECT 쿼리를 짜다가, ORDER BY가 왜 중요한지 제대로 이해하게 되었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;아~ 실시간으로 폴링을 하니까 더 단단한 순차적 폴링을 위해 ORDER BY 를 하는곤가? 추측했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;하지만!! 생각보다 훨씬 중요한 이유가 있었다.&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; background-color: #9feec3;&quot;&gt;&lt;b&gt;☆ ORDER BY가 없으면 무슨 일이 생길까?&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre class=&quot;sql&quot;&gt;&lt;code&gt;-- 이렇게 쓰면 안 된다
SELECT * FROM trade_log LIMIT 10;&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;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;얼핏 보면 문제없어 보인다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;그런데 DB는 ORDER BY가 없으면 자기 마음대로 순서를 정한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;오늘은 PK 순서대로 줄 수 있고, 내부 인덱스 상태나 실행 계획에 따라 내일은 다른 순서를 줄 수도 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;같은 쿼리인데 실행할 때마다 결과 순서가 다를 수 있다는 뜻이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;거래로그처럼 &lt;b&gt;시간 순서나 일련번호 순서가 의미 있고, 수억건이 있는 데이터&lt;/b&gt;에서 문제가 일어나면 걷잡을 수 없다.&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;sql&quot;&gt;&lt;code&gt;-- 이렇게 써야 한다
SELECT * FROM trade_log ORDER BY seq LIMIT 10;&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;근데 ORDER BY만 넣는다고 끝이 아니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;-- Page 1
SELECT * FROM trade_log ORDER BY seq DESC LIMIT 10 OFFSET 0;

-- Page 2
SELECT * FROM trade_log ORDER BY seq DESC LIMIT 10 OFFSET 10;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;ORDER BY도 넣었고, LIMIT/OFFSET도 썼다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;완벽해 보이지만.... 씹던 껌으로 막아놓은 구멍 송송 뚫린 파이프라인이다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; background-color: #9feec3;&quot;&gt;&lt;b&gt;☆ 데이터는 계속 변한다&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Page 1을 조회하는 사이에 데이터가 삭제됐다고 해보자.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;조회 전: seq 10, 9, 8, 7, 6, 5, 4, 3, 2, 1

Page 1 조회 &amp;rarr; 10, 9, 8, 7, 6 반환

이 사이에 seq 10 삭제됨

Page 2 조회 (OFFSET 10) &amp;rarr; 4, 3, 2, 1&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;seq 5번이 어디 갔지? &lt;b&gt;Page 1에도 없고 Page 2에도 없다. 그냥 누락된 거다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;반대로 새 데이터가 추가되면 같은 row가 두 페이지에 중복으로 나오기도 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;거래로그에서 특정 건이 조회 안 된다? 운영 중인 서비스에서 이런 일 생기면 꽤 심각하다.&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; background-color: #9feec3;&quot;&gt;&lt;b&gt;☆ 제대로 된 해법: 커서 기반 페이징&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;OFFSET 대신 &lt;b&gt;마지막으로 본 데이터의 기준값&lt;/b&gt;을 조건으로 넘기는 방식이다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;sql&quot;&gt;&lt;code&gt;-- 처음 조회
SELECT * FROM trade_log ORDER BY seq DESC LIMIT 10;

-- 다음 페이지: 마지막으로 받은 seq를 기준으로
SELECT * FROM trade_log WHERE seq &amp;lt; :lastSeq ORDER BY seq DESC LIMIT 10;&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;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;이렇게 하면:&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;중간에 데이터가 삭제돼도 누락 없음&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;새 데이터가 추가돼도 중복 없음&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;뒤 페이지로 갈수록 느려지는 문제도 없음 (OFFSET 100000 같은 풀스캔 방지)&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;PK가 일련번호인 테이블에서 특히 잘 맞는 방식이다.&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; background-color: #9feec3;&quot;&gt;&lt;b&gt;☆ 정리&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;table style=&quot;height: 79px;&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style16&quot;&gt;
&lt;thead&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;th style=&quot;height: 19px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;문제&lt;/span&gt;&lt;/th&gt;
&lt;th style=&quot;height: 19px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;원인&lt;/span&gt;&lt;/th&gt;
&lt;th style=&quot;height: 19px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;해결&lt;/span&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;매번 순서가 다름&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;ORDER BY 없음&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;ORDER BY 추가&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;페이지 이동 시 누락/중복&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;OFFSET 기반 페이징&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;커서 기반으로 교체&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;뒤 페이지 조회 느림&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;OFFSET 큰 값&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;커서 기반으로 교체&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;ORDER BY는 시작일 뿐이고, 페이징까지 제대로 하려면 커서 기반까지 고려해야 한다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;</description>
      <category>차곡차곡/dev-log</category>
      <author>p퐝유p</author>
      <guid isPermaLink="true">https://nikeisme827.tistory.com/101</guid>
      <comments>https://nikeisme827.tistory.com/101#entry101comment</comments>
      <pubDate>Tue, 12 May 2026 21:22:02 +0900</pubDate>
    </item>
    <item>
      <title>Claude API로 Git 작업 자동화해봤다 (브랜치명, 커밋, PR까지)</title>
      <link>https://nikeisme827.tistory.com/99</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;사이드 프로젝트 하면서 Git 작업이 점점 번거로워졌다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;왜냐하면 점점 낮아지는 나의 작문 실력 때문이었다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;원활한 공유를 위해 팀원들에게 나의 작업을 간결하면서도 가독성이 높게 pr을 진행하고 싶었는데&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt; 나의 작문 실력은 날로 증발했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;그리고 때때로, 브랜치명 지을 때마다 컨벤션 문서 찾아보고, &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;커밋 메시지는 대충 fix 때려박고, PR 본문은 귀찮아서 비워두는 일이 반복됐다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;기능 구현보다 이런 부수적인 작업에 시간이 더 드는 느낌이랄까.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;그래서 요즘 대세이자 가족,친구들보다 내가 더 많이 찾는 Claude의 API를 붙여서 이걸 자동화해봤다.&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;★ CLAUDE.md 파일이란?&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Claude Code(Anthropic에서 만든 터미널용 Claude CLI)를 사용할 때,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;프로젝트 루트에 CLAUDE.md 파일을 놓으면 Claude가 자동으로 읽어서 컨텍스트로 활용한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1774966061339&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;프로젝트 루트/
├── CLAUDE.md   &amp;larr; Claude가 자동으로 읽는 컨텍스트 파일
├── src/
└── ...&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;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;매번 &quot;우리 브랜치 컨벤션은 이래, 커밋은 이렇게 써야 해&quot; 설명할 필요 없이,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이 파일 하나로 Claude가 프로젝트 맥락을 이해하고 그에 맞는 결과물을 뽑아준다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;뭔가 인수인계 할 때의 파일처럼 이 파일을 만들어놓으면 이 맥락으로 착착착 결과물이 나온다... 대박...&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;그래서 CLAUDE.md 파일을 만들어서 Clauder가 우리 프로젝트 맥락을 항상 이해하도록 설계했다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1774966302475&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 반듯서랍 &amp;mdash; Claude Context

## 브랜치 컨벤션
{type}/{kebab-case-description}
- feature: 신규 기능
- fix: 버그 수정
- refactor: 리팩토링
...

## 커밋 컨벤션
{type}: {설명}

## PR 형식
## What / ## Why / ## How&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;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이것만 해놓으면 &quot;내가 그때 말했자나!! &quot; 이런 말을 하지 않을 수 있다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; background-color: #9feec3;&quot;&gt;★ 만든 것들&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;우선, 아래 두 파일을 만들었다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1774966510607&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;scripts/
├── branch.py   &amp;larr; 작업 내용 &amp;rarr; 브랜치명 자동 생성
└── commit.py   &amp;larr; 파일 선택 &amp;rarr; 커밋 &amp;rarr; 충돌 체크 &amp;rarr; push &amp;rarr; PR 생성&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; background-color: #99cefa;&quot;&gt;&lt;b&gt;1. branch.py 실행&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;해당 파일은 브랜치 명을 생성해주고, checkout을 해준다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;아래 명령어로 실행된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Claude는 컨텍스트를 입력하기 때문에 최대한 &quot;&quot;에 들어가는 내용을 구체적으로 적어주는게 좋다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1774966583861&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;python3 scripts/branch.py &quot;브랜치를 생성하는 의의&quot; --checkout
--checkout 옵션 붙이면 선택 즉시 git checkout -b까지 해준다.&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;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;위의 명령어를 입력하면 아래와 같이 뜬다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;브랜치 명을 3가지 정도 만들어주고 선택하게 만들었다.&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;825&quot; data-origin-height=&quot;313&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dwXVjh/dJMcaax0RcL/KddFJ9Y4Qm1MK1NyDtozA1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dwXVjh/dJMcaax0RcL/KddFJ9Y4Qm1MK1NyDtozA1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dwXVjh/dJMcaax0RcL/KddFJ9Y4Qm1MK1NyDtozA1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdwXVjh%2FdJMcaax0RcL%2FKddFJ9Y4Qm1MK1NyDtozA1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;738&quot; height=&quot;280&quot; data-origin-width=&quot;825&quot; data-origin-height=&quot;313&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #99cefa;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;2. commit.py 실행&lt;/span&gt;&lt;/b&gt;&lt;/span&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;font-family: 'Nanum Gothic';&quot;&gt;이 녀석이 아주 요긴하다.&amp;nbsp; 한번 실행하면 커밋부터 PR생성까지 다 해준다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;변경된 파일 목록 보여주고 선택해서 add&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;diff 읽어서 커밋 메시지 3개 추천&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;main과 충돌 사전 감지&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;push 자동화&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;PR 본문 자동 생성 (What/Why/How)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;gh CLI로 PR 생성까지&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;아래의 명령을 실행한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1774966915143&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;python3 scripts/commit.py&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;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;실행 후, 아래와 같이 수행이된다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1774967512160&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;python3 scripts/commit.py
```

**흐름은 이렇다:**

**1. 변경된 파일 선택 &amp;rarr; git add**
```
변경된 파일 목록:
  [1] [수정] AuthService.java
  [2] [수정] JwtService.java

선택: a
```

**2. diff 읽어서 커밋 메시지 3개 추천**
```
  [1] feat: 로그아웃 API 및 토큰 블랙리스트 처리
  [2] feat: JWT 로그아웃 구현
  [3] refactor: AuthService 로그아웃 플로우 추가

번호 선택: 1
✅ 커밋 완료
```

**3. push 전 main과 충돌 사전 감지**

push하기 전에 `origin/main`을 fetch해서 충돌 여부를 미리 확인한다. 충돌이 있으면 push를 막고 해결 방법을 알려준다.
```
  main과 충돌 체크 중...
✅ 충돌 없음
  push 완료
```

**4. push 후 CI 링크 안내**

빌드와 테스트는 GitHub Actions가 알아서 돌려준다. 로컬에서 매번 빌드하면 너무 느리니까, push 후 CI 링크만 띄워주는 방식으로 설계했다.
```
  CI 확인: https://github.com/bandeutseolap/repo/actions
```

**5. PR 본문 자동 생성 &amp;rarr; PR 생성**

diff 전체를 Claude에게 넘겨서 What/Why/How 구조로 PR 본문을 뽑아준다. GitHub CLI(`gh`)와 연동해서 터미널에서 PR 생성까지 완료된다.
```
✅ PR 생성 완료!
   https://github.com/bandeutseolap/repo/pull/12&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;3. pull requests 확인&lt;/span&gt;&lt;/b&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;font-family: 'Nanum Gothic';&quot;&gt;commit.py 까지 완료되면, pr 이 생성된 내용으로 open 된 것을 확인할 수 있고, 확인은 github에서 진행된다.&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;1928&quot; data-origin-height=&quot;1378&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/3bpzs/dJMcaiJxmGB/dX93LA2xabTfuygqdUo3Nk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/3bpzs/dJMcaiJxmGB/dX93LA2xabTfuygqdUo3Nk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/3bpzs/dJMcaiJxmGB/dX93LA2xabTfuygqdUo3Nk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F3bpzs%2FdJMcaiJxmGB%2FdX93LA2xabTfuygqdUo3Nk%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;1928&quot; height=&quot;1378&quot; data-origin-width=&quot;1928&quot; data-origin-height=&quot;1378&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;★ 마치며&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이리저리 돌아다니며 어케 claude로 이런 것 까지 구현하지라는 생각이 많았고, 한편으로는 부러웠다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;우선 깃 브랜치/커밋 자동화로 클로드랑 한번 놀아본 결과, 내가 기획자가 되어야겠다 라는 생각이 되었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;계속 부족한 것 생각해내고, 사용성을 어케 높일까 생각의 연속이었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;계속 이 시스템에 대해서 보완점을 생각해서 품질을 높여야겠다.&lt;/span&gt;&lt;/p&gt;</description>
      <category>차곡차곡/dev-log</category>
      <author>p퐝유p</author>
      <guid isPermaLink="true">https://nikeisme827.tistory.com/99</guid>
      <comments>https://nikeisme827.tistory.com/99#entry99comment</comments>
      <pubDate>Wed, 1 Apr 2026 17:49:35 +0900</pubDate>
    </item>
    <item>
      <title>DFS vs BFS &amp;mdash; 지도 탐험으로 이해하기</title>
      <link>https://nikeisme827.tistory.com/98</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;☆ 상황 설정&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;아래와 같은 도시지도&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1774836349868&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;        1
      / | \
     2  5  9
     |  |\ \
     3  6 8 10
     |  |
     4  7&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;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;목표: &lt;b&gt;1번 도시에서 출발해서 모든 도시 방문하기&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; background-color: #99cefa;&quot;&gt;☆ DFS &amp;mdash; 길이 막힐 때까지 직진하는 탐험가&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;&quot;일단 한 방향으로 끝까지 파고들고, 막히면 돌아와서 다른 길&quot;&lt;/b&gt;&lt;/span&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;font-family: 'Nanum Gothic';&quot;&gt;1번 출발 &amp;rarr; 2 &amp;rarr; 3 &amp;rarr; 4&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;(4에서 막힘, 되돌아오기)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&amp;rarr; 5 &amp;rarr; 6 &amp;rarr; 7&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;(7에서 막힘, 되돌아오기)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&amp;rarr; 8&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;(8에서 막힘, 되돌아오기)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&amp;rarr; 9 &amp;rarr; 10&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1774836429137&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;방문 순서: 1 &amp;rarr; 2 &amp;rarr; 3 &amp;rarr; 4 &amp;rarr; 5 &amp;rarr; 6 &amp;rarr; 7 &amp;rarr; 8 &amp;rarr; 9 &amp;rarr; 10&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;한 우물만 끝까지 파는 스타일&amp;nbsp;&lt;/span&gt;&lt;/blockquote&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; background-color: #9feec3;&quot;&gt;&lt;b&gt;☆ BFS &amp;mdash; 주변부터 챙기는 탐험가&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&quot;지금 있는 곳 주변 다 돌고, 그 다음 거리 돌고, 또 그 다음...&quot;&lt;/span&gt;&lt;/b&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;font-family: 'Nanum Gothic';&quot;&gt;1번 출발&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&amp;rarr; 1 주변 먼저: &lt;b&gt;2, 5, 9&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&amp;rarr; 2 주변: &lt;b&gt;3&lt;/b&gt; / 5 주변: &lt;b&gt;6, 8&lt;/b&gt; / 9 주변: &lt;b&gt;10&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&amp;rarr; 3 주변: &lt;b&gt;4&lt;/b&gt; / 6 주변: &lt;b&gt;7&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1774836527968&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;방문 순서: 1 &amp;rarr; 2 &amp;rarr; 5 &amp;rarr; 9 &amp;rarr; 3 &amp;rarr; 6 &amp;rarr; 8 &amp;rarr; 10 &amp;rarr; 4 &amp;rarr; 7&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;돌 던지면 퍼지는 물결처럼 퍼져나가는 스타일&amp;nbsp;&lt;/span&gt;&lt;/blockquote&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;☆ 차이&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 15.5426%;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 34.3798%;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;DFS&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50.0775%;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;BFS&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 15.5426%;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;방식&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 34.3798%;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;끝까지 직진 후 되돌아오기&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50.0775%;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;가까운 것부터 차례로&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 15.5426%;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;구현&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 34.3798%;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;재귀 or 스택&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50.0775%;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;큐(Queue)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 15.5426%;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;용이성&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 34.3798%;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;경로 존재 여부, 미로 탈출&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50.0775%;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;최단 경로 찾기&lt;/span&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;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;☆ 비유로 기억하기&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;DFS&lt;/b&gt; = 집에서 리모컨 찾을 때 소파 쿠션 하나 다 뒤지고, 다음 쿠션 뒤지는 스타일&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;BFS&lt;/b&gt; = 일단 눈에 보이는 곳 다 훑고, 그 다음 범위 훑는 스타일&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;최단거리 문제 나오면 &amp;rarr; BFS&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;갈 수 있나 없나 문제 나오면 &amp;rarr; DFS or BFS 둘 다 가능&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;유형별 자료 구조&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 56.1628%; height: 76px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 11.5891%; height: 19px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 9.72867%; height: 19px;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;자료구조&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 34.8449%; height: 19px;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;이유&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 11.5891%; height: 19px;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;DFS&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 9.72867%; height: 19px;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;스택&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 34.8449%; height: 19px;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;되돌아가야&lt;/b&gt; 하니까 &amp;rarr; 마지막 것부터&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 38px;&quot;&gt;
&lt;td style=&quot;width: 11.5891%; height: 38px;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;BFS&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 9.72867%; height: 38px;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;큐&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 34.8449%; height: 38px;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;발견 순서대로&lt;/b&gt; 탐색해야 하니까 &amp;rarr; 처음 것부터&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>차곡차곡/Algorithms</category>
      <author>p퐝유p</author>
      <guid isPermaLink="true">https://nikeisme827.tistory.com/98</guid>
      <comments>https://nikeisme827.tistory.com/98#entry98comment</comments>
      <pubDate>Mon, 30 Mar 2026 11:18:06 +0900</pubDate>
    </item>
    <item>
      <title>전국 지도로 이해하는 그래프 표현</title>
      <link>https://nikeisme827.tistory.com/97</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;☆ 상황 설정&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;도시 4개 : 서울(0),인천(1),수원(2),대전(3)&lt;/span&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;font-family: 'Nanum Gothic';&quot;&gt;연결된 도시&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1774834717466&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;서울 - 인천 - 수원 - 대전&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;1. 인접 행렬 = 전국 도로 지도책&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;모든 도시 조합을 표에 다 박아놓고 O/X 표시&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1774834779940&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;서울  인천  수원  대전
서울  [  X    O    X    X  ]
인천  [  O    X    O    X  ]
수원  [  X    O    X    O  ]
대전  [  X    X    O    X  ]&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&quot;서울-수원 도로 있어?&quot; &amp;rarr; 지도책에서 바로 찍으면 된다. graph[0][2] &amp;rarr; X. O(1)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;근데 도시가 1000개면?&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;실제 도로가 몇 개 없어도 &lt;b&gt;1000&amp;times;1000 = 100만 칸&lt;/b&gt; 지도책을 만들어야 한다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;공간 O(N&amp;sup2;)&lt;/b&gt;&lt;/span&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;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;2. 인접 리스트 = 각 도시 관광안내소 팜플렛&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&quot;각 도시에서 갈 수 있는 곳만 적어놓기&quot;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1774834856258&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;서울 안내소   &amp;rarr; 인천만 적혀있음
인천 안내소   &amp;rarr; 서울, 수원 적혀있음
수원 안내소   &amp;rarr; 인천, 대전 적혀있음
대전 안내소   &amp;rarr; 수원만 적혀있음&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;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;도로 없는 조합은 아예 안 적으니까 팜플렛이 훨씬 얇아요.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;공간 O(N + 간선)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;근데 단점이 있다.&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&quot;서울-수원 도로 있어?&quot; &amp;rarr; 서울 안내소 팜플렛 펼쳐서 수원이 나올 때까지 쭉 읽어야 함. O(N)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;☆결론&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&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: 19px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 19px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 19px;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;지도책 (인접행렬)&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 19px;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;팜플렛(인접 리스트)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 19px;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;연결 확인&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 19px;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;바로 찍으면 됨 &lt;b&gt;O(1)&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 19px;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;팜플렛 읽어야 함 &lt;b&gt;O(N)&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 19px;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;공간&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 19px;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;100만 칸 &lt;b&gt;O(N&amp;sup2;)&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 19px;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;있는 것만 &lt;b&gt;O(N+간선)&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 19px;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;용이성&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 19px;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;도시 적고 확인 많을 때&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 19px;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;도시 많고 도로 듬성듬성할 때&lt;/span&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;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;시간을 아끼려면 지도책, 공간을 아끼려면 팜플렛 &lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>차곡차곡/Algorithms</category>
      <author>p퐝유p</author>
      <guid isPermaLink="true">https://nikeisme827.tistory.com/97</guid>
      <comments>https://nikeisme827.tistory.com/97#entry97comment</comments>
      <pubDate>Mon, 30 Mar 2026 10:45:11 +0900</pubDate>
    </item>
    <item>
      <title>[dev] 로그인 #2 - 인증 아키텍처 설계</title>
      <link>https://nikeisme827.tistory.com/96</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;구현하기 전에 나는 &quot;만약에&quot; 함정에 빠진다☺️&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; letter-spacing: 0px;&quot;&gt;물론, 일단 구현하는 것도 좋지만 &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이제 회사에서 뭣 좀 해봣다고 &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&quot;만약에 만약에 이런 경우에는 이것도 저것도 고려해야하지 않을까&quot;라는 생각이 꼬리에 꼬리를 문다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이러한 현상은 내가 알고 있는 지식과 사고를 넘어선 확장이라는 긍정 작용도 발동하지만,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;과하게 생각해 말그대로 산으로 가기 때문에 항상 다시 중심으로 돌아와서 본질을 생각하는 습관을 들여야겠다는 다짐을 한다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;background-color: #9feec3; font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;☆ 설계 전에 정해야할 것들&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;코드 짜기 전, 세가지를 먼저 결정해야했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;1. Access Token 만료 시간&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;2. Refresh Token 만료 시간&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;3. Redis에 Refresh Token을 어떤 키로 저장할 것 인가&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #99cefa;&quot;&gt;★ Access Token 만료 시간 &amp;mdash; 1시간&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style=&quot;background-color: #99cefa;&quot;&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;- Access Token은 짧을수록 보안에 유리하다. 탈취되더라도 유효시간이 짧으면 피해범위가 줄어들기 때문이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&amp;nbsp; 어차피 Refresh Token 으로 자동 재발급하니까 사용자는 만료를 체감하지 못한다.&lt;/span&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;font-family: 'Nanum Gothic';&quot;&gt;&amp;nbsp; 처음엔 2시간으로 잡았다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&amp;nbsp; 하지만 해당 협업 툴 프로젝트는 하루종일 켜두는 서비스라는 것을 고려하면 Access Tokend은 짧게 가져가는 것이 맞다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&amp;nbsp; 보안과 UX를 분리해서 생각하면&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&amp;nbsp; &lt;b&gt;보안은 Access Token 짧게, UX는 Refresh Token 길게&lt;/b&gt; &amp;mdash; 가 정답이다. &lt;b&gt;1시간&lt;/b&gt;으로 조정했다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000; background-color: #99cefa;&quot;&gt;&lt;b&gt;★ Refresh Token 만료 시간 &amp;mdash; 14일&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Refresh Token은 Access Token이 만료됐을 때 재발급받기 위한 토큰이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt; Redis에서 관리하기 때문에 탈취되더라도 서버에서 즉시 무효화할 수 있다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;제어권이 서버에 있으니 길게 가져가도 부담이 없다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Slack, Notion, Jira 같은 협업 툴들이 로그아웃을 거의 안 시키는 이유가 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt; 출근해서 켜놓고 하루종일 쓰는 서비스에서 갑자기 재로그인을 요구하면 UX가 크게 나빠진다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;그리고 실 업무에서도 현업이 SSO,SyncUser등을 선호하는 것으로 보아 &lt;br /&gt;로그아웃 시간 제한은 최소화로 방향을 잡는게 나을 것 같다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이로써, 14일로 정했고&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;2주 이상 접속이 없으면 재로그인을 요구하는 게 자연스럽다고 판단했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000; background-color: #99cefa;&quot;&gt;&lt;b&gt;★ Redis 키 구조 - userId 기반&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Redis에 Refresh Token을 저장할 때 키를 어떻게 잡을지가 중요하다. 후보는 세 가지로 추려봤다.&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;1. userId - 사용자 식별 id 그대로&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. email - 로그인 ID로 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. uuid - 별도 발급&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;email은 변경 가능성이 있어서 키로 쓰기엔 불안정하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;uuid를 별도 발급하면 추적이 어렵고 관리 포인트(userId 매핑 등)가 늘어난다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;userId는 불변이고 조회가 단순하다.&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_1774499904863&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;RT:{username}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사내 솔루션으로 컨셉을 잡았고, 특성상 아이디 변경 기능이 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;username이 사실상 불변이라 userId 대신 username을 키로 써도 안정적이라고 판단했다. 단순하고 조회도 직관적이다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;background-color: #9feec3; font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;☆ 최종 아키텍처 구조 (변경 가능성 매우 많음)&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1774500211937&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[클라이언트]
    |
    | 로그인 요청 (ID/PW)
    ▼
[서버] 인증 성공
    ├── Access Token 발급 (1시간)
    └── Refresh Token 발급 &amp;rarr; Redis 저장 (14일 TTL)
            키: refresh:userId:{userId}
    |
    | Access Token 헤더에 담아 API 요청
    ▼
[서버] 토큰 검증
    ├── 유효 &amp;rarr; 요청 처리
    └── 만료 &amp;rarr; Refresh Token으로 재발급 요청
            Redis 조회 &amp;rarr; 일치하면 Access Token 재발급
            Redis 조회 &amp;rarr; 없으면 (만료 or 로그아웃) &amp;rarr; 재로그인 요구
    |
    | 로그아웃
    ▼
[서버] Redis에서 해당 userId 키 삭제
       &amp;rarr; Refresh Token 즉시 무효화&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;background-color: #9feec3; font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;☆ 이 시점의 고민 사항&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;설계를 마치고 나서 두 가지 고민이 남았다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;1. Redis 키 구조&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;- userId를 키로 쓰면 &lt;b&gt;한 계정에 하나의 Refresh Token만 유지&lt;/b&gt;된다. &lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;같은 계정으로 여러 기기에서 로그인하면 마지막 로그인이 이전 것을 덮어쓴다. &lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;다중 기기 세션을 지원하려면 키 구조를 refresh:userId:{userId}:{deviceId} 형태로 확장해야한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;팀원들과 머리를 맞댈 필요가 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;2. 추후 Kafka로 인증 이벤트를 집계할 가능성이 있어서 uuid 기반 키 구조를 고민했다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&amp;nbsp; &amp;nbsp; - uuid를 키로 쓰는 게 의미 있는 경우는 &lt;b&gt;다중 기기 세션 + 보안 강화&lt;/b&gt;가 동시에 필요할 때다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; 같은 userId로 여러 기기에서 로그인했을 때 각각 독립적으로 관리할 수 있다는 장점이 있다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; 사내 솔루션 컨셉이라 다중 기기 세션이 필수는 아니지만, 확장 가능성은 열어둘 필요가 있다고 생각한다.&lt;/span&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;font-family: 'Nanum Gothic';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; Kafka 집계 관점에서 필요한 건 키 구조가 아니라 이벤트 설계다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; 로그인/로그아웃 이벤트를 Kafka로 흘려보내면 consumer에서 처리하면 되고, Redis 키 구조와는 별개로 움직인다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; uuid를 쓰면 오히려 consumer 쪽에서 uuid &amp;rarr; userId 매핑을 따로 해야 해서 복잡도만 늘어난다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; Redis 키는 지금 구조 그대로 가져가되, 다중 기기 세션 지원 여부는 팀원들과 논의해봐야겠다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>차곡차곡/dev-log</category>
      <author>p퐝유p</author>
      <guid isPermaLink="true">https://nikeisme827.tistory.com/96</guid>
      <comments>https://nikeisme827.tistory.com/96#entry96comment</comments>
      <pubDate>Thu, 26 Mar 2026 14:30:51 +0900</pubDate>
    </item>
    <item>
      <title>[dev] 로그인 #1 - JWT와 Redis를 콤비네이션하기</title>
      <link>https://nikeisme827.tistory.com/95</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; background-color: #9feec3; font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;☆ 시작하게 된 이유&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;쿠키 기반 세션 방식이 보안 이슈로 지양되는 추세라는 것을 인지하고 있었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;CSRF 취약점, 도메인이 달라지면 CORS와 엮이는 문제, 모바일 환경에서의 관리 복잡도. 절대적인 이유는 아니지만, &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;새로 설계하는 시점에 굳이 이 복잡도를 안고 갈 필요는 없다고 판단했다.&lt;/span&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;font-family: 'Nanum Gothic';&quot;&gt;그래서 인증 방식을 처음부터 다시 고민했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt; JWT로 방향을 잡았지만 그것만으로는 부족했다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Refresh Token 관리에서 다시 막혔고, 결국 Redis와 조합하는 구조로 설계하게 됐다.&lt;/span&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;font-family: 'Nanum Gothic';&quot;&gt;JWT 만으로 부족한 이유&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;JWT를 쓰면 서버에 상태를 두지 않아도 된다. - 이게 장점이자 함정&lt;/span&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;font-family: 'Nanum Gothic';&quot;&gt;Access Token 만료 시간을 길게 가져가면 탈취되었을 때 대응이 없다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;짧게 가져가면 UX가 나빠진다. 그래서 Refresh Token을&amp;nbsp; 도입했는데 여기서 문제가 생긴다.&lt;/span&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;font-family: 'Nanum Gothic';&quot;&gt;Refresh Token을 클라이언트에만 두면 서버가 제어권을 잃는다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;토큰 탈취 시 강제 무효화 불가&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;로그아웃해도 토큰 만료 전까지 유효&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;다중 기기 세션 관리 불가&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;결국 Refresh Token은 서버 측에 저장해야 했고, 그 순간 &quot;완전한 Stateless&quot;는 포기한 거다. 대신 &lt;b&gt;통제 가능한 구조&lt;/b&gt;를 얻었다.&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000; font-family: 'Nanum Gothic';&quot;&gt;☆ &lt;/span&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;DB 말고 Redis를 선택한 이유&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Refresh Token 저장소로 MySQL도 고려했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;근데 인증은 서비스에서 가장 빈번하게 호출되는 경로다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;매 갱신 요청마다 디스크 I/O가 발생하는 건 불필요한 부하다.&lt;/span&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;font-family: 'Nanum Gothic';&quot;&gt;Redis를 선택한 이유는 세 가지다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;첫째, 인메모리라 조회 속도가 압도적으로 빠르다. &lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;둘째, TTL을 걸면 만료 처리를 Redis가 알아서 해준다 &amp;mdash; 별도 배치나 스케줄러가 필요 없다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt; 셋째, 로그아웃은 해당 키를 삭제하면 끝이다. 구현이 단순해진다.&lt;/span&gt;&lt;/b&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;font-family: 'Nanum Gothic';&quot;&gt;회사 솔루션이 같은 구조를 쓰는 걸 이제는 &quot;당연하다&quot;고 느낀다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; background-color: #9feec3;&quot;&gt;&lt;b&gt;☆정리&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;table style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px; border-collapse: collapse; width: 67.2093%; height: 101px;&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: 20.6705%; height: 21px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 27.1589%; height: 21px; text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;선택&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 52.1705%; height: 21px; text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이유&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20.6705%; height: 17px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;인증 방식&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 27.1589%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;JWT&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 52.1705%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Stateless, 수평 확장 고려&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20.6705%; height: 17px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Access Token&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 27.1589%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;1시간&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 52.1705%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;탈취 피해 범위 최소화&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20.6705%; height: 17px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Refresh Token&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 27.1589%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Redis, 7일 TTL&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 52.1705%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;빠른 조회 + 자동 만료 + 즉시 무효화&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20.6705%; height: 17px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;로그아웃&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 27.1589%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Redis 키 삭제&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 52.1705%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;서버 제어권 확보&lt;/span&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;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;완전한 Stateless는 아니다. 하지만 Redis 한 곳만 바라보는 구조는 관리 포인트가 명확하고, 이후 MSA 전환 시에도 인증 서버를 분리하기 수월하다. 그게 이 선택의 핵심 이유다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;다음 편은 이 구조를 바탕으로 한 실제 아키텍처 설계 과정을 기록한다.&lt;/span&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;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;** 여담 **&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이거 기가맥힌 표현이라 기록한다. 나중에 써먹어야지 ㅋㅋㅋㅋㅋㅋ&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Stateful&lt;/b&gt; &amp;rarr; 단골 카페. 사장님이 &quot;이 손님은 아메리카노 즐겨 마심&quot;을 기억하고 있음&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Stateless&lt;/b&gt; &amp;rarr; 처음 가는 카페. 매번 &quot;아메리카노 한 잔 주세요&quot;라고 직접 말해야한다. 카페는 아무것도 기억 안하고 있다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>차곡차곡/dev-log</category>
      <author>p퐝유p</author>
      <guid isPermaLink="true">https://nikeisme827.tistory.com/95</guid>
      <comments>https://nikeisme827.tistory.com/95#entry95comment</comments>
      <pubDate>Thu, 26 Mar 2026 10:54:29 +0900</pubDate>
    </item>
    <item>
      <title>JWT + Redis로 로그인 구현하기 끄적끄적용</title>
      <link>https://nikeisme827.tistory.com/94</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;사이드 프로젝트에서 로그인 기능을 구현하면서 JWT와 Redis를 함께 사용하는 방식을 선택했다.&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;☆ JWT&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- JWT (Json Web Token)은 사용자 인증 정보를 JSON 형태로 담아 서명한 토큰이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 서버가 DB를 조회하지 않아도 토큰 자체에서 사용자 정보를 검증할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 구조는 Header / Payload / Signature 세 파트로 나뉜다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; color: #000000; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Header&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;: 알고리즘 종류 (HS256 등) + 타입&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Payload&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;: 실제 데이터 (userId, roles, 만료시간 등)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Signature&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;: Header + Payload를 secret key로 서명한 값&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 서버의 Secret Key 로 서명되어 위변조를 막을 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;☆ Redis&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 인메모리 key-value 저장소로, 디스크 DB 대비 수백 배 빠른 읽기와 쓰기가 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 만료 시간을 key마다 설정할 수 있어서 토큰 관리에 적합하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;☆ 왜 Redis + JWT 조합인가?&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 93px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 19px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 19px;&quot;&gt;JWT 단독&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 19px;&quot;&gt;JWT + Redis&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 19px;&quot;&gt;로그아웃&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 19px;&quot;&gt;토큰 만료까지 유효&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 19px;&quot;&gt;즉시 무효화 가능&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 19px;&quot;&gt;성능&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 19px;&quot;&gt;DB 조회 없음&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 19px;&quot;&gt;Redis 조회&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;Refresh Token&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;관리 어려움&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;Redis TTL로 자동 만료&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 19px;&quot;&gt;구현 복잡도&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 19px;&quot;&gt;단순&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 19px;&quot;&gt;Redis 인프라 필요&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;JWT 단독으로는 토큰을 서버에서 강제 무효화할 수 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Redis를 추가하면 로그아웃&amp;middot;보안 이슈 시 즉시 차단이 가능해지고, Refresh Token 관리도 TTL 하나로 해결된다.&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;☆ Redis TTL 이란?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- TTL은 &lt;b&gt;Time To Live&lt;/b&gt;의 약자로, Redis에 저장한 데이터에 &quot;이 키는 N초 후에 자동으로 삭제해&quot; 라고 수명을 정해주는 기능이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 예를 들어, Refresh Token을 Redis 에 저장했을 때, TTL 없이 그냥 저장하면 로그아웃하지 않는 한 영원히 남아있다.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; TTL을 걸어두면 14일 후에 자동으로 키가 사라지니까 별도로 정리하는 로직이 필요하지 않다는 것이 장점이다.&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;application.yml 에 jwt에 대한 AT(Access Token), RT(Refresh Token) 만료에 대한 설정을 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 설정값은 redis에 저장된 순간부터 카운트다운이 시작된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock floatLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;716&quot; data-origin-height=&quot;220&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bQfpwy/dJMcajauTl3/wVCQHvXvQKPR4P6Ge30WZ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bQfpwy/dJMcajauTl3/wVCQHvXvQKPR4P6Ge30WZ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bQfpwy/dJMcajauTl3/wVCQHvXvQKPR4P6Ge30WZ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbQfpwy%2FdJMcajauTl3%2FwVCQHvXvQKPR4P6Ge30WZ1%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;439&quot; height=&quot;220&quot; data-origin-width=&quot;716&quot; data-origin-height=&quot;220&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 설정을 바탕으로&lt;br /&gt;아래와 같이 흐름도를 계획했다.&lt;/p&gt;
&lt;pre id=&quot;code_1774341203129&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Value(&quot;${jwt.refresh-expiration}&quot;)
private long refreshExpiration;
```
위의처럼 만료일에 대한 변수를 설정하면,
아래의 흐름은 이렇게 된다
```
application.yml
  jwt.refresh-expiration: 1209600000
          &amp;darr;
  @Value로 주입
          &amp;darr;
  .set(&quot;RT:user&quot;, token, 1209600000, MILLISECONDS)
          &amp;darr;
  Redis에 TTL 14일로 저장&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;우선 아래는 내가 설계한 Auth 의 흐름대로 도표를 만들어달라고&amp;nbsp; 클로드한테&amp;nbsp; 도움을 요청했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;너무 좋네 직접 안만들어도 되고 훟후후후ㅜㅎ훗 기특한녀석&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1396&quot; data-origin-height=&quot;1320&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CFaSJ/dJMcaaYXsi1/CINH00UGTGdmeJQ0jES4R1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CFaSJ/dJMcaaYXsi1/CINH00UGTGdmeJQ0jES4R1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CFaSJ/dJMcaaYXsi1/CINH00UGTGdmeJQ0jES4R1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCFaSJ%2FdJMcaaYXsi1%2FCINH00UGTGdmeJQ0jES4R1%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;560&quot; height=&quot;530&quot; data-origin-width=&quot;1396&quot; data-origin-height=&quot;1320&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오케이 이거 참고해서 구현을 한번 해보겟다!!!&lt;/p&gt;</description>
      <category>차곡차곡/dev-log</category>
      <author>p퐝유p</author>
      <guid isPermaLink="true">https://nikeisme827.tistory.com/94</guid>
      <comments>https://nikeisme827.tistory.com/94#entry94comment</comments>
      <pubDate>Tue, 24 Mar 2026 17:54:38 +0900</pubDate>
    </item>
    <item>
      <title>[자료구조] 트리</title>
      <link>https://nikeisme827.tistory.com/93</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;★&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt; 트리&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt; &lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;▷&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&amp;nbsp; 트리는 계층형 비선형 자료 구조&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 82px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 22px;&quot;&gt;
&lt;td style=&quot;width: 7.55814%; height: 22px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 42.4419%; height: 22px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;선형 구조&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 22px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;비선형 구조&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 22px;&quot;&gt;
&lt;td style=&quot;width: 7.55814%; height: 22px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;구성&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 42.4419%; height: 22px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;데이터가 순차적으로 나열시킨 형태&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 22px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;데이터가 계층적 혹은 망으로 구성&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 22px;&quot;&gt;
&lt;td style=&quot;width: 7.55814%; height: 22px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;용도&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 42.4419%; height: 22px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;자료를 저장하고 꺼내는 것에 초점&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 22px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;표현에 초점&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 7.55814%;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;종류&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 42.4419%;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;큐, 스택&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;트리, 그래프&lt;/span&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;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;▷ 트리 구성 요소&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 128px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 16px;&quot;&gt;
&lt;td style=&quot;width: 21.6279%; height: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;구성 요소&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 78.3721%; height: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;의미&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 16px;&quot;&gt;
&lt;td style=&quot;width: 21.6279%; height: 16px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Node&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 78.3721%; height: 16px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;트리에 데이터를 저장하는 기본 요소&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 16px;&quot;&gt;
&lt;td style=&quot;width: 21.6279%; height: 16px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Root Node&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 78.3721%; height: 16px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;트리 맨 위에 있는 노드&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 16px;&quot;&gt;
&lt;td style=&quot;width: 21.6279%; height: 16px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Level&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 78.3721%; height: 16px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;최상위 노드를 Level 0으로 하였을 때, 하위 Branch로 연결된 노드를 깊이 나타냄&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 16px;&quot;&gt;
&lt;td style=&quot;width: 21.6279%; height: 16px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Parent Node&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 78.3721%; height: 16px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;어떤 노드의 상위 레벨에 연결된 노드&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 16px;&quot;&gt;
&lt;td style=&quot;width: 21.6279%; height: 16px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Child Node&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 78.3721%; height: 16px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;어떤 노드의 하위 레벨에 연결된 노드&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 16px;&quot;&gt;
&lt;td style=&quot;width: 21.6279%; height: 16px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Leaf Node&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;(Terminal Node)&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 78.3721%; height: 16px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Child Node가 하나도 없는 노드&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 16px;&quot;&gt;
&lt;td style=&quot;width: 21.6279%; height: 16px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Depth&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 78.3721%; height: 16px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;루트에서 어떤 노드에 도달하기 위해 거쳐야 하는 간선의 수&lt;/span&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;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;▷ 트리의 종류&lt;/span&gt;&lt;/b&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;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;1. 이진트리 (Binary Tree&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; - 각 노드가 최대 두 개의 자식을 가진다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; 무조건 0,1,2 개만 있어야 한다.&lt;/span&gt;&lt;/b&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;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;2. 완전 이진트리(Complete Binary Tree)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp;- 노드를 삽입할 때, 최하단 왼쪽 노드부터 차례대로 삽입해야한다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1091&quot; data-origin-height=&quot;1000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BoDZg/dJMcagjRTRZ/KpcqEU4glTeSBE662UDsf1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BoDZg/dJMcagjRTRZ/KpcqEU4glTeSBE662UDsf1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BoDZg/dJMcagjRTRZ/KpcqEU4glTeSBE662UDsf1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBoDZg%2FdJMcagjRTRZ%2FKpcqEU4glTeSBE662UDsf1%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;397&quot; height=&quot;364&quot; data-origin-width=&quot;1091&quot; data-origin-height=&quot;1000&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;span style=&quot;background-color: #9feec3;&quot;&gt; &lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;▷ 완전 이진 트리를 배열로 표현&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp;- 트리 구조 표현 방법은 &lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;직접 클래스를 구현하여 사용 / &lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;배열로 표현하는 방법 2가지가 있음&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;단, 배열로 표현할 때는 완전 이진 트리일 때만 가능&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; - 완전 이진 트리는 왼쪽부터 데이터가 쌓이게 됨&lt;/span&gt;&lt;/b&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;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;lt;예시&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;아래의 트리는 이진 트리이면서 완전 이진트리&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1767452975638&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;      8      Level 0
    6   3    Level 1
   4 2 5     Level 2  # -&amp;gt; 이진 트리 O 완전 이진 트리 O&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;트리를 구현할 때는 0번째 인덱스는 사용하지 않는다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;그래서 None 값을 배열에 넣고 시작&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1767452873440&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;      8      Level 0 -&amp;gt; [None, 8] 첫번째 레벨의 8을 넣고,
    6   3    Level 1 -&amp;gt; [None, 8, 6, 3] 다음 레벨인 6, 3을 넣고
   4 2 5     Level 2 -&amp;gt; [None, 8, 6, 3, 4, 2, 5] 다음 레벨인 4, 2, 5를 넣는다&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt; ▷&amp;nbsp; &lt;span style=&quot;background-color: #9feec3;&quot;&gt;완전이진트리 배열의 인덱스&lt;/span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 60px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 22px;&quot;&gt;
&lt;td style=&quot;width: 20.5814%; height: 22px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt; 현재 인덱스 * 2 &lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 79.4186%; height: 22px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #333333; text-align: start;&quot;&gt; 왼쪽 자식의 인덱스 &lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 22px;&quot;&gt;
&lt;td style=&quot;width: 20.5814%; height: 22px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #333333; text-align: start;&quot;&gt; 현재 인덱스 * 2 + 1 &lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 79.4186%; height: 22px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #333333; text-align: start;&quot;&gt; 오른쪽 자식의 인덱스 &lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 16px;&quot;&gt;
&lt;td style=&quot;width: 20.5814%; height: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #333333; text-align: start;&quot;&gt; 현재 인덱스 // 2&amp;nbsp; &lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 79.4186%; height: 16px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #333333; text-align: start;&quot;&gt; 부모의 인덱스&amp;nbsp; &lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;▷&amp;nbsp; 완전이진트리의 높이&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;&quot;&gt;&lt;b&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;- 트리의 높이 : 루트 노드부터 가장 아래 리프 노드까지의 길이 (&lt;span style=&quot;background-color: #9feec3;&quot;&gt;가장 아래 리프노드 - 루트 노드&lt;/span&gt;)&lt;/b&gt;&lt;/span&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;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;▷&amp;nbsp; 완전이진트리의 노드 개수&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; - 레벨을 k라고 한다면, &lt;span style=&quot;background-color: #9feec3;&quot;&gt;2^k 개수&lt;/span&gt;&lt;/span&gt;&lt;/b&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;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;▷&amp;nbsp; 만약 높이가 h인데, 모든 노드가 꽉 차 있는 이진트리라면 모든 노드의 개수는 몇개?&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; 1 + 2^1 + 2^2 + 2^3 + 2^4 ..... 2^h &lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; 즉, 이를 수식으로 표현하면 &lt;span style=&quot;background-color: #9feec3;&quot;&gt;2^(h+1) - 1&lt;/span&gt; 이 된다.&lt;/span&gt;&lt;/b&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;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;출처 :&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1767453509819&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;38군데 합격 비법, 2025 코딩테스트 필수 알고리즘| 딩코딩코 - 인프런 강의&quot; data-og-description=&quot;현재 평점 5.0점 수강생 2,371명인 강의를 만나보세요. 초보자도 쉽게 이해하는 단계별 설명으로, 막연했던 코딩 테스트가 명확해집니다. 필요한 것만 배우고 바로 실전에 적용하세요! 알고리즘, &quot; data-og-host=&quot;www.inflearn.com&quot; data-og-source-url=&quot;https://www.inflearn.com/course/38%EA%B5%B0%EB%8D%B0-%ED%95%A9%EA%B2%A9%EB%B9%84%EB%B2%95-%EC%BD%94%ED%85%8C-%ED%95%84%EC%88%98-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98/dashboard&quot; data-og-url=&quot;https://www.inflearn.com/course/38%EA%B5%B0%EB%8D%B0-%ED%95%A9%EA%B2%A9%EB%B9%84%EB%B2%95-%EC%BD%94%ED%85%8C-%ED%95%84%EC%88%98-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bpKll4/hyZQ4HSBtO/cEVa6pLVOKG4mujQ1czDk0/img.gif?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/bSwHSR/hyZQLnoydA/1wn8732QnGkZcbOS9V0Xp0/img.gif?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/y8N1u/hyZPFWDLPW/xYyQYZati2ZSwUNk8zuqw0/img.png?width=404&amp;amp;height=404&amp;amp;face=121_67_269_228&quot;&gt;&lt;a href=&quot;https://www.inflearn.com/course/38%EA%B5%B0%EB%8D%B0-%ED%95%A9%EA%B2%A9%EB%B9%84%EB%B2%95-%EC%BD%94%ED%85%8C-%ED%95%84%EC%88%98-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98/dashboard&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.inflearn.com/course/38%EA%B5%B0%EB%8D%B0-%ED%95%A9%EA%B2%A9%EB%B9%84%EB%B2%95-%EC%BD%94%ED%85%8C-%ED%95%84%EC%88%98-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98/dashboard&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bpKll4/hyZQ4HSBtO/cEVa6pLVOKG4mujQ1czDk0/img.gif?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/bSwHSR/hyZQLnoydA/1wn8732QnGkZcbOS9V0Xp0/img.gif?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/y8N1u/hyZPFWDLPW/xYyQYZati2ZSwUNk8zuqw0/img.png?width=404&amp;amp;height=404&amp;amp;face=121_67_269_228');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;38군데 합격 비법, 2025 코딩테스트 필수 알고리즘| 딩코딩코 - 인프런 강의&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;현재 평점 5.0점 수강생 2,371명인 강의를 만나보세요. 초보자도 쉽게 이해하는 단계별 설명으로, 막연했던 코딩 테스트가 명확해집니다. 필요한 것만 배우고 바로 실전에 적용하세요! 알고리즘,&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.inflearn.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>차곡차곡/dev-log</category>
      <author>p퐝유p</author>
      <guid isPermaLink="true">https://nikeisme827.tistory.com/93</guid>
      <comments>https://nikeisme827.tistory.com/93#entry93comment</comments>
      <pubDate>Sun, 4 Jan 2026 00:20:18 +0900</pubDate>
    </item>
    <item>
      <title>[CI/CD] GitHub Actions Self-Hosted Runner &amp;ndash; deploy 단계에서 로딩이 지속 (서버에서 실행하려고 했을 때 생긴 문제) 해결 기록</title>
      <link>https://nikeisme827.tistory.com/92</link>
      <description>&lt;p data-end=&quot;453&quot; data-start=&quot;335&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;GitHub Actions Runner 를 내 서버에 올려서 자동 배포(CI/CD)를 만들려고 했다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;그런데 Runner 를 실행하는 과정에서 여러 오류가 발생했고,&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;문제 해결 과정을 그대로 정리해 둔다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;453&quot; data-start=&quot;335&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;524&quot; data-start=&quot;455&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;나중에 나처럼 Runner 를 처음 설치하거나&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;systemd/SELinux 때문에 막히는 개발자에게 참고가 되길 바란다.&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-end=&quot;524&quot; data-start=&quot;455&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #9feec3; font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;★ 문제&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-end=&quot;524&quot; data-start=&quot;455&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;서버 작업으로 인해 모든 작업들이 다 내려가있었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;524&quot; data-start=&quot;455&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;action-runner 또한 내려가있어 gitAction에서 deploy 단계일때,&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;524&quot; data-start=&quot;455&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;수행하지 않고 5분 넘게 지속되는 현상이 있었다.&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot; data-start=&quot;455&quot; data-end=&quot;524&quot;&gt;&lt;span style=&quot;background-color: #9feec3; font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;★ 첫번째 시도, svc.sh start 로 실행 &lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;처음에 runner 경로에서 다음 명령을 실행했다:&lt;/span&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1763985946137&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo ./svc.sh start&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;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;하지만 systemd 서비스가 실행되지 않았다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;로그를 확인하니 이런 오류가 있었다:&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1763986121678&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;status=203/EXEC
Failed to locate executable /home/devuser/actions-runner/runsvc.sh: Permission denied&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;524&quot; data-start=&quot;455&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #9feec3; font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;★ 문제1 - 기존 서비스가 이미 설치되어 있던 상태&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;처음 설치 시도 시 다음 메시지 발생:&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1764075854623&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Failed: error: exists /etc/systemd/system/actions.runner.&amp;lt;repo&amp;gt;.service&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1046&quot; data-start=&quot;1036&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;✔ 원인&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;1112&quot; data-start=&quot;1047&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;이전에 실행된 Runner 설치가 systemd 서비스 파일만 남겨둔 상태여서 &lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;새로운 install 이 막힌 것.&lt;/span&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;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;✔ 해결&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1764075892233&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo ./svc.sh stop || true          # 이미 실행 중이면 중지, 없으면 오류 무시
sudo ./svc.sh uninstall || true     # 기존 서비스 제거, 없으면 오류 무시
sudo rm /etc/systemd/system/actions.runner.*.service   # 남아 있는 서비스 파일 강제 삭제
sudo systemctl daemon-reload        # systemd 캐시 갱신&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot; data-start=&quot;455&quot; data-end=&quot;524&quot;&gt;&lt;span style=&quot;background-color: #9feec3; font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;★ 문제2 - systemd 가 runsvc.sh 실행 실패 (203/EXEC) &lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1370&quot; data-start=&quot;1338&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;여전히 service start 시 아래 오류가 발생했다:&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1764075991311&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;status=203/EXEC
Permission denied: /home/runner/actions-runner/runsvc.sh&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;✔ 원인&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- &lt;span style=&quot;letter-spacing: 0px;&quot;&gt;SELinux 가 /home 디렉토리에서 systemd 실행을 막고 있었고, &lt;/span&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;systemd 실행 경로가 적절하지 않았다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;letter-spacing: 0px; font-family: 'Noto Serif KR';&quot;&gt; ✔ 해결 &lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px; font-family: 'Noto Serif KR';&quot;&gt;- Runner 를 /opt/actions-runner 로 옮기기로 결정.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1764076098368&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo mkdir -p /opt/actions-runner   # Runner를 둘 안정적인 시스템 경로 생성
sudo mv /home/runner/actions-runner /opt/actions-runner   # 기존 runner를 /opt로 이동
sudo chown -R root:root /opt/actions-runner   # systemd 실행을 위해 root 소유로 변경&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1783&quot; data-start=&quot;1712&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;처음에는 Runner를 /home 아래 설치했다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;하지만 systemd가 그 안의 runsvc.sh 를 실행하지 못했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;1824&quot; data-start=&quot;1785&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;SELinux 정책이 home 영역에서의 실행을 막고 있었기 때문이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;1864&quot; data-start=&quot;1826&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;이 경험을 통해 /opt가 다음 이유로 더 적합하다는 걸 배웠다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1950&quot; data-start=&quot;1866&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1889&quot; data-start=&quot;1866&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;시스템 서비스가 실행하기 좋은 영역&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;1916&quot; data-start=&quot;1890&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;SELinux가 기본적으로 허용하는 경로&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;1950&quot; data-start=&quot;1917&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;system 디렉터리와 사용자 디렉터리를 분리할 수 있음&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1998&quot; data-start=&quot;1952&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;단순한 경로 이동이 아니라&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;ldquo;운영 체제의 동작 방식&amp;rdquo;을 이해하게 되는 계기였다.&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;524&quot; data-start=&quot;455&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #9feec3; font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;★ 문제3 -&amp;nbsp; config.sh를 root로 실행함 (금지됨)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt; config.sh 실행 시 다음 오류 발생: &lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1764076274424&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Must not run with sudo&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;2129&quot; data-start=&quot;2119&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;✔ 원인&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;2205&quot; data-start=&quot;2130&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;GitHub Actions Runner 는 &lt;b&gt;설정(config.sh)을 일반 사용자 계정에서 실행해야 한다.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;(root 금지)&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;2205&quot; data-start=&quot;2130&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;2205&quot; data-start=&quot;2130&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt; ✔ 해결 &lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1764076301772&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;su - runner
cd /opt/actions-runner
./config.sh --url https://github.com/&amp;lt;user&amp;gt;/&amp;lt;repo&amp;gt; --token &amp;lt;token&amp;gt;&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;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;token 정보는&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;깃헙의 Settings &amp;gt; Actions &amp;gt; Runners &amp;gt; New self-hosted runner 버튼 클릭 &amp;gt; 해당하는 os 선택 &amp;gt; Configure의 코드 복사&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;1132&quot; data-origin-height=&quot;374&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qc4uN/dJMcadAoykt/egQ530AntlTQqlNA4nGxS0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qc4uN/dJMcadAoykt/egQ530AntlTQqlNA4nGxS0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qc4uN/dJMcadAoykt/egQ530AntlTQqlNA4nGxS0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fqc4uN%2FdJMcadAoykt%2FegQ530AntlTQqlNA4nGxS0%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;1132&quot; height=&quot;374&quot; data-origin-width=&quot;1132&quot; data-origin-height=&quot;374&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot; data-start=&quot;455&quot; data-end=&quot;524&quot;&gt;&lt;span style=&quot;background-color: #9feec3; font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;★ 문제4 -&amp;nbsp; config.sh 실행 중 permission denied 다수 발생&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;letter-spacing: 0px; font-family: 'Noto Serif KR';&quot;&gt;✔ 에러 메시지&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1764076616419&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;touch: cannot touch '.env': 허가 거부
.path: 허가 거부
Access denied: /opt/actions-runner/_diag&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt; ✔ 원인 &lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt; Runner 디렉터리가 root 소유 &amp;rarr; 일반 사용자(runner) 파일 생성 불가 &lt;/span&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;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt; ✔ 해결 &lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1764076652055&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo chown -R runner:runner /opt/actions-runner   # 디렉터리 소유자를 runner로 변경
sudo restorecon -R /opt/actions-runner            # (선택) SELinux 컨텍스트 복구&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;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;이후 다시 실행:&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1764076677615&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;./config.sh --url ... --token ...&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;524&quot; data-start=&quot;455&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #9feec3; font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;★ 최종 성공 &amp;mdash; Runner 서비스 정상 실행 &lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt; config.sh 완료 후: &lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1764076713435&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo ./svc.sh install
sudo ./svc.sh start
sudo ./svc.sh status&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt; ✔ 성공&lt;/span&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;1594&quot; data-origin-height=&quot;669&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HBTvK/dJMcaacEsDe/tyPYDL7SGomBdG5ieHWR01/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HBTvK/dJMcaacEsDe/tyPYDL7SGomBdG5ieHWR01/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HBTvK/dJMcaacEsDe/tyPYDL7SGomBdG5ieHWR01/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHBTvK%2FdJMcaacEsDe%2FtyPYDL7SGomBdG5ieHWR01%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;1020&quot; height=&quot;428&quot; data-origin-width=&quot;1594&quot; data-origin-height=&quot;669&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;683&quot; data-origin-height=&quot;291&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/VVVUP/dJMcagjDdO1/u0SJlfkNQTpb0vbu1VkRQ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/VVVUP/dJMcagjDdO1/u0SJlfkNQTpb0vbu1VkRQ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/VVVUP/dJMcagjDdO1/u0SJlfkNQTpb0vbu1VkRQ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FVVVUP%2FdJMcagjDdO1%2Fu0SJlfkNQTpb0vbu1VkRQ1%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;683&quot; height=&quot;291&quot; data-origin-width=&quot;683&quot; data-origin-height=&quot;291&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt; 1. &lt;b&gt;Runner 설치는 단순 설치작업이 아니라 운영 영역에 가깝다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;666&quot; data-start=&quot;584&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;666&quot; data-start=&quot;584&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;처음에는 단순히 공식 문서 따라 config.sh만 실행하면 끝날 줄 알았다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;하지만 실제로는 &lt;b&gt;서버 운영 환경&lt;/b&gt;과 강하게 연결되어 있었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;674&quot; data-start=&quot;668&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;예를 들어:&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;783&quot; data-start=&quot;676&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;708&quot; data-start=&quot;676&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;systemd가 스크립트를 어디서 실행할 수 있는지&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;739&quot; data-start=&quot;709&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;SELinux가 home 디렉토리 실행을 막는지&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;760&quot; data-start=&quot;740&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;어떤 계정으로 실행해야 하는지&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;783&quot; data-start=&quot;761&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;디렉터리 권한은 어떻게 맞춰야 하는지&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;829&quot; data-start=&quot;785&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;이런 부분들을 제대로 이해하지 않으면 Runner가 정상적으로 올라오지 않는다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;875&quot; data-start=&quot;831&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;설치 과정에서 나는 거의 절반의 시간을&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;ldquo;보안 정책과 권한&amp;rdquo; 때문에 막혔다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;943&quot; data-start=&quot;877&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;이 경험을 통해,&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;CI/CD는 단순히 코드 문제가 아니라 인프라와 운영 전체가 연결된 작업&lt;/b&gt;이라는 걸 배웠다.&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-end=&quot;943&quot; data-start=&quot;877&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;943&quot; data-start=&quot;877&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt; 2. &lt;b&gt;&amp;lsquo;권한&amp;rsquo;과 &amp;lsquo;경로&amp;rsquo;가 80%의 문제를 만든다는 사실&lt;/b&gt; &lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;943&quot; data-start=&quot;877&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;943&quot; data-start=&quot;877&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt; Runner 설치 중 가장 많이 본 에러는 이거였다: &lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1764077416416&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;status=203/EXEC
Permission denied&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1081&quot; data-start=&quot;1063&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;원인은 대부분 다음 두 가지였다.&lt;/span&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;1135&quot; data-start=&quot;1083&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;1104&quot; data-start=&quot;1083&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;권한(owner)이 맞지 않음&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;1135&quot; data-start=&quot;1105&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;systemd가 실행하는 경로가 보안 정책에 걸림&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-end=&quot;1203&quot; data-start=&quot;1137&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;특히 /home/* 경로 아래 스크립트를 systemd가 실행하는 건&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;SELinux 때문에 거의 막히는 수준이었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;1263&quot; data-start=&quot;1205&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;이 경험 이후,&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;ldquo;&lt;b&gt;안 되면 권한 &amp;rarr; 경로 &amp;rarr; SELinux 순으로 체크한다&lt;/b&gt;&amp;rdquo;는 나만의 규칙이 생겼다.&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-end=&quot;1263&quot; data-start=&quot;1205&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;3. config.sh와 svc.sh는 서로 다른 권한으로 실행해야 한다는 점&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;1350&quot; data-start=&quot;1321&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1350&quot; data-start=&quot;1321&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Runner 설치에서 가장 헷갈렸던 부분은 이거였다:&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1421&quot; data-start=&quot;1352&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1388&quot; data-start=&quot;1352&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Runner 설정 &amp;rarr; &lt;b&gt;일반 사용자 계정에서 실행해야 함&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;1421&quot; data-start=&quot;1389&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Runner 서비스 &amp;rarr; &lt;b&gt;root에서 실행해야 함&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1460&quot; data-start=&quot;1423&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;처음엔 root로 config.sh 를 실행해서 계속 에러가 났다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1764077520647&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Must not run with sudo&lt;/code&gt;&lt;/pre&gt;
&lt;p data-end=&quot;1574&quot; data-start=&quot;1494&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1574&quot; data-start=&quot;1494&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Runner가 실행되는 방식 자체가&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;ldquo;업무를 특정 사용자 계정으로 수행해야 하기 때문&amp;rdquo;이라는 걸 이해하고 나서야&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;전체 구조가 명확해졌다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;1664&quot; data-start=&quot;1576&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;이걸 이해하고 나니 왜&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;/opt/actions-runner 에서&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;runner 사용자로 config.sh 를 실행하는 게 표준인지 이해할 수 있었다.&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-end=&quot;2801&quot; data-start=&quot;2732&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;이번 Runner 설치 경험은 단순히 에러 해결을 넘어서&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;CI/CD와 서버 운영의 본질을 직접 체감한 과정&lt;/b&gt;이었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;2845&quot; data-start=&quot;2803&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;세밀하게 파고든 덕분에&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;지금은 Runner 설치와 운영에 자신이 생겼다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;2914&quot; data-start=&quot;2847&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;앞으로 비슷한 환경 구성이나&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;실무에서 CI/CD 인프라를 맡게 될 때&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;이번 경험이 확실한 기반이 되어줄 것 같다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;1998&quot; data-start=&quot;1952&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>차곡차곡/error-log</category>
      <author>p퐝유p</author>
      <guid isPermaLink="true">https://nikeisme827.tistory.com/92</guid>
      <comments>https://nikeisme827.tistory.com/92#entry92comment</comments>
      <pubDate>Tue, 25 Nov 2025 22:33:28 +0900</pubDate>
    </item>
    <item>
      <title>[Spring Boot + JWT 인증 시스템 구축기(2)]</title>
      <link>https://nikeisme827.tistory.com/91</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;User 엔티티 설계부터 Spring Security 기본 세팅, 그리고 삽질 기록까지&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;1편에서는 &lt;b&gt;프로젝트 환경 세팅과 디렉토리 구조 설계&lt;/b&gt;까지 정리했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 2편에서는:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;431&quot; data-start=&quot;414&quot;&gt;User 엔티티 설계&lt;/li&gt;
&lt;li data-end=&quot;455&quot; data-start=&quot;432&quot;&gt;UserRepository 구현&lt;/li&gt;
&lt;li data-end=&quot;519&quot; data-start=&quot;456&quot;&gt;Spring Security에서 유저 정보를 불러오기 위한 CustomUserDetailsService&lt;/li&gt;
&lt;li data-end=&quot;559&quot; data-start=&quot;520&quot;&gt;JWT 토큰 발급/검증 역할의 JwtTokenProvider&lt;/li&gt;
&lt;li data-end=&quot;605&quot; data-start=&quot;560&quot;&gt;매 요청마다 토큰을 검사하는 JwtAuthenticationFilter&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;까지 구현한 과정을 정리해본다.&lt;br /&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;★ 1. User 엔티티 설계&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;770&quot; data-start=&quot;713&quot; data-ke-size=&quot;size16&quot;&gt;JWT 기반 인증에서 가장 중요한 것은 &lt;b&gt;&quot;누구를 인증할 것인가&quot;&lt;/b&gt;, 즉 &lt;b&gt;User 엔티티&lt;/b&gt;다.&lt;/p&gt;
&lt;pre id=&quot;code_1763886300199&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/**
 * User 엔티티
 *
 * - Spring Security + JWT 기반 인증에서 핵심이 되는 사용자 정보 테이블
 * - username(로그인 아이디), password(암호), role(권한) 필드를 가짐
 */
@Entity
@Table(name = &quot;users&quot;)
@Getter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;   // MariaDB의 AUTO_INCREMENT 방식으로 PK 증가

    @Column(nullable = false, unique = true)
    private String username;    // 로그인 아이디 (이메일도 가능)

    @Column(nullable = false)
    private String password;    // 암호화된 비밀번호 저장 (평문X)

    @Column(nullable = false)
    private String role;        // 권한 (예: &quot;USER&quot;, &quot;ADMIN&quot;)
}&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;p data-end=&quot;1534&quot; data-start=&quot;1527&quot; data-ke-size=&quot;size16&quot;&gt;설계 포인트:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1675&quot; data-start=&quot;1536&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1589&quot; data-start=&quot;1536&quot;&gt;username 은 &lt;b&gt;로그인 아이디&lt;/b&gt;로 사용되며 unique = true 적용&lt;/li&gt;
&lt;li data-end=&quot;1631&quot; data-start=&quot;1590&quot;&gt;password 는 나중에 &lt;b&gt;BCrypt로 암호화&lt;/b&gt;해서 저장&lt;/li&gt;
&lt;li data-end=&quot;1675&quot; data-start=&quot;1632&quot;&gt;role 은 &quot;USER&quot;, &quot;ADMIN&quot; 등 권한 구분용 문자열&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;★ 2. UserRepository &amp;ndash; JPA로 사용자 조회&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;UserRepository는 Spring Data JPA를 사용해 간단하게 구현했다.&lt;/p&gt;
&lt;pre id=&quot;code_1763886157114&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/**
 * UserRepository
 *
 * - User 엔티티에 대한 데이터 접근 계층
 * - 기본 CRUD는 JpaRepository가 제공
 * - username으로 유저를 조회하는 메서드만 추가로 정의
 */
 
public interface UserRepository extends JpaRepository&amp;lt;User, Long&amp;gt; {

    Optional&amp;lt;User&amp;gt; findByUsername(String username);
}&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;Spring Security에서 로그인 시, username 으로 유저를 찾기 위해&lt;br /&gt;findByUsername 메서드를 필수로 넣어두었다.&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;color: #333333; text-align: start;&quot;&gt;★ 3. CustomUserDetailsService &amp;ndash; Spring Security와 User 엔티티 연결&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;2482&quot; data-start=&quot;2392&quot; data-ke-size=&quot;size16&quot;&gt;- Spring Security는 로그인할 때 내부적으로 UserDetailsService를 사용해서&lt;br /&gt;&amp;nbsp; &quot;이 username으로 된 유저가 있는지&quot;를 확인한다.&lt;/p&gt;
&lt;p data-end=&quot;2551&quot; data-start=&quot;2484&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;그래서 UserRepository와 User 엔티티를 Spring Security에 연결해 줄 서비스가 필요하다.&lt;/p&gt;
&lt;pre id=&quot;code_1763886353333&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/**
 * CustomUserDetailsService
 *
 * - Spring Security가 인증을 수행할 때 호출되는 서비스
 * - username(로그인 아이디)을 기반으로 DB에서 실제 User를 조회한다.
 * - 조회된 User 엔티티를 Spring Security가 이해할 수 있는 UserDetails 형태로 변환해준다.
 */
@Service
@RequiredArgsConstructor
public class CustomUserDetailsService implements UserDetailsService {

    private final UserRepository userRepository;

    /**
     * 로그인 요청 시 실행되는 메서드
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        User user = userRepository.findByUsername(username)
                .orElseThrow(() -&amp;gt; new UsernameNotFoundException(&quot;사용자를 찾을 수 없습니다: &quot; + username));

        // Spring Security에서 사용하는 UserDetails 객체로 변환
        return withUsername(user.getUsername())
                .password(user.getPassword())
                .roles(user.getRole())
                .build();
    }
}&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;&amp;ldquo;DB에 저장된 User&amp;rdquo; &amp;rarr; &amp;ldquo;Spring Security가 이해하는 UserDetails&amp;rdquo;&lt;/b&gt; 변환 과정이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;★ 4. JwtTokenProvider &amp;ndash; 토큰 생성 &amp;amp; 검증&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;4130&quot; data-start=&quot;4119&quot; data-ke-size=&quot;size16&quot;&gt;JWT를 사용하려면:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;4204&quot; data-start=&quot;4132&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;4165&quot; data-start=&quot;4132&quot;&gt;로그인 성공 시 &lt;b&gt;토큰을 발급&lt;/b&gt;할 수 있어야 하고&lt;/li&gt;
&lt;li data-end=&quot;4204&quot; data-start=&quot;4166&quot;&gt;클라이언트가 보낸 토큰이 유효한지 &lt;b&gt;검증&lt;/b&gt;할 수 있어야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;4240&quot; data-start=&quot;4206&quot; data-ke-size=&quot;size16&quot;&gt;이를 담당하는 클래스가 JwtTokenProvider이다.&lt;/p&gt;
&lt;pre id=&quot;code_1763886420611&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/**
 * JwtTokenProvider
 *
 * - JWT Access Token을 생성하고 검증하는 역할을 담당하는 클래스.
 * - username과 roles 정보를 넣어 JWT를 생성한다.
 * - 요청이 들어왔을 때 토큰이 유효한지 검사한다.
 */
@Component
public class JwtTokenProvider {

    /**
     * application.yml에서 가져올 secret key
     * jwt.secret: &quot;아주 긴 랜덤 문자열&quot;
     */
    @Value(&quot;${jwt.secret}&quot;)
    private String secretKey;

    // Access Token 유효 시간: 1시간(3600000ms)
    private final long validityInMs = 1000L * 60 * 60;

    /**
     * secretKey를 기반으로 서명에 사용할 Key 객체 생성
     */
    private Key getSigningKey() {
        return Keys.hmacShaKeyFor(secretKey.getBytes(StandardCharsets.UTF_8));
    }

    /**
     * JWT 토큰 생성
     */
    public String createToken(String username, Collection&amp;lt;? extends GrantedAuthority&amp;gt; roles) {
        Claims claims = Jwts.claims().setSubject(username); // sub: username
        claims.put(&quot;roles&quot;, roles.stream()
                .map(GrantedAuthority::getAuthority)
                .collect(Collectors.toList()));

        Date now = new Date();
        Date expire = new Date(now.getTime() + validityInMs); // 만료 시간 설정

        return Jwts.builder()
                .setClaims(claims)               // 사용자 정보
                .setIssuedAt(now)               // 발급 시간(iat)
                .setExpiration(expire)          // 만료 시간(exp)
                .signWith(getSigningKey(), SignatureAlgorithm.HS256) // 서명
                .compact();
    }

    /**
     * 토큰에서 username 꺼내기
     */
    public String getUsername(String token) {
        return Jwts.parserBuilder()
                .setSigningKey(getSigningKey()) // 서명 검증
                .build()
                .parseClaimsJws(token)
                .getBody()
                .getSubject();
    }

    /**
     * 토큰 유효성 검사
     */
    public boolean validateToken(String token) {
        try {
            Jwts.parserBuilder()
                    .setSigningKey(getSigningKey())
                    .build()
                    .parseClaimsJws(token);

            return true; // 문제 없으면 유효한 토큰
        } catch (JwtException | IllegalArgumentException e) {
            return false; // 서명 오류, 만료 등 문제 발생
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-end=&quot;4240&quot; data-start=&quot;4206&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;4240&quot; data-start=&quot;4206&quot; data-ke-size=&quot;size16&quot;&gt;★ 5. JwtTokenProvider &amp;ndash; 토큰 생성 &amp;amp; 검증&lt;/p&gt;
&lt;p data-end=&quot;4240&quot; data-start=&quot;4206&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;4240&quot; data-start=&quot;4206&quot; data-ke-size=&quot;size16&quot;&gt;이제 토큰을 만들 수 있게 되었으니,&lt;br /&gt;매 요청마다 HTTP 헤더에 담긴 토큰을 검증하는 필터가 필요하다.&lt;/p&gt;
&lt;pre id=&quot;code_1763886966380&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/**
 * JwtAuthenticationFilter
 *
 * - API 요청이 들어올 때마다 실행되는 필터.
 * - Authorization 헤더에서 Bearer 토큰을 꺼내 JWT 유효성을 검증한다.
 * - 유효한 토큰이면 로그인 인증 완료된 사용자 상태(SecurityContext)에 저장.
 */
@Component
@RequiredArgsConstructor
public class JwtAuthenticationFilter extends OncePerRequestFilter {

    private final JwtTokenProvider jwtTokenProvider;
    private final UserDetailsService userDetailsService;

    @Override
    protected void doFilterInternal(
            HttpServletRequest request,
            HttpServletResponse response,
            FilterChain filterChain)
            throws ServletException, IOException {

        String header = request.getHeader(&quot;Authorization&quot;);

        // Authorization 헤더 존재 + Bearer 형태인지 확인
        if (header != null &amp;amp;&amp;amp; header.startsWith(&quot;Bearer &quot;)) {

            String token = header.substring(7); // &quot;Bearer &quot; 뒤의 문자열만 추출

            // JWT 토큰 검증
            if (jwtTokenProvider.validateToken(token)) {
                String username = jwtTokenProvider.getUsername(token);

                // username 기반 유저 정보 조회
                UserDetails userDetails = userDetailsService.loadUserByUsername(username);

                // 인증 객체 생성 (Spring Security 내부 인증 객체)
                UsernamePasswordAuthenticationToken auth =
                        new UsernamePasswordAuthenticationToken(
                                userDetails,
                                null,
                                userDetails.getAuthorities()
                        );

                // SecurityContext에 저장 &amp;rarr; 인증 완료 상태
                SecurityContextHolder.getContext().setAuthentication(auth);
            }
        }

        // 다음 필터 실행 (필수)
        filterChain.doFilter(request, response);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-end=&quot;4240&quot; data-start=&quot;4206&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>차곡차곡/dev-log</category>
      <author>p퐝유p</author>
      <guid isPermaLink="true">https://nikeisme827.tistory.com/91</guid>
      <comments>https://nikeisme827.tistory.com/91#entry91comment</comments>
      <pubDate>Sun, 23 Nov 2025 17:37:11 +0900</pubDate>
    </item>
    <item>
      <title>[Spring Boot + JWT 인증 시스템 구축기(1)]</title>
      <link>https://nikeisme827.tistory.com/90</link>
      <description>&lt;p data-end=&quot;407&quot; data-start=&quot;302&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;이 글은 &lt;b&gt;Spring Boot 3.x + Spring Security 6.x&lt;/b&gt; 기반으로&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;407&quot; data-start=&quot;302&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;JWT 인증/인가 시스템을 직접 구축한 과정&lt;/b&gt;을 정리한 시리즈의 첫 번째 글.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;519&quot; data-start=&quot;409&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;JWT 기반 인증 구조는 실제 기업의 백엔드 서비스에서 매우 널리 사용되기 때문에,&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;이번 프로젝트를 통해 &lt;b&gt;기본 인증 구조 + 보안 설계 + 실무 환경 구성&lt;/b&gt;까지 익히는 것이 목표다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-end=&quot;519&quot; data-start=&quot;409&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;★ 개발 환경&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-end=&quot;564&quot; data-start=&quot;541&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;해당 프로젝트는 아래 환경에서 진행했다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;769&quot; data-start=&quot;566&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;594&quot; data-start=&quot;566&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;IntelliJ IDEA Ultimate&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;608&quot; data-start=&quot;595&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;Java 17&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;632&quot; data-start=&quot;609&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;Spring Boot 3.5.x&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;658&quot; data-start=&quot;633&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;Gradle (Kotlin DSL)&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;672&quot; data-start=&quot;659&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;MariaDB&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;706&quot; data-start=&quot;673&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;Hibernate + Spring Data JPA&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;732&quot; data-start=&quot;707&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;Spring Security 6.x&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;769&quot; data-start=&quot;733&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;Swagger(Springdoc OpenAPI 2.x)&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;847&quot; data-start=&quot;771&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Spring Boot 3.x 이후로 Security와 Swagger 문법이 많이 달라졌기 때문에&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;최신 버전에 맞춘 구성을 정리한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;847&quot; data-start=&quot;771&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;847&quot; data-start=&quot;771&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;★ build.gradle.kts 설정&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-end=&quot;847&quot; data-start=&quot;771&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;이 프로젝트의 핵심이 되는 의존성은 우선 아래와 같다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;847&quot; data-start=&quot;771&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;하지만 추후 변경 가능성이 있다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1763883691515&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;plugins {
    java
    id(&quot;org.springframework.boot&quot;) version &quot;3.5.4&quot;
    id(&quot;io.spring.dependency-management&quot;) version &quot;1.1.7&quot;
}

dependencies {
    // Web
    implementation(&quot;org.springframework.boot:spring-boot-starter-web&quot;)

    // Database
    implementation(&quot;org.springframework.boot:spring-boot-starter-data-jpa&quot;)
    implementation(&quot;org.mariadb.jdbc:mariadb-java-client:3.3.3&quot;)

    // JWT
    implementation(&quot;io.jsonwebtoken:jjwt-api:0.11.5&quot;)
    runtimeOnly(&quot;io.jsonwebtoken:jjwt-impl:0.11.5&quot;)
    runtimeOnly(&quot;io.jsonwebtoken:jjwt-jackson:0.11.5&quot;)

    // Lombok
    compileOnly(&quot;org.projectlombok:lombok&quot;)
    annotationProcessor(&quot;org.projectlombok:lombok&quot;)

    // Swagger(OpenAPI)
    implementation(&quot;org.springdoc:springdoc-openapi-starter-webmvc-ui:2.5.0&quot;)

    // Test
    testImplementation(&quot;org.springframework.boot:spring-boot-starter-test&quot;)
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-end=&quot;847&quot; data-start=&quot;771&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;847&quot; data-start=&quot;771&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;특히 &lt;b&gt;Swagger 의존성은 Spring Boot 3.x 대응을 위해 반드시 2.x 버전을 사용해야 한다.&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;847&quot; data-start=&quot;771&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;847&quot; data-start=&quot;771&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; background-color: #9feec3;&quot;&gt;&lt;b&gt;★ 4. application.yml 구성&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-end=&quot;847&quot; data-start=&quot;771&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;외부 환경 변수를 .env 로 관리하고&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;MariaDB와 JPA 설정을 분리하여 유지보수를 쉽게 했다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1763883955464&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;spring:
  application:
    name: 프로젝트

  config:
    import: optional:file:.env[.properties]

  datasource:
    url: ${DATABASE_URL}
    username: ${DATABASE_USERNAME}
    password: ${DATABASE_PASSWORD}
    driver-class-name: org.mariadb.jdbc.Driver

  jpa:
    hibernate:
      ddl-auto: update
    show-sql: true
    properties:
      hibernate.format_sql: true
    database-platform: org.hibernate.dialect.MariaDBDialect

server:
  port: 8080&lt;/code&gt;&lt;/pre&gt;
&lt;p data-end=&quot;847&quot; data-start=&quot;771&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;847&quot; data-start=&quot;771&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;★&amp;nbsp;&lt;/span&gt;4. 디렉토리 구조 설계 (DDD Lite 방식)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-end=&quot;847&quot; data-start=&quot;771&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;우선 프로젝트에 대한 디렉토리 구조는 아래와 같다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1763883996485&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt; ├── domain
 │    ├── user
 │    ├── board
 │    └── auth
 │
 ├── global
 │    ├── config
 │    ├── error
 │    └── security
 │
 └── mainApplication.java&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-end=&quot;3028&quot; data-start=&quot;3014&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;✔ domain 계층&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-end=&quot;3083&quot; data-start=&quot;3029&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;각 도메인을 user/board/auth 등으로 독립 구성하여&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;확장성과 유지보수성을 높인다는 장점이 있다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;3137&quot; data-start=&quot;3085&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;3095&quot; data-start=&quot;3085&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;entity&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;3110&quot; data-start=&quot;3096&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;repository&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;3122&quot; data-start=&quot;3111&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;service&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;3137&quot; data-start=&quot;3123&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;controller&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;3170&quot; data-start=&quot;3139&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;구조를 DDD-lite 패턴으로 자연스럽게 분리했다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-end=&quot;3191&quot; data-start=&quot;3177&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;✔ global 계층&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-end=&quot;3221&quot; data-start=&quot;3193&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;프로젝트 전역에서 사용하는 공통 기능을 포함한다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;3347&quot; data-start=&quot;3223&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;3265&quot; data-start=&quot;3223&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;security&lt;/b&gt; : JWT, SecurityConfig, 필터&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;3307&quot; data-start=&quot;3266&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;config&lt;/b&gt; : SwaggerConfig, WebConfig&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;3347&quot; data-start=&quot;3308&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;error&lt;/b&gt; : GlobalExceptionHandler 예정&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;3382&quot; data-start=&quot;3349&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;이 구조는 실제 기업에서도 가장 많이 쓰는 설계 방식이라는 내용이 많이 보여 사용하기로 했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;3382&quot; data-start=&quot;3349&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;3382&quot; data-start=&quot;3349&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;★ &lt;/span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;User 엔티티 설계 &lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-end=&quot;3382&quot; data-start=&quot;3349&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;JWT 인증의 핵심은 &quot;사용자 정보를 인증 토큰과 연결&quot;하는 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1763884114334&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Entity
@Table(name = &quot;users&quot;)
@Getter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false, unique = true)
    private String username;  // 로그인 아이디

    @Column(nullable = false)
    private String password;  // 암호화 저장

    @Column(nullable = false)
    private String role;      // USER / ADMIN 등 권한
}
\&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;3906&quot; data-start=&quot;3899&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;설계 포인트:&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;3981&quot; data-start=&quot;3908&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;3931&quot; data-start=&quot;3908&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;username은 unique 조건&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;3957&quot; data-start=&quot;3932&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;password는 BCrypt로 암호화&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;3981&quot; data-start=&quot;3958&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;role은 문자열 기반(확장 쉬움)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; background-color: #9feec3;&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;★ &lt;/span&gt;환경 설정 완료 여부 테스트&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;환경 설정이 정상이라면&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1763884317373&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;./gradlew build
./gradlew bootRun&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;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;으로 서버가 정상적으로 실행된다.&lt;/span&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>차곡차곡/dev-log</category>
      <author>p퐝유p</author>
      <guid isPermaLink="true">https://nikeisme827.tistory.com/90</guid>
      <comments>https://nikeisme827.tistory.com/90#entry90comment</comments>
      <pubDate>Sun, 23 Nov 2025 17:11:54 +0900</pubDate>
    </item>
    <item>
      <title>[CI/CD 오류] failed to build: process &amp;quot;/bin/sh -c npm run build&amp;quot; did not complete successfully: exit code: 127</title>
      <link>https://nikeisme827.tistory.com/89</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;프론트엔드 Dockerfile에서 다음과 같은 에러가 발생했다:&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1763471224550&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;failed to build: process &quot;/bin/sh -c npm run build&quot; did not complete successfully: exit code: 127&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1559&quot; data-origin-height=&quot;257&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bKHLWk/dJMcafydOuS/7gKYuyz9g4buTAQyM6cywK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bKHLWk/dJMcafydOuS/7gKYuyz9g4buTAQyM6cywK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bKHLWk/dJMcafydOuS/7gKYuyz9g4buTAQyM6cywK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbKHLWk%2FdJMcafydOuS%2F7gKYuyz9g4buTAQyM6cywK%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;1357&quot; height=&quot;224&quot; data-origin-width=&quot;1559&quot; data-origin-height=&quot;257&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;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;이 에러는 보통 &quot;명령어가 없음&quot; 의 상황에서 발생한다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;이번 케이스에서 문제의 핵심은 아래 Dockerfile의 내용에 있다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1763471459717&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;FROM node:20-alpine AS build
ENV NODE_ENV=production     # &amp;larr; 여기
WORKDIR /app

COPY package*.json ./
RUN npm ci                  # &amp;larr; devDependencies 미설치

COPY . .
RUN npm run build           # &amp;larr; react-scripts / vite / webpack 없음 &amp;rarr; 127 에러&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;☆ 원인 분석&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- NODE_ENV=production 때문에 devDependencies가 설치되지 않음 &lt;/span&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;font-family: 'Noto Serif KR';&quot;&gt;1) NODE_ENV=production란?&lt;/span&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;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; - NODE_ENV 는 Node.js에게 지금 어떤 환경인지 알려주는 변수이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &quot;development&quot; : 개발중&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &quot;production&quot;&amp;nbsp; &amp;nbsp; &amp;nbsp;: 배포용&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &quot;test&quot;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; : 테스트환경&lt;/span&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;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; NODE_ENV=production 은 꼭 필요한 것만 설치해라 라고 이해하면된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; 이 변수로 npm은&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; dependencies 만 설치하고, devDependencies 는 건너뛴다.&lt;/span&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;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; devDependencies는 개발할때만 쓰는 도구다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; react-scripts, vite 등 빌드할때 (= npm build) 반드시 필요한 애들이 있어서&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp;즉, &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;devDependencies 가 없으면 빌드 자체가 불가능하다.&lt;/span&gt;&lt;/span&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;color: #333333; text-align: start; font-family: 'Noto Serif KR';&quot;&gt;나의 Dockerfile에는 build 단계에서 아래와 같이 되어있었다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1763472182499&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ENV NODE_ENV=production
RUN npm ci&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;1611&quot; data-origin-height=&quot;426&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/baRp4m/dJMcacuJkIm/xKxHuhk7ecu8kC9u85t5u1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/baRp4m/dJMcacuJkIm/xKxHuhk7ecu8kC9u85t5u1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/baRp4m/dJMcacuJkIm/xKxHuhk7ecu8kC9u85t5u1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbaRp4m%2FdJMcacuJkIm%2FxKxHuhk7ecu8kC9u85t5u1%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;1611&quot; height=&quot;426&quot; data-origin-width=&quot;1611&quot; data-origin-height=&quot;426&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;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;그래서&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;npm이 아~ 프로덕션이구나 하고 devDependencies 를 다 건너띄었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;그래서 node_modules 안에 react-scripts / vite 같은 빌드 도구가 없었던 것이고,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;아래서 npm run build 를 호출하려면 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;react-scripts&amp;nbsp; 를 실행해야하는데&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start; font-family: 'Noto Serif KR';&quot;&gt;없어서 exit code 127이 발생했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt; ☆ 해결 방법&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;NODE_ENV = production 을 build단계에서 제거하기&lt;/span&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;font-family: 'Noto Serif KR';&quot;&gt;일반적인 Docker 멀티 스테이지 빌드에서는 이렇게 한다.&lt;/span&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;font-family: 'Noto Serif KR';&quot;&gt;1) 빌드 단계&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; - devDependencies 포함 전체 설치&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; - 빌드 실행&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;2) Runtime(Ngix) 단계 (결과물을 실제로 서비스하는 단계)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp;- 빌드 결과물 (dist/build) 만 복사&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; - &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;NODE_ENV = production&amp;nbsp; 설정&amp;nbsp;&lt;/span&gt;&lt;/span&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;font-family: 'Noto Serif KR';&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;즉, NODE_ENV = production 을 사용하지 않으면 된다.&lt;/span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;/span&gt;&lt;/span&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;color: #333333; text-align: start; font-family: 'Noto Serif KR';&quot;&gt;그래서 아래와 같이 Dockerfile을 수정해줬다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1596&quot; data-origin-height=&quot;720&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d4Sxa2/dJMcagjAY0b/x1PLRCpzdTTZPEBzDSUUnk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d4Sxa2/dJMcagjAY0b/x1PLRCpzdTTZPEBzDSUUnk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d4Sxa2/dJMcagjAY0b/x1PLRCpzdTTZPEBzDSUUnk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd4Sxa2%2FdJMcagjAY0b%2Fx1PLRCpzdTTZPEBzDSUUnk%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;1596&quot; height=&quot;720&quot; data-origin-width=&quot;1596&quot; data-origin-height=&quot;720&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;그냥 이건 내가 한 정리&lt;/span&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;font-family: 'Noto Serif KR';&quot;&gt;1) 1단계 Build &amp;rarr; 건물을 짓는 과정&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; - 공사 인력 (개발 도구) 필요함&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; - 여러 장비( devDependencies ) 필요&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; - 그러니 난장판&lt;/span&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;font-family: 'Noto Serif KR';&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;2) 2단계 Runtime&amp;nbsp;&lt;/span&gt;&amp;rarr; 완성된 건물에서 실제로 운영하는 단계&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp;- 손님 (유저) 에게 보여줄 건물만 있으면 되지&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; -&amp;nbsp; 공사 장비(node_modules) 따위 필요없어&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; -&amp;nbsp; 깔끔쓰하고 최적화된 상태여야하니 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;NODE_ENV = production 로 가즈아~~~~~!!!!&lt;/span&gt;&lt;/span&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;font-family: 'Noto Serif KR';&quot;&gt; ☆ 오늘의 교훈&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Runtime(Nginx) 단계에서는 &quot;완성된 dist/build 파일만&quot; 사용해서 실제 서비스를 하는 단계이며,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;이때, NODE_ENV = production를 설정해 프로덕션 최적화를 적용한다!!&lt;/span&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>차곡차곡/error-log</category>
      <author>p퐝유p</author>
      <guid isPermaLink="true">https://nikeisme827.tistory.com/89</guid>
      <comments>https://nikeisme827.tistory.com/89#entry89comment</comments>
      <pubDate>Tue, 18 Nov 2025 22:36:49 +0900</pubDate>
    </item>
    <item>
      <title>[CI/CD 오류] Vue + GitHub Actions: buildx failed with /app/build not found</title>
      <link>https://nikeisme827.tistory.com/88</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1564&quot; data-origin-height=&quot;280&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cTqe4C/dJMb99Si930/k4sLVG79Wo0U5OWn4DWH41/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cTqe4C/dJMb99Si930/k4sLVG79Wo0U5OWn4DWH41/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cTqe4C/dJMb99Si930/k4sLVG79Wo0U5OWn4DWH41/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcTqe4C%2FdJMb99Si930%2Fk4sLVG79Wo0U5OWn4DWH41%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;1564&quot; height=&quot;280&quot; data-origin-width=&quot;1564&quot; data-origin-height=&quot;280&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt; &lt;span style=&quot;font-family: 'Noto Serif KR'; color: #333333; text-align: start;&quot;&gt;☆&lt;/span&gt; 에러 메시지&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1763468439291&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;buildx failed with: ERROR: failed to build: failed to solve:
failed to compute cache key: failed to calculate checksum of ref
g6jv2ev09dowgkglksu1rd348s::rwtyh1walc64d4lp2i4omzzb9a: &quot;/app/build&quot;: not found&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;☆ 문제 상황&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- Github Actions에서 frontend Dockerfile 빌드 과정에서 실패&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- 캐시 계산 (cache key) 단계에서 /app/build 디렉토리를 찾을 수 없다는 에러 발생&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- frontend 이미지가 실패하자 backend 이미지 빌드도 중단됨&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; background-color: #9feec3;&quot;&gt;☆ 원인 분석&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;이 에러는 Dockerfile이 /app/build 디렉토리를 COPY 하려하는데&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;빌드 단계에서 그 디렉토리가 아예 생성되지 않아 발생함&lt;/span&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;font-family: 'Noto Serif KR';&quot;&gt;즉,&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1763468780567&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;RUN npm ci
RUN npm run build&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;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;이 단계에서 build 폴더가 생성되지 않았음.&lt;/span&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;font-family: 'Noto Serif KR';&quot;&gt;왜 안만들어졌을까?&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; background-color: #9feec3;&quot;&gt;☆ 원인 분석&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;1.프론트가 React 기준 Dockerfile이었는데 실제 프로젝트는 Vue였음&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp;- 기존에는 React 를 사용하기로 했으나 Vue로 변경이 되었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;하지만 나는 라이브러리 변경 후, 로컬에서 오 잘되는구나 하고 이 GitActions 를 신경쓰지 못하고&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;왜 안되지 만 바보같이 반복하고 있었다.&lt;/span&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;font-family: 'Noto Serif KR';&quot;&gt;2. Vue의 기본 결과물은 /dist 로 생성이 된다. (React는 /build)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1082&quot; data-start=&quot;1053&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;그래서 Dockerfile에서 이렇게 되어 있었다면:&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1763469033760&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;COPY --from=build /app/build/ /usr/share/nginx/html/&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;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Vue에는 /build 폴더 자체가 생기니 당연히 에러가 발생할 수 밖에...&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;☆ 해결 방법&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&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;font-family: 'Noto Serif KR';&quot;&gt;Dockerfile을 &lt;b&gt;Vue 기준으로 수정&lt;/b&gt;해야 함.&lt;/span&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;font-family: 'Noto Serif KR';&quot;&gt;프론트엔드 Dockerfile 수정 전 (문제 버전)&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1763469293309&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;COPY --from=build /app/build/ /usr/share/nginx/html/&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;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;프론트엔드 Dockerfile 수정 후 (문제 버전)&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1763469311926&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;COPY --from=build /app/dist/ /usr/share/nginx/html/&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;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Vue + Vite 프로젝트는 항상 /dist 폴더가 최종 산출물임.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;642&quot; data-origin-height=&quot;153&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bE9qdj/dJMcahQlbFv/98hS78pkSlIkV2EoD24enK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bE9qdj/dJMcahQlbFv/98hS78pkSlIkV2EoD24enK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bE9qdj/dJMcahQlbFv/98hS78pkSlIkV2EoD24enK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbE9qdj%2FdJMcahQlbFv%2F98hS78pkSlIkV2EoD24enK%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;153&quot; data-origin-width=&quot;642&quot; data-origin-height=&quot;153&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;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;☆ 결론&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; - React 용 Dockerfile을 Vue 프로젝트에 사용해서 생긴 문제&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; - Vue의 빌드 산출물은 /dist&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; - Dockerfile COPY 경로 수정으로 해결됨&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;  추가 오류: Backend Docker 빌드 실패 (gradlew bootJar exit code 1)&lt;/span&gt;&lt;/b&gt;&lt;/h3&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;font-family: 'Noto Serif KR';&quot;&gt;프론트엔드 문제를 해결하자 이번에는 백엔드 이미지 빌드 단계에서 실패하는 문제가 발생했다.&lt;/span&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;font-family: 'Noto Serif KR';&quot;&gt;GitHub Actions 로그 메시지는 다음과 같다:&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1763469656697&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;buildx failed with: ERROR: failed to build: failed to solve:
process &quot;/bin/sh -c ./gradlew bootJar --no-daemon --stacktrace&quot;
did not complete successfully: exit code: 1&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1561&quot; data-origin-height=&quot;158&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EU5Nt/dJMcahpgUsC/UfdSSQgYMTpMBgfIyvkTd1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EU5Nt/dJMcahpgUsC/UfdSSQgYMTpMBgfIyvkTd1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EU5Nt/dJMcahpgUsC/UfdSSQgYMTpMBgfIyvkTd1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEU5Nt%2FdJMcahpgUsC%2FUfdSSQgYMTpMBgfIyvkTd1%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;1561&quot; height=&quot;158&quot; data-origin-width=&quot;1561&quot; data-origin-height=&quot;158&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;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;☆ 오류 추적 방법&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-end=&quot;605&quot; data-start=&quot;550&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;1) Annotations에는 단순히 &amp;ldquo;exit code: 1&amp;rdquo;만 보여서 정보가 부족&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;642&quot; data-start=&quot;606&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;rarr; 그래서 실제 빌드 로그 전체를 스크롤하여 원인을 찾아야 했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;642&quot; data-start=&quot;606&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;642&quot; data-start=&quot;606&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;2) buildx 로그 중 What went wrong: 부분까지 내려감&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;642&quot; data-start=&quot;606&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; - Gradle이 어떤 Task를 실행하는 중 구성(Configuration) 오류가 발생했을 때 출력되는 표준 오류 섹션&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;642&quot; data-start=&quot;606&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; Gradle이 Task를 실행하기전&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;642&quot; data-start=&quot;606&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; '필요한 파일,디렉토리가 존재하는지', 'Task 속성이 올바르게 설정되었는지' 등을 검사하는 단계에서&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;642&quot; data-start=&quot;606&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; 문제를 발견했을 때 나타나는 에러&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;642&quot; data-start=&quot;606&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;642&quot; data-start=&quot;606&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;거기서 다음 메시지를 발견:&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1763469902289&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;What went wrong:
Some problems were found with the configuration of task ':npmBuild'
In plugin 'com.github.node-gradle.node' type 'NpmTask' property '$1' specifies directory '/frontend/src' which doesn&amp;rsquo;t exist.
&amp;hellip;
Specifies file '/frontend/package.json' which doesn't exist.
Specifies file '/frontend/package-lock.json' which doesn't exist.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-end=&quot;1109&quot; data-start=&quot;1061&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;1295&quot; data-origin-height=&quot;561&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/RUkxP/dJMcahpgUzE/vbrlqDRfP3gFM9a9pN8UkK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/RUkxP/dJMcahpgUzE/vbrlqDRfP3gFM9a9pN8UkK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/RUkxP/dJMcahpgUzE/vbrlqDRfP3gFM9a9pN8UkK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRUkxP%2FdJMcahpgUzE%2FvbrlqDRfP3gFM9a9pN8UkK%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;1295&quot; height=&quot;561&quot; data-origin-width=&quot;1295&quot; data-origin-height=&quot;561&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;1109&quot; data-start=&quot;1061&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1109&quot; data-start=&quot;1061&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;즉, 백엔드 빌드 중인데 프론트엔드 관련 파일을 찾으려 하면서 실패하고 있었음.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;1109&quot; data-start=&quot;1061&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;1109&quot; data-start=&quot;1061&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;☆ 원인 분석&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-end=&quot;1109&quot; data-start=&quot;1061&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;원인 1) backend/build.gradle 안에 프론트 자동 빌드를 위한 NpmTask가 들어있었음&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;1109&quot; data-start=&quot;1061&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;내 backend 빌드 파일에는 아래처럼 설정이 존재했다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1763470073529&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;inputs.dir(&quot;${project.rootDir}/../frontend/src&quot;)
inputs.file(&quot;${project.rootDir}/../frontend/package.json&quot;)
inputs.file(&quot;${project.rootDir}/../frontend/package-lock.json&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;751&quot; data-origin-height=&quot;244&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xSw7F/dJMb99Lxx4Z/3XEbcfk70x62XJyxCHVvA1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xSw7F/dJMb99Lxx4Z/3XEbcfk70x62XJyxCHVvA1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xSw7F/dJMb99Lxx4Z/3XEbcfk70x62XJyxCHVvA1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxSw7F%2FdJMb99Lxx4Z%2F3XEbcfk70x62XJyxCHVvA1%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;244&quot; data-origin-width=&quot;751&quot; data-origin-height=&quot;244&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;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;이 작업이 실행되면 backend Dockerfile에서 다음이 실행됨&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1763470156737&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;./gradlew bootJar&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;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;그러면 Gradle은 backend 의 모든 task 를 포함하여&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;npmBuild task 도 함께 실행하려고 시도한다.&lt;/span&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;font-family: 'Noto Serif KR';&quot;&gt;하지만,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;현재 컨테이너는 backend, frontend 분리하여 총 2개로 운영하기때문에 다음 경로를 찾지 못한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;/frontend/src&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;/frontend/package.json&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;/fronted/package-lock.json&lt;/span&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;font-family: 'Noto Serif KR';&quot;&gt;결과적으로 npmBuild task 가 실패 &amp;rarr; bootJar 전체 실패 &amp;rarr; Docker 빌드 실패&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;☆ 해결 방법&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- backend에서 npmBuild task 제거&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;backend/build.gradle.kts에서 다음 블록을 아예 삭제:&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1763470475933&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;val npmBuild by tasks.registering(&amp;hellip;){
    &amp;hellip;
}
val copyFrontend by tasks.registering(Copy::class) {
    dependsOn(npmBuild)
    &amp;hellip;
}
tasks.processResources {
    dependsOn(copyFrontend)
}&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;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;이렇게 되면 backend는 온전히 SpringBoot만 빌드가 되고 frontend는 GitHubActions에서 별도로 빌드하여 충돌하지 않는다.&lt;/span&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>차곡차곡/error-log</category>
      <author>p퐝유p</author>
      <guid isPermaLink="true">https://nikeisme827.tistory.com/88</guid>
      <comments>https://nikeisme827.tistory.com/88#entry88comment</comments>
      <pubDate>Tue, 18 Nov 2025 22:01:24 +0900</pubDate>
    </item>
    <item>
      <title>GitHub Actions CI/CD 환경에서 DB 연결 오류 해결기</title>
      <link>https://nikeisme827.tistory.com/87</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Spring Boot를 깃으로 형상관리할 때,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;DB, 토큰 등 중요 정보 관리 방법 중 하나는 .env 파일에 환경 변수로 관리하는 방법이다.&lt;/span&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;font-family: 'Noto Serif KR';&quot;&gt;.env 파일은&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;.gitignore 파일에 커밋이 되지 않도록 설정이 되면 로컬에서만 실행이 되는 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;.env 자체가 git 에 올라가지 않는데&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;gitAction으로 Docker 에 배포가 되어 DB 접속 정보는 어떻게 불러오느냐가 문제였다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;우선 .env 파일을 올리지 않고 백엔드 도커를 배포했더니 DB 커넥션이 되지 않은 상태에서 방법을 찾아봤다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;문제 상황&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- GitHub Actions로 CI/CD를 돌리는데, 애플리케이션에서 DB 접속 정보를 필요로 함&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- 중요한 정보(DB URL, 계정, 비밀번호)는 코드에 직접 쓰면 안 됨 &amp;rarr; secrets 활용&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;해결 방법&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- secrets 값을 .env 파일로 생성해서 docker-compose가 읽도록 함&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- GitHub Actions에서 job step으로 .backend.env 파일을 만듦&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #333333; font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;docker-compose.yml 파일에 env_file 경로 추가하기&lt;/b&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;1154&quot; data-origin-height=&quot;204&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nCFTR/btsQ4mcLjhu/48zDfB0akdOYAhqzkRo7DK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nCFTR/btsQ4mcLjhu/48zDfB0akdOYAhqzkRo7DK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nCFTR/btsQ4mcLjhu/48zDfB0akdOYAhqzkRo7DK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnCFTR%2FbtsQ4mcLjhu%2F48zDfB0akdOYAhqzkRo7DK%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;1154&quot; height=&quot;204&quot; data-origin-width=&quot;1154&quot; data-origin-height=&quot;204&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;루트 최상단 파일에 .backed.env 파일 명을 읽어&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;docker-compose가 실행되어 DB 접속 정보를 읽어 DB 접속이 될 수 있도록 해당 로직을 추가한다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #333333; text-align: start;&quot;&gt;GitHub Actions에서 job step으로&lt;span&gt; &lt;span style=&quot;font-family: 'Noto Serif KR'; color: #333333; text-align: start;&quot;&gt;.backend.env 파일 생성 로직 추가&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1759589604113&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;- name: Create .backend.env next to compose
  run: |
    set -euo pipefail
    cd &quot;$GITHUB_WORKSPACE&quot;
    cat &amp;gt; .backend.env &amp;lt;&amp;lt;'EOF'
    DATABASE_URL=${{ secrets.DATABASE_URL }}
    DATABASE_USERNAME=${{ secrets.DATABASE_USERNAME }}
    DATABASE_PASSWORD=${{ secrets.DATABASE_PASSWORD }}
    SPRING_JACKSON_TIME_ZONE=Asia/Seoul
    EOF
    ls -al .backend.env docker-compose.yml&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;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp;1. set -euo pipefail : 스크립트에서 실수를 최대한 빨리 잡고, 조용히 실패하지 않게 하는 안전장치&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;set -e : 스크립트 실행 중 **에러(exit code 0이 아닌 경우)**가 발생하면 즉시 종료.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;set -u : &lt;b&gt;정의되지 않은 변수를 참조&lt;/b&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;하려 하면 에러 발생시키고 종료.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;set -o pipefail&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;파이프(|)로 연결된 명령어 실행 시, &lt;b&gt;마지막 명령어가 아니라 첫 번째 실패한 명령어의 exit code를 반환&lt;/b&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;.&lt;br /&gt;&lt;/span&gt;없으면 마지막 명령어만 성공하면 전체 성공으로 간주됨 &amp;rarr; 중간 실패를 놓칠 수 있음.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;2. cd &quot;$GITHUB_WORKSPACE&quot;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&amp;nbsp;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt; GitHub Actions 러너 환경에서 작업 디렉토리를 이동 &lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;131&quot; data-start=&quot;102&quot;&gt;&amp;nbsp; $GITHUB_WORKSPACE&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;- GitHub Actions가 실행될 때 자동으로 설정되는 &lt;b&gt;환경 변수&lt;/b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; letter-spacing: 0px;&quot;&gt;.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; - 의미: &lt;b&gt;현재 리포지토리 코드가 체크아웃(clone)된 경로&lt;/b&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; - 위치 : /home/devuser/actions-runner/_work/&amp;lt;리포지토리명&amp;gt;/&amp;lt;리포지토리명&amp;gt; &lt;/span&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;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;3. &lt;b&gt;cat &amp;gt; .backend.env &amp;lt;&amp;lt;'EOF' ... EOF&lt;/b&gt; &lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;GitHub Secrets 값들을 환경파일로 저장&amp;nbsp;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;4.&lt;b&gt; ls -al .backend.env docker-compose.yml&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;디버깅용(파일이 제대로 생성됐는지 확인) &lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;GitHub Actions에서 &lt;/span&gt;Actions secrets and variables 생성하기&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;아래의 화면 경로로 들어가&amp;nbsp;&lt;br /&gt;화면 경로 : 깃헙 repository &amp;gt; settings &amp;gt; security &amp;gt; Secrets and variables &amp;gt; actions&lt;/span&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&gt;CI-CD.yml파일에서 입력한 변수명으로 DB 정보를 저장한다.&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;800&quot; data-origin-height=&quot;213&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bUxivt/btsQ2jBCMuE/dqVmezgqFnMkmqxnqVNHwK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bUxivt/btsQ2jBCMuE/dqVmezgqFnMkmqxnqVNHwK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bUxivt/btsQ2jBCMuE/dqVmezgqFnMkmqxnqVNHwK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbUxivt%2FbtsQ2jBCMuE%2FdqVmezgqFnMkmqxnqVNHwK%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;800&quot; height=&quot;213&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;213&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;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;GitHub Actions 실행하기&lt;/span&gt;&lt;/b&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;1533&quot; data-origin-height=&quot;403&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dd4CG2/btsQ3WSYSnu/PVvqOyGE2cW1j6pZQDKrDK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dd4CG2/btsQ3WSYSnu/PVvqOyGE2cW1j6pZQDKrDK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dd4CG2/btsQ3WSYSnu/PVvqOyGE2cW1j6pZQDKrDK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdd4CG2%2FbtsQ3WSYSnu%2FPVvqOyGE2cW1j6pZQDKrDK%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;864&quot; height=&quot;227&quot; data-origin-width=&quot;1533&quot; data-origin-height=&quot;403&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;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;DB 연결 실패 1 - Host 허용 문제&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- Error:&amp;nbsp;1130-HY000:&amp;nbsp;Host&amp;nbsp;'172.18.0.3'&amp;nbsp;is&amp;nbsp;not&amp;nbsp;allowed&amp;nbsp;to&amp;nbsp;connect&amp;nbsp;to&amp;nbsp;this&amp;nbsp;MySQL&amp;nbsp;server&lt;/span&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;1063&quot; data-origin-height=&quot;66&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bEl3U6/btsQ2A4Civx/7ww2C6sMrOk3KpN6qkEQt1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bEl3U6/btsQ2A4Civx/7ww2C6sMrOk3KpN6qkEQt1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bEl3U6/btsQ2A4Civx/7ww2C6sMrOk3KpN6qkEQt1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbEl3U6%2FbtsQ2A4Civx%2F7ww2C6sMrOk3KpN6qkEQt1%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;1063&quot; height=&quot;66&quot; data-origin-width=&quot;1063&quot; data-origin-height=&quot;66&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;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;원인&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt; DB가 &lt;b&gt;도커 브리지 대역(172.18.0.*)&lt;/b&gt; 에서의 접속을 허용하지 않음. &lt;/span&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;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;해결 방법&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;DB의 계정을 지정하여 도커 브리지 대역에 접속을 허용하도록 권한을 부여하는 쿼리를 실행한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1759848466326&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;GRANT ALL PRIVILEGES ON [DB명].* TO '[계정명]'@'172.18.0.%' IDENTIFIED BY '[패스워드]';&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;DB 연결 실패 2 -&amp;nbsp; RSA 공개키/인증 방식&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start; font-family: 'Noto Serif KR';&quot;&gt; - RSA public key is not available client side &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;1352&quot; data-origin-height=&quot;68&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bq7R3j/btsQ5GIJePj/4dxxNW6C1TYDQsYu6dGpVk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bq7R3j/btsQ5GIJePj/4dxxNW6C1TYDQsYu6dGpVk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bq7R3j/btsQ5GIJePj/4dxxNW6C1TYDQsYu6dGpVk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbq7R3j%2FbtsQ5GIJePj%2F4dxxNW6C1TYDQsYu6dGpVk%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;1352&quot; height=&quot;68&quot; data-origin-width=&quot;1352&quot; data-origin-height=&quot;68&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;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;원인&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt; 서버 인증 플러그인과 JDBC가 충돌. &lt;/span&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;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;해결 방법&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;JDBC URL에 ?allowPublicKeyRetrieval=true&amp;amp;useSSL=false 추가&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;최종검증&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;아래의 명령어로 컨테이너 네트워크에서 직접 연결을 한다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;임시로 연결하는 것이라 네트워크 명은 testnet 이런식으로 명명해도 된다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1759848872471&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;docker run --rm -it --network [네트워크명] mariadb:10.6 \
  mysql -h 192.168.0.201 -u &amp;lt;정확한계정&amp;gt; -p [데이터베이스명] -e &quot;SELECT 1&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;SELECT 1 이 확인되면 연결완료!&amp;nbsp;&lt;/span&gt;&lt;/b&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;span style=&quot;&quot;&gt;브릿지 서버도 올라가는 순간 찍어놓았던 아래 데이터베이스 연결여부에 대한 디버깅용 코드도 확인이 되었다.&lt;/span&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;1067&quot; data-origin-height=&quot;20&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sIGyd/btsQ3COeUfP/y897cK23jZalpVSeWqPcuK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sIGyd/btsQ3COeUfP/y897cK23jZalpVSeWqPcuK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sIGyd/btsQ3COeUfP/y897cK23jZalpVSeWqPcuK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsIGyd%2FbtsQ3COeUfP%2Fy897cK23jZalpVSeWqPcuK%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;1067&quot; height=&quot;20&quot; data-origin-width=&quot;1067&quot; data-origin-height=&quot;20&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;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;이로써 데이터베이스 연결 성공&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>차곡차곡/error-log</category>
      <author>p퐝유p</author>
      <guid isPermaLink="true">https://nikeisme827.tistory.com/87</guid>
      <comments>https://nikeisme827.tistory.com/87#entry87comment</comments>
      <pubDate>Wed, 8 Oct 2025 00:02:50 +0900</pubDate>
    </item>
    <item>
      <title>헷갈리는 배열 정리해보기</title>
      <link>https://nikeisme827.tistory.com/86</link>
      <description>&lt;h3 data-end=&quot;145&quot; data-start=&quot;109&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;★ LinkedList와 List 차이점 &amp;ndash; 언제 뭘 써야 할까?&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-end=&quot;313&quot; data-start=&quot;147&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Java를 공부하다 보면 List, ArrayList, LinkedList 같은 자료구조를 자주 만나게 된다. 이름은 비슷한데, 정확히 무슨 차이가 있는지 헷갈리는 경우가 많다. 이번 글에서는 각각이 어떤 역할을 하는지, 그리고 어떤 상황에서 어떤 걸 쓰는 게 좋은지 정리해보려고 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;313&quot; data-start=&quot;147&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;338&quot; data-start=&quot;320&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;☆ List는 인터페이스&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;474&quot; data-start=&quot;340&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;먼저 List는 클래스가 아니라 &lt;b&gt;인터페이스&lt;/b&gt;다. 쉽게 말하면, 어떤 기능을 제공할지 약속만 해놓은 틀 같은 거다. 실제로 데이터를 저장하거나 조작하는 일은 ArrayList, LinkedList 같은 구현 클래스가 담당한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;474&quot; data-start=&quot;340&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot; data-start=&quot;109&quot; data-end=&quot;145&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;★&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;ArrayList와 LinkedList는 구현 방식이 다르다&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-end=&quot;767&quot; data-start=&quot;692&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;둘 다 List 인터페이스를 구현하고 있고, 데이터를 순서대로 저장할 수 있다. 하지만 내부 구조와 동작 방식에는 큰 차이가 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;767&quot; data-start=&quot;692&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;792&quot; data-start=&quot;769&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;✅ &lt;b&gt;ArrayList &amp;ndash; 배열 기반&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;908&quot; data-start=&quot;794&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;821&quot; data-start=&quot;794&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;내부적으로 배열을 사용해서 데이터를 저장한다.&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;863&quot; data-start=&quot;822&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;인덱스를 이용한 접근이 빠르다. (get(index) 속도가 빠름)&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;908&quot; data-start=&quot;864&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;중간에 삽입하거나 삭제할 때는 느리다. (요소들을 옮겨야 해서 시간이 걸림)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;934&quot; data-start=&quot;910&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;✅&lt;b&gt; LinkedList &amp;ndash; 노드 기반&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1056&quot; data-start=&quot;936&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;970&quot; data-start=&quot;936&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;노드들이 서로 연결되어 있는 구조다. (이중 연결 리스트)&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;1013&quot; data-start=&quot;971&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;중간에 데이터를 삽입하거나 삭제할 때 빠르다. (노드 연결만 바꾸면 됨)&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;1056&quot; data-start=&quot;1014&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;인덱스를 통한 접근은 느리다. (앞에서부터 순차적으로 찾아야 하기 때문)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;1061&quot; data-start=&quot;1058&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;145&quot; data-start=&quot;109&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;★ &lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;언제 어떤 걸 써야 할까?&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;상황추천 자료구조&lt;/span&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;1289&quot; data-start=&quot;1085&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody data-end=&quot;1289&quot; data-start=&quot;1128&quot;&gt;
&lt;tr data-end=&quot;1160&quot; data-start=&quot;1128&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1145&quot; data-start=&quot;1128&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;인덱스로 자주 접근할 경우&lt;/span&gt;&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1160&quot; data-start=&quot;1145&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;ArrayList&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1200&quot; data-start=&quot;1161&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1184&quot; data-start=&quot;1161&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;중간 삽입/삭제가 자주 일어나는 경우&lt;/span&gt;&lt;/td&gt;
&lt;td data-end=&quot;1200&quot; data-start=&quot;1184&quot; data-col-size=&quot;sm&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;LinkedList&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1239&quot; data-start=&quot;1201&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1224&quot; data-start=&quot;1201&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;데이터 크기가 자주 바뀌지 않는 경우&lt;/span&gt;&lt;/td&gt;
&lt;td data-end=&quot;1239&quot; data-start=&quot;1224&quot; data-col-size=&quot;sm&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;ArrayList&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1289&quot; data-start=&quot;1240&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1273&quot; data-start=&quot;1240&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;큐(Queue)처럼 앞뒤로 데이터를 넣고 빼야 할 경우&lt;/span&gt;&lt;/td&gt;
&lt;td data-end=&quot;1289&quot; data-start=&quot;1273&quot; data-col-size=&quot;sm&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;LinkedList&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1308&quot; data-start=&quot;1291&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;예시 &amp;ndash; 큐처럼 사용하기&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Queue&amp;lt;String&amp;gt; queue = new LinkedList&amp;lt;&amp;gt;(); queue.offer(&quot;apple&quot;); queue.poll(); // 가장 앞의 요소 제거&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1584&quot; data-start=&quot;1448&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1490&quot; data-start=&quot;1448&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;대부분의 경우에는 ArrayList를 사용하는 게 더 효율적이다.&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;1535&quot; data-start=&quot;1491&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;삽입과 삭제가 빈번한 경우에는 LinkedList를 고려해볼 만하다.&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;1584&quot; data-start=&quot;1536&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;항상 List로 선언해두고, 상황에 따라 구현체만 바꾸는 방식이 가장 유연하다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 data-end=&quot;195&quot; data-start=&quot;146&quot;&gt;&amp;nbsp;&lt;/h1&gt;
&lt;h1 data-end=&quot;195&quot; data-start=&quot;146&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;★ Java에서 ArrayList&amp;lt;String&amp;gt; vs String[] 차이점 정리&lt;/span&gt;&lt;/b&gt;&lt;/h1&gt;
&lt;p data-end=&quot;195&quot; data-start=&quot;146&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;1. 기본 개념부터 다름&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;585&quot; data-start=&quot;221&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody data-end=&quot;585&quot; data-start=&quot;310&quot;&gt;
&lt;tr data-end=&quot;349&quot; data-start=&quot;310&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;317&quot; data-start=&quot;310&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;자료구조&lt;/span&gt;&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;334&quot; data-start=&quot;317&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;배열 (Array)&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td data-col-size=&quot;md&quot; data-end=&quot;349&quot; data-start=&quot;334&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;컬렉션 클래스&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;394&quot; data-start=&quot;350&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;355&quot; data-start=&quot;350&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;크기&lt;/span&gt;&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;377&quot; data-start=&quot;355&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;고정됨 (한 번 정하면 변경 불가)&lt;/span&gt;&lt;/td&gt;
&lt;td data-end=&quot;394&quot; data-start=&quot;377&quot; data-col-size=&quot;md&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;동적으로 크기 조절 가능&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;483&quot; data-start=&quot;395&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;400&quot; data-start=&quot;395&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;선언&lt;/span&gt;&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;434&quot; data-start=&quot;400&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;String[] arr = new String[3];&lt;/span&gt;&lt;/td&gt;
&lt;td data-end=&quot;483&quot; data-start=&quot;434&quot; data-col-size=&quot;md&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;ArrayList&amp;lt;String&amp;gt; list = new ArrayList&amp;lt;&amp;gt;();&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;534&quot; data-start=&quot;484&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;489&quot; data-start=&quot;484&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;기능&lt;/span&gt;&lt;/td&gt;
&lt;td data-end=&quot;507&quot; data-start=&quot;489&quot; data-col-size=&quot;sm&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;단순 저장 및 인덱스로 접근&lt;/span&gt;&lt;/td&gt;
&lt;td data-end=&quot;534&quot; data-start=&quot;507&quot; data-col-size=&quot;md&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;추가, 삭제, 검색 등 다양한 메서드 제공&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;585&quot; data-start=&quot;535&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;540&quot; data-start=&quot;535&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;속도&lt;/span&gt;&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;560&quot; data-start=&quot;540&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;조금 더 빠름 (가볍고 단순함)&lt;/span&gt;&lt;/td&gt;
&lt;td data-end=&quot;585&quot; data-start=&quot;560&quot; data-col-size=&quot;md&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;상대적으로 느릴 수 있음 (기능 많음)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-end=&quot;590&quot; data-start=&quot;587&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-end=&quot;604&quot; data-start=&quot;592&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;2. 크기 유연성&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;954&quot; data-start=&quot;606&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;772&quot; data-start=&quot;606&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;String[]은 크기를 한 번 정하면 &lt;b&gt;변경이 안 된다&lt;/b&gt;.&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;772&quot; data-start=&quot;651&quot;&gt;
&lt;div&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;String[] arr = new String[3]; arr[0] = &quot;A&quot;; arr[1] = &quot;B&quot;; arr[2] = &quot;C&quot;; // arr[3] = &quot;D&quot;; // 에러 발생 &lt;/span&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li data-end=&quot;954&quot; data-start=&quot;774&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;ArrayList는 계속 add()로 요소를 추가할 수 있다.&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;954&quot; data-start=&quot;818&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; letter-spacing: 0px;&quot;&gt;ArrayList&amp;lt;String&amp;gt; list = new ArrayList&amp;lt;&amp;gt;(); list.add(&quot;A&quot;); list.add(&quot;B&quot;); list.add(&quot;C&quot;); list.add(&quot;D&quot;); // 문제 없음&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;980&quot; data-start=&quot;961&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;3. 사용 가능한 메서드 차이&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1186&quot; data-start=&quot;982&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1037&quot; data-start=&quot;982&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;배열은 거의 기능이 없다. 그냥 인덱스로 접근하고, 길이 구하는 정도 (arr.length)&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;1186&quot; data-start=&quot;1038&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;ArrayList는 여러 기능이 포함돼 있다.&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;1186&quot; data-start=&quot;1071&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; letter-spacing: 0px;&quot;&gt;list.add(&quot;apple&quot;); list.remove(&quot;apple&quot;); list.contains(&quot;banana&quot;); list.size(); list.get(2);&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1212&quot; data-start=&quot;1193&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;4. 제네릭 지원 (&amp;lt;&amp;gt;)&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1312&quot; data-start=&quot;1214&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1269&quot; data-start=&quot;1214&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;ArrayList&amp;lt;String&amp;gt;처럼 &lt;b&gt;제네릭 타입&lt;/b&gt;을 쓸 수 있어서 타입 안정성이 좋다.&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;1312&quot; data-start=&quot;1270&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;배열은 타입을 정하긴 하지만, 복잡한 구조에서는 제네릭처럼 쓸 수 없다.&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-end=&quot;1336&quot; data-start=&quot;1319&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;5. 사용 예와 추천 상황&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;상황추천 자료구조&lt;/span&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;1550&quot; data-start=&quot;1338&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody data-end=&quot;1550&quot; data-start=&quot;1380&quot;&gt;
&lt;tr data-end=&quot;1412&quot; data-start=&quot;1380&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1398&quot; data-start=&quot;1380&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;크기가 고정된 단순한 데이터&lt;/span&gt;&lt;/td&gt;
&lt;td data-end=&quot;1412&quot; data-start=&quot;1398&quot; data-col-size=&quot;sm&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;String[]&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1458&quot; data-start=&quot;1413&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1435&quot; data-start=&quot;1413&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;데이터 추가/삭제가 자주 필요할 때&lt;/span&gt;&lt;/td&gt;
&lt;td data-end=&quot;1458&quot; data-start=&quot;1435&quot; data-col-size=&quot;sm&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;ArrayList&amp;lt;String&amp;gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1505&quot; data-start=&quot;1459&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1481&quot; data-start=&quot;1459&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;반복문에서 빠르게 처리해야 할 경우&lt;/span&gt;&lt;/td&gt;
&lt;td data-end=&quot;1505&quot; data-start=&quot;1481&quot; data-col-size=&quot;sm&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;String[] (조금 더 빠름)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1550&quot; data-start=&quot;1506&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1527&quot; data-start=&quot;1506&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;기능이 다양한 조작이 필요한 경우&lt;/span&gt;&lt;/td&gt;
&lt;td data-end=&quot;1550&quot; data-start=&quot;1527&quot; data-col-size=&quot;sm&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;ArrayList&amp;lt;String&amp;gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1702&quot; data-start=&quot;1569&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1631&quot; data-start=&quot;1569&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;배열(String[])은 &lt;b&gt;가볍고 빠르지만&lt;/b&gt;, &lt;b&gt;기능이 제한적&lt;/b&gt;이고 &lt;b&gt;크기가 고정&lt;/b&gt;되어 있다.&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;1702&quot; data-start=&quot;1632&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;ArrayList&amp;lt;String&amp;gt;는 &lt;b&gt;유연하고 메서드가 많지&lt;/b&gt;만, 상대적으로 &lt;b&gt;성능은 조금 떨어질 수 있다&lt;/b&gt;.&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;1751&quot; data-start=&quot;1716&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;단순하고 고정된 데이터 구조가 필요하다면 배열을 쓰면 된다.&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;1842&quot; data-start=&quot;1752&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;하지만 대부분의 실무에서는 데이터가 계속 추가되고, 삭제되기도 하고, 검색이나 정렬 같은 작업도 해야 하기 때문에 ArrayList를 더 자주 쓰게 된다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>차곡차곡/Java</category>
      <author>p퐝유p</author>
      <guid isPermaLink="true">https://nikeisme827.tistory.com/86</guid>
      <comments>https://nikeisme827.tistory.com/86#entry86comment</comments>
      <pubDate>Sat, 28 Jun 2025 20:39:42 +0900</pubDate>
    </item>
    <item>
      <title>이때까지 회피해왔던 시간 복잡도 알아보기</title>
      <link>https://nikeisme827.tistory.com/85</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;나는 알고리즘 문제를 풀거나, 답을 구하기 위해 다른 천재분들이 풀어왔던 알고리즘 관련 글을 볼때&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;시간 복잡도와 공간 복잡도를 애써 무시, 회피해왔다.&lt;/span&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;font-family: 'Noto Serif KR';&quot;&gt;하지만 회피도 이제 한계가 왔다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;코드를 짜거나 진짜 뭔가 개발자 흉내를 내기 위해서라도 이러면 속도가 빠를거야, 효율적인 코드야 이런 근거 없는 생각보다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&quot;시간 복잡도&quot; / &quot;공간 복잡도&quot; 등을 고려하며 근거 있는 코드를 짜기 위해 이친구들과 친해지기로 마음을 먹어 글을 써본다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt; &lt;span style=&quot;font-family: 'Noto Serif KR'; color: #333333; text-align: start;&quot;&gt;★ 시간 복잡도&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #333333; text-align: start;&quot;&gt;&amp;nbsp; &amp;nbsp; - 시간 복잡도란 &lt;b&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;&quot;입력값에 비해 얼마나 일을 수행해야 하는가?&quot;&lt;/span&gt; &lt;/b&gt;를 의미한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #333333; text-align: start;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; 입력값과 문제를 해결하는데 걸리는 시간과의 상관관계를 말한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #333333; text-align: start;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #333333; text-align: start;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; 만약, 입력 값이 2배로 늘어났을 때,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #333333; text-align: start;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; 문제를 해결하는데 시간은 몇배로 늘어나는지를 보는 것을 말한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #333333; text-align: start;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; 시간 복잡도를 고려한 알고리즘은 입력 값이 늘어나도 걸리는 시간이 덜 늘어나는 알고리즘이 좋은 것이라 할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt; ☆ 최댓값 찾기 알고리즘의 시간 복잡도 판단해보기 &lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;첫번째 방법&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1748935037976&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def find_max_num(array):
    for number in array: # array 의 길이만큼 아래 연산이 실행
        is_max_num = True # 최댓값 변수 (flag)
        for compare_number in array: # array 의 길이만큼 아래 연산이 실행
            if number &amp;lt; compare_number: # 비교 연산 1번 실행
                is_max_num = False # 대입 연산 1번 실행
        if is_max_num:# 비교 연산 1번 실행
            return number

print(&quot;정답 = 6 / 현재 풀이 값 = &quot;, find_max_num([3, 5, 6, 1, 2, 4]))
print(&quot;정답 = 6 / 현재 풀이 값 = &quot;, find_max_num([6, 6, 6]))
print(&quot;정답 = 1888 / 현재 풀이 값 = &quot;, find_max_num([6, 9, 2, 7, 1888]))&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;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt; 이 해결 방법은 각 숫자마다 모든 다른 숫자와 비교해서 최대값인지 확인하는 코드이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;만약 다른 모든 값보다 크다면 반복문을 중단한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt; 바로, &lt;b&gt;각 줄이 실행되는 걸 1번의 연산이 된다고 생각&lt;/b&gt;하고&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;/span&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;font-family: 'Noto Serif KR';&quot;&gt;아래와 같이 계산하여 위의 함수는&lt;span style=&quot;background-color: #9feec3;&quot;&gt; &lt;b&gt;2* N^2 + N &lt;/b&gt;&lt;/span&gt;만큼의 &lt;span data-token-index=&quot;2&quot;&gt;시간이 걸린 것이라고 알 수 있다.&amp;nbsp;&lt;/span&gt;&lt;/span&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;font-family: 'Noto Serif KR';&quot;&gt;1. &lt;span style=&quot;background-color: #9feec3;&quot;&gt;array의 길이 x array의 길이 x ( 비교 연산 1번 + 대입 연산 1번) &amp;rarr; &lt;span style=&quot;font-family: 'Noto Serif KR'; color: #333333; text-align: start;&quot;&gt;&amp;nbsp;&lt;b&gt;N x N x 2&amp;nbsp;&lt;/b&gt;&lt;/span&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp;(여기서 array(입력값)의 길이는 보통 N이라고 표현한다.)&lt;/span&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;font-family: 'Noto Serif KR'; color: #333333; text-align: start;&quot;&gt;2. &lt;span style=&quot;background-color: #9feec3;&quot;&gt;array의 길이 x 비교 연산 1번 &lt;span style=&quot;font-family: 'Noto Serif KR'; color: #333333; text-align: start;&quot;&gt;&amp;rarr;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #333333; text-align: start;&quot;&gt;&amp;nbsp;&lt;b&gt;N&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #333333; text-align: start;&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;두번째 방법&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1748936200168&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def find_max_num(array):
    max_num = array[0] # 연산 1번 실행
    for number in array:  # array의 길이 만큼 아래 연산이 실행
        if number &amp;gt; max_num: # 비교 연산 1번 실행
            max_num = number # 대입 연산 1번 실행

    return max_num


print(&quot;정답 = 6 / 현재 풀이 값 = &quot;, find_max_num([3, 5, 6, 1, 2, 4]))
print(&quot;정답 = 6 / 현재 풀이 값 = &quot;, find_max_num([6, 6, 6]))
print(&quot;정답 = 1888 / 현재 풀이 값 = &quot;, find_max_num([6, 9, 2, 7, 1888]))&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;아래와 같이 계산하여 &lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;1 + 2 x N&lt;/b&gt;&lt;/span&gt; 만큼의 시간이 걸린 것이라고 할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; background-color: #9feec3;&quot;&gt;max_num 대입 연산 1번&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; background-color: #9feec3;&quot;&gt;array의 길이 x (비교 연산 1번 + 대입 연산 1번)&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #333333; text-align: start;&quot;&gt;★ 비교하기&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #333333; text-align: start;&quot;&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #333333; text-align: start;&quot;&gt;&amp;nbsp; &amp;nbsp; 두 함수를 비교해보면 &lt;span style=&quot;font-family: 'Noto Serif KR'; color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;두번째 함수의 &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;1 + 2 x N 가 더 효율적&lt;/span&gt;이라고 볼 수 있다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #333333; text-align: start;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt; ☆ 2N^2 + N vs 2N+1&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 107px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 22px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 22px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;N의 길이&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 22px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt; &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&amp;sum;&lt;/span&gt; &lt;b&gt;2N^2 + N&lt;/b&gt; &lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 22px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #333333; text-align: start;&quot;&gt; &amp;sum; &lt;b&gt;2N+1&lt;/b&gt; &lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;1&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;3&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;3&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;10&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;210&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;21&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;100&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;20100&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;201&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;1000&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;2001000&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;2001&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;10000&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;200010000&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;20001&lt;/span&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;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- 위의 표를 보면,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; background-color: #ffc9af;&quot;&gt;&amp;nbsp; &lt;b&gt;2N^2 + N 의 연산량이 나온 첫번째 풀이 방법은 &lt;b&gt;N^2 만큼의 연산량이 필요하고,&lt;/b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; background-color: #ffc9af;&quot;&gt;&lt;b&gt;&lt;b&gt;&amp;nbsp; &lt;b&gt;2N+1 의 연산량이 나온 두번째 풀이 방법은 N 만큼의 연산량이 필요하다.&lt;/b&gt;&lt;/b&gt;&lt;/b&gt;&lt;/span&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;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;이렇게 알아봄으로써&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;아, 시간복잡도를 고려했을때 좀 코드를 고쳐야겠는데??&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;시간 복잡도를 고려하지 않고 코드를 짰네 바보같아 &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;이렇게 말할 수 있도록 더욱 성장하는 사람이 되고 싶다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;</description>
      <category>차곡차곡/Algorithms</category>
      <author>p퐝유p</author>
      <guid isPermaLink="true">https://nikeisme827.tistory.com/85</guid>
      <comments>https://nikeisme827.tistory.com/85#entry85comment</comments>
      <pubDate>Sat, 14 Jun 2025 22:45:58 +0900</pubDate>
    </item>
    <item>
      <title>[DFS]백준 11724번 - 연결 요소의 개수_Java</title>
      <link>https://nikeisme827.tistory.com/84</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;연결된 요소의 개수를 구하는 문제는 &quot;연결&quot; 이라는 키워드로 봐서&amp;nbsp; DFS 혹은 BFS 유형의 문제이다.&lt;/span&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;1111&quot; data-origin-height=&quot;814&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/J3Doj/btsObpRR6xe/vuf0olh5Z3Ej3lOG0pVHOK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/J3Doj/btsObpRR6xe/vuf0olh5Z3Ej3lOG0pVHOK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/J3Doj/btsObpRR6xe/vuf0olh5Z3Ej3lOG0pVHOK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJ3Doj%2FbtsObpRR6xe%2Fvuf0olh5Z3Ej3lOG0pVHOK%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;1111&quot; height=&quot;814&quot; data-origin-width=&quot;1111&quot; data-origin-height=&quot;814&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;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;서로 연결되었다는 정보를 2차원 배열 boolean 형태로 표현하였다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;이미 방문한 지점을 다시 방문하지 않으려면 1차원 배열 boolean 형태로 표현하였다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;연결된 지점을 찾는 것 이기 때문에 정점의 개수만큼 DFS를 반복했다.&lt;/span&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;1101&quot; data-origin-height=&quot;1440&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/prL5x/btsOb8PDqXP/DV5ljkII3eElCD8tHSwQJ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/prL5x/btsOb8PDqXP/DV5ljkII3eElCD8tHSwQJ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/prL5x/btsOb8PDqXP/DV5ljkII3eElCD8tHSwQJ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FprL5x%2FbtsOb8PDqXP%2FDV5ljkII3eElCD8tHSwQJ0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;561&quot; height=&quot;734&quot; data-origin-width=&quot;1101&quot; data-origin-height=&quot;1440&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;div style=&quot;background-color: #1f1f1f; color: #cccccc;&quot;&gt;
&lt;div&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;package&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;java_dfs&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;test&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;;&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;java&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;io&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;BufferedReader&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;java&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;io&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;BufferedWriter&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;java&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;io&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;IOException&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;java&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;io&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;InputStreamReader&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;java&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;io&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;OutputStreamWriter&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;java&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;util&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;StringTokenizer&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;;&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;ConnetcedComponent&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; {&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;final&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;static&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #4fc1ff;&quot;&gt;MAX&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #b5cea8;&quot;&gt;1000&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #b5cea8;&quot;&gt;10&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; ; &lt;/span&gt;&lt;span style=&quot;color: #6a9955;&quot;&gt;// 최댓값은 여유있게 10정도 늘려주자&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;static&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;boolean&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;graph&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;[][]; &lt;/span&gt;&lt;span style=&quot;color: #6a9955;&quot;&gt;// 2차원 배열의 그래프 생성&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;static&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;boolean&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;visited&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;[]; &lt;/span&gt;&lt;span style=&quot;color: #6a9955;&quot;&gt;// 방문여부 배열&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;static&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;N&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;M&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;; &lt;/span&gt;&lt;span style=&quot;color: #6a9955;&quot;&gt;// N : 정점의 개수 , M: 간선의 개수&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;static&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;answer&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;; &lt;/span&gt;&lt;span style=&quot;color: #6a9955;&quot;&gt;// 연결요소 개수&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;static&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;void&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #dcdcaa;&quot;&gt;dfs&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;index&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;){&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;visited&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;index&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;] &lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; ; &lt;/span&gt;&lt;span style=&quot;color: #6a9955;&quot;&gt;// 방문여부 true로 변경&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #c586c0;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #b5cea8;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;; &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;lt;=&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;M&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;; &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;++&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;){ &lt;/span&gt;&lt;span style=&quot;color: #6a9955;&quot;&gt;// 간선 개수 만큼 반복&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #c586c0;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;visited&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;] &lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;false&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;graph&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;index&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;][&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;]){ &lt;/span&gt;&lt;span style=&quot;color: #6a9955;&quot;&gt;// 다음 방문 예정인 요소가 fasle상태이고, idx번/i번째 요소가 연결되어있어야함 &lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #dcdcaa;&quot;&gt;dfs&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;);&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;public&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;static&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;void&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #dcdcaa;&quot;&gt;main&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;String&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;[] &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;args&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;throws&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;IOException&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;{&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #6a9955;&quot;&gt;//0.입력 초기화&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;BufferedReader&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;br&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #c586c0;&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #dcdcaa;&quot;&gt;BufferedReader&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #c586c0;&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #dcdcaa;&quot;&gt;InputStreamReader&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;System&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #4fc1ff;&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;));&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;BufferedWriter&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;bw&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #c586c0;&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #dcdcaa;&quot;&gt;BufferedWriter&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #c586c0;&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #dcdcaa;&quot;&gt;OutputStreamWriter&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;System&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #4fc1ff;&quot;&gt;out&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;));&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;StringTokenizer&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;st&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #c586c0;&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #dcdcaa;&quot;&gt;StringTokenizer&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;br&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #dcdcaa;&quot;&gt;readLine&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;());&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;N&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;Integer&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #dcdcaa;&quot;&gt;parseInt&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;st&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #dcdcaa;&quot;&gt;nextToken&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;()); &lt;/span&gt;&lt;span style=&quot;color: #6a9955;&quot;&gt;//N : 정점의 개수&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;M&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;Integer&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #dcdcaa;&quot;&gt;parseInt&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;st&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #dcdcaa;&quot;&gt;nextToken&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;()); &lt;/span&gt;&lt;span style=&quot;color: #6a9955;&quot;&gt;//N: 노드의 개수&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #6a9955;&quot;&gt;// 1. 그래프의 연결정보 채우기&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;graph&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #c586c0;&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;boolean&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #4fc1ff;&quot;&gt;MAX&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;][&lt;/span&gt;&lt;span style=&quot;color: #4fc1ff;&quot;&gt;MAX&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;]; &lt;/span&gt;&lt;span style=&quot;color: #6a9955;&quot;&gt;// 그래프 연결 정보 채우기 &lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;visited&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #c586c0;&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;boolean&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #4fc1ff;&quot;&gt;MAX&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;]; &amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #6a9955;&quot;&gt;// 방문여부 배열 채우기 &lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #c586c0;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #b5cea8;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;; &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;M&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;; &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;++&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;){ &lt;/span&gt;&lt;span style=&quot;color: #6a9955;&quot;&gt;// 정점의 개수 &lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;st&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #c586c0;&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #dcdcaa;&quot;&gt;StringTokenizer&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;br&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #dcdcaa;&quot;&gt;readLine&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;());&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;u&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;Integer&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #dcdcaa;&quot;&gt;parseInt&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;st&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #dcdcaa;&quot;&gt;nextToken&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;()); &lt;/span&gt;&lt;span style=&quot;color: #6a9955;&quot;&gt;// 양끝점 중 하나&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;v&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;Integer&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #dcdcaa;&quot;&gt;parseInt&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;st&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #dcdcaa;&quot;&gt;nextToken&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;()); &lt;/span&gt;&lt;span style=&quot;color: #6a9955;&quot;&gt;// 양끝점 중 하나&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #6a9955;&quot;&gt;// 재방문을 막기 위해 양끝점 둘다 true로 채워줘야함&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;graph&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;u&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;][&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;v&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;] &lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;; &lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;graph&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;v&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;][&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;u&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;] &lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;; &lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #6a9955;&quot;&gt;//2. 재귀 함수 호출&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #c586c0;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #b5cea8;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;; &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;lt;=&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;M&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;; &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;++&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;){ &lt;/span&gt;&lt;span style=&quot;color: #6a9955;&quot;&gt;// 간선의 개수 만큼&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #c586c0;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;!&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;visited&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;]){ &lt;/span&gt;&lt;span style=&quot;color: #6a9955;&quot;&gt;// 방문을 하지 않았다면&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #dcdcaa;&quot;&gt;dfs&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;); &lt;/span&gt;&lt;span style=&quot;color: #6a9955;&quot;&gt;// 재귀함수 호출&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;answer&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;++&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;; &lt;/span&gt;&lt;span style=&quot;color: #6a9955;&quot;&gt;// 연결요소 개수 카운트 증가&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #6a9955;&quot;&gt;// 3. 출력&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;bw&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #dcdcaa;&quot;&gt;write&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;String&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #dcdcaa;&quot;&gt;valueOf&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;answer&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;));&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;bw&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #dcdcaa;&quot;&gt;close&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;();&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;br&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #dcdcaa;&quot;&gt;close&lt;/span&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;();&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;&amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #cccccc;&quot;&gt;}&lt;/span&gt;&lt;/div&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;★ 결과&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;753&quot; data-origin-height=&quot;60&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9XRgN/btsOaOLrsfb/ouYhGxmIp1kthK9UhxPGF0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9XRgN/btsOaOLrsfb/ouYhGxmIp1kthK9UhxPGF0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9XRgN/btsOaOLrsfb/ouYhGxmIp1kthK9UhxPGF0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9XRgN%2FbtsOaOLrsfb%2FouYhGxmIp1kthK9UhxPGF0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;753&quot; height=&quot;60&quot; data-origin-width=&quot;753&quot; data-origin-height=&quot;60&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;</description>
      <category>차곡차곡/Algorithms</category>
      <author>p퐝유p</author>
      <guid isPermaLink="true">https://nikeisme827.tistory.com/84</guid>
      <comments>https://nikeisme827.tistory.com/84#entry84comment</comments>
      <pubDate>Sun, 25 May 2025 22:28:26 +0900</pubDate>
    </item>
    <item>
      <title>[알고리즘]  DFS 재귀함수 - 타겟넘버문제 풀이</title>
      <link>https://nikeisme827.tistory.com/83</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/43165&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/43165&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1747484219616&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;프로그래머스&quot; data-og-description=&quot;SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프&quot; data-og-host=&quot;programmers.co.kr&quot; data-og-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/43165&quot; data-og-url=&quot;https://programmers.co.kr/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/LRPSl/hyYU2EaO3I/03tLxjROkgkwO5BDQlMdB0/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960,https://scrap.kakaocdn.net/dn/y09EU/hyYW2ccr7q/WoVaTkNBrqB53izvNFIkvk/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/43165&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/43165&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/LRPSl/hyYU2EaO3I/03tLxjROkgkwO5BDQlMdB0/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960,https://scrap.kakaocdn.net/dn/y09EU/hyYW2ccr7q/WoVaTkNBrqB53izvNFIkvk/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;프로그래머스&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;programmers.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;42&quot; data-start=&quot;0&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; background-color: #9feec3;&quot;&gt;&lt;b&gt;DFS (깊이 우선 탐색, Depth-First Search)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-end=&quot;173&quot; data-start=&quot;44&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;DFS는 &lt;b&gt;그래프&lt;/b&gt;나 &lt;b&gt;트리&lt;/b&gt;에서 노드를 깊이 우선으로 ㅊ방문하는 탐색 알고리즘입니다. 즉, &lt;b&gt;가장 깊은 노드&lt;/b&gt;까지 탐색한 후, 더 이상 깊이 갈 수 없으면 &lt;b&gt;다시 이전 노드로 돌아와&lt;/b&gt; 다른 경로를 탐색하는 방식입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;173&quot; data-start=&quot;44&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;198&quot; data-start=&quot;180&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; background-color: #9feec3;&quot;&gt;&lt;b&gt;DFS의 특징&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;451&quot; data-start=&quot;200&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;270&quot; data-start=&quot;200&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;완전탐색 (Brute Force) 가능&lt;/b&gt;&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;270&quot; data-start=&quot;234&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;270&quot; data-start=&quot;234&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;모든 가능한 경로를 탐색하여 최적의 해를 찾는 데 유용합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;326&quot; data-start=&quot;272&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;재귀적 구조&lt;/b&gt;&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;326&quot; data-start=&quot;291&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;326&quot; data-start=&quot;291&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;일반적으로 &lt;b&gt;재귀&lt;/b&gt;나 &lt;b&gt;스택&lt;/b&gt;을 이용하여 구현합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;378&quot; data-start=&quot;328&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;메모리 효율성&lt;/b&gt;&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;378&quot; data-start=&quot;348&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;378&quot; data-start=&quot;348&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;BFS보다 메모리를 적게 사용하는 경우가 많습니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;451&quot; data-start=&quot;380&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;백트래킹과의 결합&lt;/b&gt;&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;451&quot; data-start=&quot;402&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;451&quot; data-start=&quot;402&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;특정 조건에서 탐색을 중단하고 이전 상태로 돌아가는 백트래킹과 함께 자주 사용됩니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-end=&quot;482&quot; data-start=&quot;458&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; background-color: #9feec3;&quot;&gt;&lt;b&gt;&amp;nbsp;DFS의 기본 동작 원리&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;589&quot; data-start=&quot;484&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;501&quot; data-start=&quot;484&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;시작 노드에서 출발&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;525&quot; data-start=&quot;502&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;깊이 있는 노드로 최대한 이동&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;564&quot; data-start=&quot;526&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;더 이상 갈 곳이 없으면 이전 노드로 돌아옴 (백트래킹)&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;589&quot; data-start=&quot;565&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;모든 노드를 방문할 때까지 반복&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;589&quot; data-start=&quot;565&quot;&gt;&amp;nbsp;&lt;/li&gt;
&lt;/ol&gt;
&lt;pre id=&quot;code_1747484261434&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Solution {
    int answer;  // 최종 정답을 저장할 변수

    public int solution(int[] numbers, int target) {
        answer = 0;  // 초기화 (각 테스트 케이스마다 초기화 필요)
        dfs(0, 0, numbers, target);  // DFS 탐색 시작 (시작 인덱스 0, 초기 합 0)
        return answer;  // 최종 정답 반환
    }

    void dfs(int n, int sum, int[] numbers, int target) {
        // 모든 숫자를 다 사용한 경우 (트리의 리프 노드에 도달)
        if (n == numbers.length) {
            // 목표 값과 현재 합이 일치하는지 확인
            if (sum == target) 
                answer++;  // 목표 값 달성 시 정답 카운트 증가
            return;  // 종료 (리프 노드 도달 시 리턴)
        }

        // 현재 숫자를 더한 경우
        dfs(n + 1, sum + numbers[n], numbers, target);
        
        // 현재 숫자를 뺀 경우
        dfs(n + 1, sum - numbers[n], numbers, target);
    }
}&lt;/code&gt;&lt;/pre&gt;</description>
      <author>p퐝유p</author>
      <guid isPermaLink="true">https://nikeisme827.tistory.com/83</guid>
      <comments>https://nikeisme827.tistory.com/83#entry83comment</comments>
      <pubDate>Sat, 17 May 2025 21:20:18 +0900</pubDate>
    </item>
    <item>
      <title>[Docker] 3. 도커 기본 명령어 익히기</title>
      <link>https://nikeisme827.tistory.com/81</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #ffc1c8;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #000000;&quot;&gt;★ 이미지 다운로드&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #000000;&quot;&gt;&amp;nbsp; &amp;nbsp; - 이미지명만 입력해도 최신버전(latest)으로 다운된다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1746376105963&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# docker pull 이미지명
$ docker pull nginx # docker pull nginx:latest와 동일하게 작동&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;675&quot; data-origin-height=&quot;285&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cVNYKf/btsNKZy2dfF/NzkheeoumomMrf3jpeziKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cVNYKf/btsNKZy2dfF/NzkheeoumomMrf3jpeziKk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cVNYKf/btsNKZy2dfF/NzkheeoumomMrf3jpeziKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcVNYKf%2FbtsNKZy2dfF%2FNzkheeoumomMrf3jpeziKk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;675&quot; height=&quot;285&quot; data-origin-width=&quot;675&quot; data-origin-height=&quot;285&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;span style=&quot;font-family: 'Noto Serif KR'; color: #000000;&quot;&gt;이미지를 다운로드 할 때 &lt;b&gt;Dockerhub&lt;/b&gt;이라는 곳에서 이미지를 다운 받는다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #000000;&quot;&gt;Dockerhub도 마찬가지로 사람들이 올려놓은 이미지들이 저장되어 있어서 pull을 통해 다운받아서 사용할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #000000;&quot;&gt;&lt;b&gt;Dockerhub&lt;/b&gt;은 Github처럼 &lt;b&gt;이미지를 저장 및 다운받을 수 있는 저장소 역할&lt;/b&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;1916&quot; data-origin-height=&quot;317&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cQPHYL/btsNJYnhcTJ/9XpTBLR8d2sYxLZquvVrnK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cQPHYL/btsNJYnhcTJ/9XpTBLR8d2sYxLZquvVrnK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cQPHYL/btsNJYnhcTJ/9XpTBLR8d2sYxLZquvVrnK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcQPHYL%2FbtsNJYnhcTJ%2F9XpTBLR8d2sYxLZquvVrnK%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;1916&quot; height=&quot;317&quot; data-origin-width=&quot;1916&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;&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;span style=&quot;font-family: 'Noto Serif KR'; color: #000000;&quot; data-token-index=&quot;0&quot;&gt;[특정 버전 이미지 다운로드] &lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1746376320508&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# docker pull 이미지명:태그명
$ docker pull nginx:stable-perl&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;span style=&quot;font-family: 'Noto Serif KR'; color: #000000;&quot;&gt;특정 버전을 나타내는 이름을 &lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;태그명&lt;/b&gt;&lt;/span&gt;이라고 한다. 태그명은 dockerhub에서 확인할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1894&quot; data-origin-height=&quot;637&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/y9BDC/btsNJ1K2zRW/fkKfVAgn6SzVLVRwRxMdBk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/y9BDC/btsNJ1K2zRW/fkKfVAgn6SzVLVRwRxMdBk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/y9BDC/btsNJ1K2zRW/fkKfVAgn6SzVLVRwRxMdBk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fy9BDC%2FbtsNJ1K2zRW%2FfkKfVAgn6SzVLVRwRxMdBk%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;278&quot; data-origin-width=&quot;1894&quot; data-origin-height=&quot;637&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;823&quot; data-origin-height=&quot;147&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cM0idb/btsNJRIvdwj/YCz1B4MKmgKBRLs34ctvp1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cM0idb/btsNJRIvdwj/YCz1B4MKmgKBRLs34ctvp1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cM0idb/btsNJRIvdwj/YCz1B4MKmgKBRLs34ctvp1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcM0idb%2FbtsNJRIvdwj%2FYCz1B4MKmgKBRLs34ctvp1%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;823&quot; height=&quot;147&quot; data-origin-width=&quot;823&quot; data-origin-height=&quot;147&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;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #ffc1c8;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #000000; text-align: start;&quot;&gt;★ 이미지 조회&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #000000; text-align: start;&quot;&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #000000; text-align: start;&quot;&gt;- 다운받은 모든 이미지 조회 &lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1746376469251&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;docker image ls&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;560&quot; data-origin-height=&quot;79&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bPa2IB/btsNJRaCEIB/oxVZgy42nowqHlMild2l30/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bPa2IB/btsNJRaCEIB/oxVZgy42nowqHlMild2l30/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bPa2IB/btsNJRaCEIB/oxVZgy42nowqHlMild2l30/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbPa2IB%2FbtsNJRaCEIB%2FoxVZgy42nowqHlMild2l30%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;560&quot; height=&quot;79&quot; data-origin-width=&quot;560&quot; data-origin-height=&quot;79&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;span style=&quot;color: #000000; font-family: 'Noto Serif KR';&quot;&gt;항목 명 의미&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;REPOSITORY&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이미지의 이름&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;TAG&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이미지의 버전 또는 라벨. 기본값은 latest이며, 직접 태그를 만들 수도 있다.&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;IMAGE ID&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;color: #000000;&quot;&gt;해당 이미지의 고유 식별자입니 컨테이너를 만들거나 삭제할 때 사용 가능&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;CREATED&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이미지가 만들어진 시점.&amp;nbsp; docker hub 에 만들어진 시점을 의미&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;SIZE&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이미지의 용량 . 디스크에서 이 이미지가 차지하는 공간을 나타냄.&lt;/span&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;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #ffc1c8;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #000000; text-align: start;&quot;&gt; ★ 이미지 삭제&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #000000; text-align: start;&quot;&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #000000; text-align: start;&quot;&gt;특정 이미지 삭제할 때,&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1746376739241&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ docker image rm [이미지 ID 또는 이미지명]&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;rm : remove의 약자&lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #000000;&quot;&gt;이미지 ID를 입력할 때 전체 ID를 다 입력하지 않고 ID의 일부만 입력해도 된다. (단, ID의 일부만 입력했을 때, 입력한 ID의 일부를 가진 이미지가 단 1개여야 한다.)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;컨테이너에서 사용하고 있지 않은 이미지만 삭제가 가능하다.&lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;/span&gt;&lt;/span&gt;&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;691&quot; data-origin-height=&quot;58&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mfo7J/btsNJTM2Xqb/r8eUC96fKM1Z0K8WC3rDik/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mfo7J/btsNJTM2Xqb/r8eUC96fKM1Z0K8WC3rDik/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mfo7J/btsNJTM2Xqb/r8eUC96fKM1Z0K8WC3rDik/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fmfo7J%2FbtsNJTM2Xqb%2Fr8eUC96fKM1Z0K8WC3rDik%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;691&quot; height=&quot;58&quot; data-origin-width=&quot;691&quot; data-origin-height=&quot;58&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;span style=&quot;font-family: 'Noto Serif KR'; color: #000000;&quot;&gt;중지된 컨테이너에서 사용하고 있는 이미지 강제 삭제할 때,&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1746376829760&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ docker image rm -f [이미지 ID 또는 이미지명]&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;span style=&quot;font-family: 'Noto Serif KR'; color: #000000;&quot;&gt;실행 중인 컨테이너에서 사용하고 있는 이미지는 강제로 삭제할 수 없다. &lt;/span&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;color: #000000;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; text-align: start;&quot;&gt;전체 이미지 삭제할 때,&lt;/span&gt; &lt;span style=&quot;font-family: 'Noto Serif KR'; text-align: start;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1746376878720&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 컨테이너에서 사용하고 있지 않은 이미지만 전체 삭제
$ docker image rm $(docker images -q)

# 컨테이너에서 사용하고 있는 이미지를 포함해서 전체 이미지 삭제
$ docker image rm -f $(docker images -q)&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;span style=&quot;font-family: 'Noto Serif KR'; color: #000000;&quot;&gt;docker images -q : 시스템에 있는 모든 이미지의 ID를 반환한다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #000000;&quot;&gt;&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; 여기서 -q 옵션은 quite를 의미하며, 상세 정보 대신에 각 이미지의 고유한 ID만 표시하도록 지시한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #ffc1c8;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #000000; text-align: start;&quot;&gt;★ 컨테이너 생성&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt; 이미지를 바탕으로 컨테이너를 &lt;span style=&quot;color: #000000;&quot; data-token-index=&quot;1&quot;&gt;생성&lt;/span&gt;한다. 이 때, 컨테이너를 &lt;span style=&quot;color: #000000;&quot; data-token-index=&quot;3&quot;&gt;실행시키지는 않는다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt; (컨테이너를 실행하지 않고 생성만 하는 경우가 잘 없어서, 이 명령어는 잘 사용하지 않는다.)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt; &amp;rarr; 로컬 환경에 다운받은 이미지가 없다면 Dockerhub으로부터 이미지를 다운(&lt;span style=&quot;color: #000000; background-color: #9feec3;&quot; data-token-index=&quot;1&quot;&gt;docker pull&lt;/span&gt;)받아서 컨테이너를 생성한다. &lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1746377067229&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# docker create 이미지명[:태그명]
$ docker create nginx

$ docker ps -a # 모든 컨테이너 조회&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;852&quot; data-origin-height=&quot;277&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CyiXb/btsNJSOaRAB/ZlTSdfKTUKklzdppodkHYk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CyiXb/btsNJSOaRAB/ZlTSdfKTUKklzdppodkHYk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CyiXb/btsNJSOaRAB/ZlTSdfKTUKklzdppodkHYk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCyiXb%2FbtsNJSOaRAB%2FZlTSdfKTUKklzdppodkHYk%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;852&quot; height=&quot;277&quot; data-origin-width=&quot;852&quot; data-origin-height=&quot;277&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;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #ffc1c8;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #000000; text-align: start;&quot;&gt;★ 컨테이너&amp;nbsp; 실행&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt; 정지되어 있는 컨테이너를 실행시킨다.&lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1746377291959&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# docker start 컨테이너명[또는 컨테이너 ID]
$ docker start 컨테이너명[또는 컨테이너 ID]

$ docker ps # 실행중인 컨테이너 조회

# Nginx 컨테이너 중단 후 삭제하기
$ docker ps # 실행 중인 컨테이너 조회
$ docker stop {nginx를 실행시킨 Contnainer ID} # 컨테이너 중단
$ docker rm {nginx를 실행시킨 Contnainer ID} # 컨테이너 삭제
$ docker image rm nginx # Nginx 이미지 삭제&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;922&quot; data-origin-height=&quot;171&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/QeZIn/btsNLVbB2tx/n2XtS3ETL8G3kFKdQhwE51/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/QeZIn/btsNLVbB2tx/n2XtS3ETL8G3kFKdQhwE51/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/QeZIn/btsNLVbB2tx/n2XtS3ETL8G3kFKdQhwE51/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQeZIn%2FbtsNLVbB2tx%2Fn2XtS3ETL8G3kFKdQhwE51%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;922&quot; height=&quot;171&quot; data-origin-width=&quot;922&quot; data-origin-height=&quot;171&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;968&quot; data-origin-height=&quot;201&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/UPZvL/btsNK4G0TGA/rPoLkjI9EA4vXYO6uDeVF0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/UPZvL/btsNK4G0TGA/rPoLkjI9EA4vXYO6uDeVF0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/UPZvL/btsNK4G0TGA/rPoLkjI9EA4vXYO6uDeVF0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FUPZvL%2FbtsNK4G0TGA%2FrPoLkjI9EA4vXYO6uDeVF0%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;968&quot; height=&quot;201&quot; data-origin-width=&quot;968&quot; data-origin-height=&quot;201&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;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #ffc1c8;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #000000; text-align: start;&quot;&gt;★ 컨테이너&amp;nbsp; 생성 + 실행&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt; 이미지를 바탕으로 컨테이너를 생성한 뒤, 컨테이너를 실행까지 시킨다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;(처음에 이미지를 바탕으로 컨테이너를 실행시키고 싶을 때, 이 명령어를 자주 사용한다고 한다.)&lt;/span&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;font-family: 'Noto Serif KR';&quot;&gt; ▶ 로컬 환경에 다운받은 이미지가 없다면 Dockerhub으로부터 이미지를 다운(docker pull)받아서 실행시킨다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt; &lt;span style=&quot;font-family: 'Noto Serif KR'; color: #333333; text-align: start;&quot;&gt;▶&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt; Dockerhub으로부터 &lt;b&gt;새롭게 갱신된 이미지를 다운&lt;/b&gt; 받고 싶다면 docker pull 명령어를 활용해야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1746377621834&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# docker run 이미지명[:태그명]
$ docker run nginx # 포그라운드에서 실행 (추가적인 명령어 조작을 할 수가 없음)

# Ctrl + C로 종료할 수 있음&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;805&quot; data-origin-height=&quot;311&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/baItTc/btsNJO55pZ0/uUChEgT0l1PtebWtyF6XZ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/baItTc/btsNJO55pZ0/uUChEgT0l1PtebWtyF6XZ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/baItTc/btsNJO55pZ0/uUChEgT0l1PtebWtyF6XZ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbaItTc%2FbtsNJO55pZ0%2FuUChEgT0l1PtebWtyF6XZ1%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;805&quot; height=&quot;311&quot; data-origin-width=&quot;805&quot; data-origin-height=&quot;311&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;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; background-color: #9feec3;&quot;&gt;※ 포그라운드 (foreground) vs 백그라운드 &lt;span style=&quot;color: #000000;&quot; data-token-index=&quot;0&quot;&gt;(background) 차이&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt; &lt;span style=&quot;color: #d44c47;&quot; data-token-index=&quot;0&quot;&gt;포그라운드 : &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot; data-token-index=&quot;2&quot;&gt;내가 실행시킨 프로그램의 내용이 화면에서 실행되고 출력되는 상태&lt;/span&gt;를 뜻한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;그러다보니 포그라운드 상태에서는 다른 프로그램을 조작 불가.&lt;/span&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;font-family: 'Noto Serif KR';&quot;&gt;&lt;span style=&quot;color: #d44c47;&quot; data-token-index=&quot;4&quot;&gt;백그라운드 : &lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color: #000000;&quot; data-token-index=&quot;6&quot;&gt;내가 실행시킨 프로그램이 컴퓨터 내부적으로 실행되는 상태&lt;/span&gt;를 의미. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 그래서 프로그램이 어떻게 실행되고 있는 지에 대한 정보를 화면에서 확인 불가.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;이런 특성 때문에 다른 명령어를 추가로 입력할 수도 있고, 새로운 프로그램을 조작할 수도 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt; ☆ 컨테이너에 이름 붙여서 생성 및 실행하기&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1746377972573&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# docker run -d --name [컨테이너 이름] 이미지명[:태그명]
$ docker run -d --name my-web-server nginx

# Nginx 컨테이너 중단 후 삭제하기
$ docker ps # 실행 중인 컨테이너 조회
$ docker stop {nginx를 실행시킨 Contnainer ID} # 컨테이너 중단
$ docker rm {nginx를 실행시킨 Contnainer ID} # 컨테이너 삭제
$ docker image rm nginx # Nginx 이미지 삭제&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1043&quot; data-origin-height=&quot;558&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bDZam1/btsNLp5aBOu/cxUoKUZopvVkv60Me4Wc7k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bDZam1/btsNLp5aBOu/cxUoKUZopvVkv60Me4Wc7k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bDZam1/btsNLp5aBOu/cxUoKUZopvVkv60Me4Wc7k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbDZam1%2FbtsNLp5aBOu%2FcxUoKUZopvVkv60Me4Wc7k%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;1043&quot; height=&quot;558&quot; data-origin-width=&quot;1043&quot; data-origin-height=&quot;558&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;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;☆&lt;span&gt; &lt;span data-token-index=&quot;0&quot;&gt;호스트의 포트와 컨테이너의 포트를 연결하기&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;span&gt;&lt;span data-token-index=&quot;0&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1746378079449&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# docker run -d -p [호스트 포트]:[컨테이너 포트] 이미지명[:태그명]
$ docker run -d -p 4000:80 nginx&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1039&quot; data-origin-height=&quot;96&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bCTGLf/btsNKzUPFx1/OiUcczOwzR52lr0FSgi7O1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bCTGLf/btsNKzUPFx1/OiUcczOwzR52lr0FSgi7O1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bCTGLf/btsNKzUPFx1/OiUcczOwzR52lr0FSgi7O1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbCTGLf%2FbtsNKzUPFx1%2FOiUcczOwzR52lr0FSgi7O1%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;1039&quot; height=&quot;96&quot; data-origin-width=&quot;1039&quot; data-origin-height=&quot;96&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;span style=&quot;font-family: 'Noto Serif KR'; color: #000000;&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;954&quot; data-origin-height=&quot;333&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bYvund/btsNLsAIdtB/9DkHT1TadEl3L2Rnr8t6Nk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bYvund/btsNLsAIdtB/9DkHT1TadEl3L2Rnr8t6Nk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bYvund/btsNLsAIdtB/9DkHT1TadEl3L2Rnr8t6Nk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbYvund%2FbtsNLsAIdtB%2F9DkHT1TadEl3L2Rnr8t6Nk%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;954&quot; height=&quot;333&quot; data-origin-width=&quot;954&quot; data-origin-height=&quot;333&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1440&quot; data-origin-height=&quot;914&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Bl0fU/btsNKAlUGn9/SWT9k3bjycvaldh1T5ZeD0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Bl0fU/btsNKAlUGn9/SWT9k3bjycvaldh1T5ZeD0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Bl0fU/btsNKAlUGn9/SWT9k3bjycvaldh1T5ZeD0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBl0fU%2FbtsNKAlUGn9%2FSWT9k3bjycvaldh1T5ZeD0%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;1440&quot; height=&quot;914&quot; data-origin-width=&quot;1440&quot; data-origin-height=&quot;914&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;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;span style=&quot;color: #000000;&quot; data-token-index=&quot;0&quot;&gt;docker run -p 4000:80 &lt;/span&gt;라고 명령어를 입력하게 되면, &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;도커를 실행하는 호스트의 4000번 포트를 컨테이너의 80번 포트로 연결하도록 설정한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #ffc1c8;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #000000; text-align: start;&quot;&gt;★ 컨테이너&amp;nbsp; 조회&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffc1c8;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #000000; text-align: start;&quot;&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;☆&lt;span&gt;&lt;span&gt; &lt;span data-token-index=&quot;0&quot;&gt;실행 중인 컨테이너들만 조회&lt;/span&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1746378724730&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ docker ps&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;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;span style=&quot;color: #eb5757;&quot; data-token-index=&quot;0&quot;&gt;ps&lt;/span&gt; : process status의 약자 &lt;/span&gt;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;☆&lt;span&gt;&lt;span&gt;&lt;span&gt; &lt;span data-token-index=&quot;0&quot;&gt;모든 컨테이너 조회 (작동 중인 컨테이너 + 작동을 멈춘 컨테이너)&lt;/span&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1746378824137&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt; docker ps -a&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;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt; &lt;span style=&quot;color: #eb5757;&quot; data-token-index=&quot;0&quot;&gt;-a&lt;/span&gt; : all의 약자&lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&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;1036&quot; data-origin-height=&quot;103&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/blR2Ct/btsNMafhhGC/AhynFBxg4D8DPuUPpwKJx1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/blR2Ct/btsNMafhhGC/AhynFBxg4D8DPuUPpwKJx1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/blR2Ct/btsNMafhhGC/AhynFBxg4D8DPuUPpwKJx1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FblR2Ct%2FbtsNMafhhGC%2FAhynFBxg4D8DPuUPpwKJx1%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;1036&quot; height=&quot;103&quot; data-origin-width=&quot;1036&quot; data-origin-height=&quot;103&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;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #ffc1c8;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #000000; text-align: start;&quot;&gt;★ 컨테이너&amp;nbsp; 중지&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffc1c8;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #000000; text-align: start;&quot;&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1746378962806&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ docker stop 컨테이너명[또는 컨테이너 ID]
$ docker kill 컨테이너명[또는 컨테이너 ID]&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;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;집에 있는 컴퓨터로 비유하자면 &lt;span style=&quot;color: #eb5757;&quot; data-token-index=&quot;1&quot;&gt;stop&lt;/span&gt;은 시스템 종료 버튼을 통해 정상적으로 컴퓨터를 종료하는 걸 의미&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;span style=&quot;color: #eb5757;&quot; data-token-index=&quot;3&quot;&gt;kill&lt;/span&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;901&quot; data-origin-height=&quot;143&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uDqyI/btsNLSlDJeR/xJCUkUidySDznsvBorB831/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uDqyI/btsNLSlDJeR/xJCUkUidySDznsvBorB831/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uDqyI/btsNLSlDJeR/xJCUkUidySDznsvBorB831/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuDqyI%2FbtsNLSlDJeR%2FxJCUkUidySDznsvBorB831%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;901&quot; height=&quot;143&quot; data-origin-width=&quot;901&quot; data-origin-height=&quot;143&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;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #ffc1c8;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #000000; text-align: start;&quot;&gt;★ 컨테이너&amp;nbsp; 삭제&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1746379139442&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 중지되어 있는 특정 컨테이너 삭제
$ docker rm 컨테이너명[또는 컨테이너 ID] 

//실행되고 있는 특정 컨테이너 삭제
 docker rm -f 컨테이너명[또는 컨테이너 ID]
 
 //중지되어 있는 모든 컨테이너 삭제
 $ docker rm $(docker ps -qa)
 
 //실행되고 있는 모든 컨테이너 삭제
 $ docker rm -f $(docker ps -qa)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;936&quot; data-origin-height=&quot;147&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5pZxE/btsNKZsdUc0/dkcZuNO20kJ2pFMKaxhbCk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5pZxE/btsNKZsdUc0/dkcZuNO20kJ2pFMKaxhbCk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5pZxE/btsNKZsdUc0/dkcZuNO20kJ2pFMKaxhbCk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5pZxE%2FbtsNKZsdUc0%2FdkcZuNO20kJ2pFMKaxhbCk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;936&quot; height=&quot;147&quot; data-origin-width=&quot;936&quot; data-origin-height=&quot;147&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;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #ffc1c8;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #000000; text-align: start;&quot;&gt;★ 컨테이너&amp;nbsp; 로그 조회&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt; 컨테이너를 실행시키고나서 실행시킨 컨테이너가 잘 실행되고 있는지, &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;에러가 발생한 건 아닌 지 로그를 확인할 수 있어야 한다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;디버깅할 때 필수로 확인해야 하는 게 로그다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1746379316041&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 특정 컨테이너의 모든 로그 조회
$ docker run -d nginx
$ docker logs [nginx가 실행되고 있는 컨테이너 ID]

# 최근 로그 10줄만 조회
# dokcer logs --tail [로그 끝부터 표시할 줄 수] [컨테이너 ID 또는 컨테이너명]
$ dokcer logs --tail 10 [컨테이너 ID 또는 컨테이너명]

#기존 로그 조회 + 생성되는 로그를 실시간으로 보고 싶은 경우
# Nginx의 컨테이너에 실시간으로 쌓이는 로그 확인하기
$ docker run -d -p 80:80 nginx
$ docker logs -f

#기존 로그는 조회하지 않기 + 생성되는 로그를 실시간으로 보고 싶은 경우
docker logs --tail 0 -f [컨테이너 ID 또는 컨테이너명]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1099&quot; data-origin-height=&quot;550&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kEMPN/btsNKgnJgnV/jnDY3BEb8vHbdU3CnMa69K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kEMPN/btsNKgnJgnV/jnDY3BEb8vHbdU3CnMa69K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kEMPN/btsNKgnJgnV/jnDY3BEb8vHbdU3CnMa69K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkEMPN%2FbtsNKgnJgnV%2FjnDY3BEb8vHbdU3CnMa69K%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;1099&quot; height=&quot;550&quot; data-origin-width=&quot;1099&quot; data-origin-height=&quot;550&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1328&quot; data-origin-height=&quot;1007&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ccDGqJ/btsNMfnjDUr/zK76f8hAZCU2SYWSKYy8KK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ccDGqJ/btsNMfnjDUr/zK76f8hAZCU2SYWSKYy8KK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ccDGqJ/btsNMfnjDUr/zK76f8hAZCU2SYWSKYy8KK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FccDGqJ%2FbtsNMfnjDUr%2FzK76f8hAZCU2SYWSKYy8KK%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;1328&quot; height=&quot;1007&quot; data-origin-width=&quot;1328&quot; data-origin-height=&quot;1007&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;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #ffc1c8;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #000000; text-align: start;&quot;&gt;★ 실행중인 컨테이너 내부에 접속하기 (exec -it)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffc1c8;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #000000; text-align: start;&quot;&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;☆&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt; 실행 중인 컨테이너 내부에 접속하기&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1746379485231&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# docker exec -it 컨테이너명[또는 컨테이너 ID] bash

$ docker run -d nginx
$ docker exec -it [Nginx가 실행되고 있는 컨테이너 ID] bash
$ ls # 컨테이너 내부 파일 조회
$ cd /etc/nginx 
$ cat nginx.conf&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;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt; &amp;rarr; 컨테이너 내부에서 나오려면 Ctrl + D 또는 exit을 입력하면 된다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt; &amp;rarr;&amp;nbsp; bash : 쉘(Shell)의 일&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt; &amp;rarr;&amp;nbsp; -it : -it옵션을 사용해야 명령어를 입력하고 결과를 확인할 수 있다. -it옵션을 적지 않으면 명령어를 1번만 실행시키고 종료되어 버린다. 즉, -it 옵션을 적어야 계속해서 명령어를 입력할 수 있다.&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;1409&quot; data-origin-height=&quot;716&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/elbS1Y/btsNKW98uOm/f1JPRjKjKZBYlskRQRyz0k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/elbS1Y/btsNKW98uOm/f1JPRjKjKZBYlskRQRyz0k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/elbS1Y/btsNKW98uOm/f1JPRjKjKZBYlskRQRyz0k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FelbS1Y%2FbtsNKW98uOm%2Ff1JPRjKjKZBYlskRQRyz0k%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;1409&quot; height=&quot;716&quot; data-origin-width=&quot;1409&quot; data-origin-height=&quot;716&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1440&quot; data-origin-height=&quot;917&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dKirgL/btsNLs8zlyj/OnWWxN2Rnokk3fCDM48JBK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dKirgL/btsNLs8zlyj/OnWWxN2Rnokk3fCDM48JBK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dKirgL/btsNLs8zlyj/OnWWxN2Rnokk3fCDM48JBK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdKirgL%2FbtsNLs8zlyj%2FOnWWxN2Rnokk3fCDM48JBK%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;1440&quot; height=&quot;917&quot; data-origin-width=&quot;1440&quot; data-origin-height=&quot;917&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;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #ffc1c8;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #000000; text-align: start;&quot;&gt;★ Docker 로 Redis 실행시켜보기&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffc1c8;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #000000; text-align: start;&quot;&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;☆&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt; &lt;span data-token-index=&quot;0&quot;&gt;Redis 이미지를 바탕으로 컨테이너 실행시키기&lt;/span&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&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;font-family: 'Noto Serif KR';&quot;&gt;로컬 환경에 redis 이미지가 없으면 Dockerhub으로부터 Redis 이미지를 자동으로 다운받는다. &lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1746379807733&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ docker run -d -p 6379:6379 redis&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1879&quot; data-origin-height=&quot;284&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/WYA9E/btsNLuyyxKW/j0S3jBwpVk031CK1bSnRgK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/WYA9E/btsNLuyyxKW/j0S3jBwpVk031CK1bSnRgK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/WYA9E/btsNLuyyxKW/j0S3jBwpVk031CK1bSnRgK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWYA9E%2FbtsNLuyyxKW%2Fj0S3jBwpVk031CK1bSnRgK%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;1879&quot; height=&quot;284&quot; data-origin-width=&quot;1879&quot; data-origin-height=&quot;284&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;705&quot; data-origin-height=&quot;220&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eikUxD/btsNLpxoaNf/khNf5bHwQQE0krITWR0ZvK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eikUxD/btsNLpxoaNf/khNf5bHwQQE0krITWR0ZvK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eikUxD/btsNLpxoaNf/khNf5bHwQQE0krITWR0ZvK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeikUxD%2FbtsNLpxoaNf%2FkhNf5bHwQQE0krITWR0ZvK%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;705&quot; height=&quot;220&quot; data-origin-width=&quot;705&quot; data-origin-height=&quot;220&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;☆ &lt;span data-token-index=&quot;0&quot;&gt;다운로드 된 이미지 확인하기&lt;/span&gt; &lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1746379848871&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ docker image ls&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;☆&lt;span&gt;&amp;nbsp;컨&lt;span data-token-index=&quot;0&quot;&gt;테이너가 잘 실행되고 있는 지 체크&lt;/span&gt; &lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1746379874228&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ docker ps&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;☆&lt;span&gt; &lt;span data-token-index=&quot;0&quot;&gt;컨테이너 실행시킬 때 에러 없이 잘 실행됐는 지 로그 체크&lt;/span&gt; &lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1746379897481&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ docker logs [컨테이너 ID 또는 컨테이너명]&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;1406&quot; data-origin-height=&quot;255&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bMxXYe/btsNJ24q6CQ/EcOYBgoxAGAgxYdvYFBZY1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bMxXYe/btsNJ24q6CQ/EcOYBgoxAGAgxYdvYFBZY1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bMxXYe/btsNJ24q6CQ/EcOYBgoxAGAgxYdvYFBZY1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbMxXYe%2FbtsNJ24q6CQ%2FEcOYBgoxAGAgxYdvYFBZY1%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;1406&quot; height=&quot;255&quot; data-origin-width=&quot;1406&quot; data-origin-height=&quot;255&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;☆&lt;span&gt;&lt;span&gt; &lt;span data-token-index=&quot;0&quot;&gt;Redis 컨테이너에 접속&lt;/span&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1746379913648&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ docker exec -it [컨테이너 ID 또는 컨테이너명] bash&lt;/code&gt;&lt;/pre&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;☆ &lt;span data-token-index=&quot;0&quot;&gt;컨테이너에서 redis 사용해보기&lt;/span&gt; &lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;span data-token-index=&quot;0&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1746379934494&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ redis-cli

127.0.0.1:6379&amp;gt; set 1 jscode
127.0.0.1:6379&amp;gt; get 1&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;630&quot; data-origin-height=&quot;127&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cxN0pt/btsNKWhY9UD/QpfWaHn9GnUC22PgTcadJ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cxN0pt/btsNKWhY9UD/QpfWaHn9GnUC22PgTcadJ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cxN0pt/btsNKWhY9UD/QpfWaHn9GnUC22PgTcadJ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcxN0pt%2FbtsNKWhY9UD%2FQpfWaHn9GnUC22PgTcadJ1%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;630&quot; height=&quot;127&quot; data-origin-width=&quot;630&quot; data-origin-height=&quot;127&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1440&quot; data-origin-height=&quot;889&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/coyKAH/btsNJPKGJaN/kvmbJgs7oT6rTMfT50kpJ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/coyKAH/btsNJPKGJaN/kvmbJgs7oT6rTMfT50kpJ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/coyKAH/btsNJPKGJaN/kvmbJgs7oT6rTMfT50kpJ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcoyKAH%2FbtsNJPKGJaN%2FkvmbJgs7oT6rTMfT50kpJ1%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;1440&quot; height=&quot;889&quot; data-origin-width=&quot;1440&quot; data-origin-height=&quot;889&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;※ 참고 강의&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1746380172381&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;비전공자도 이해할 수 있는 Docker 입문/실전 강의 | JSCODE 박재성 - 인프런&quot; data-og-description=&quot;JSCODE 박재성 | ,   에라이, 못 해먹겠네!비전공자로 개발을 시작해 여러 회사에서 CTO로 활동하다가, 현재는 교육자로 활동하고 있는 박재성이라고 합니다. 저도 비전공자로 개발을 시작해 서버&quot; data-og-host=&quot;www.inflearn.com&quot; data-og-source-url=&quot;https://www.inflearn.com/course/%EB%B9%84%EC%A0%84%EA%B3%B5%EC%9E%90-docker-%EC%9E%85%EB%AC%B8-%EC%8B%A4%EC%A0%84/dashboard&quot; data-og-url=&quot;https://www.inflearn.com/course/%EB%B9%84%EC%A0%84%EA%B3%B5%EC%9E%90-docker-%EC%9E%85%EB%AC%B8-%EC%8B%A4%EC%A0%84&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/60SW6/hyYPc0JrJW/UIhc5IpNz4973AZr7zBeHk/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/joHTU/hyYMYh81Yc/VcK1lFD6nSEOKmmz2D8B6K/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/hNdH1/hyYPmhXf13/MwDwCLr3ygwJCkYprg4rnK/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781&quot;&gt;&lt;a href=&quot;https://www.inflearn.com/course/%EB%B9%84%EC%A0%84%EA%B3%B5%EC%9E%90-docker-%EC%9E%85%EB%AC%B8-%EC%8B%A4%EC%A0%84/dashboard&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.inflearn.com/course/%EB%B9%84%EC%A0%84%EA%B3%B5%EC%9E%90-docker-%EC%9E%85%EB%AC%B8-%EC%8B%A4%EC%A0%84/dashboard&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/60SW6/hyYPc0JrJW/UIhc5IpNz4973AZr7zBeHk/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/joHTU/hyYMYh81Yc/VcK1lFD6nSEOKmmz2D8B6K/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/hNdH1/hyYPmhXf13/MwDwCLr3ygwJCkYprg4rnK/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;비전공자도 이해할 수 있는 Docker 입문/실전 강의 | JSCODE 박재성 - 인프런&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;JSCODE 박재성 | ,   에라이, 못 해먹겠네!비전공자로 개발을 시작해 여러 회사에서 CTO로 활동하다가, 현재는 교육자로 활동하고 있는 박재성이라고 합니다. 저도 비전공자로 개발을 시작해 서버&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.inflearn.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <author>p퐝유p</author>
      <guid isPermaLink="true">https://nikeisme827.tistory.com/81</guid>
      <comments>https://nikeisme827.tistory.com/81#entry81comment</comments>
      <pubDate>Mon, 5 May 2025 02:36:42 +0900</pubDate>
    </item>
    <item>
      <title>[Docker]3.Docker / 컨테이너(Container)/ 이미지(Image) 개념 복습하기</title>
      <link>https://nikeisme827.tistory.com/80</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; background-color: #ffc1c8;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;★ Docker 란?&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #000000;&quot;&gt;컨테이너를 사용하여 각각의 프로그램을 분리된 환경에서 실행 및 관리할 수 있는 툴&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #ffc1c8; color: #000000;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt; ★ 컨테이너란?&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #000000;&quot;&gt;- 하나의 컴퓨터 환경 내에서 독립적인 컴퓨터 환경을 구성하여 , 각 환경에 프로그램을 별도로 설치할 수 있는 개념이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #000000;&quot;&gt;&amp;nbsp; 윈도우에서도 하나의 컴퓨터에 여러 사용자로 나뉘어서 사용할 수 있다. 각 사용자들에게 각각 다른 환경들을 독립적으로&amp;nbsp; &amp;nbsp; &amp;nbsp; 구성할 수 있고,필요한 프로그램을 따로따로 설치가 가능하다. 즉,하나의 컴퓨터 환경 내에서 여러개의 미니 컴퓨터 환경&amp;nbsp; &amp;nbsp; &amp;nbsp; 을&amp;nbsp; 구성할 수 있는 형태이다. 여기서 얘기하는 &lt;b&gt;미니 컴퓨터&lt;/b&gt;를 보고 &lt;b&gt;Docker에서는 &lt;u&gt;컨테이너(Container)&lt;/u&gt;&lt;/b&gt;라고 부른다.&lt;/span&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;font-family: 'Noto Serif KR'; color: #000000;&quot;&gt;아래의 그림을 보면&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #000000;&quot;&gt; 여기서 &amp;lsquo;컨테이너&amp;rsquo;와 &amp;lsquo;컨테이너를 포함하고 있는 컴퓨터&amp;rsquo;를 구분하기 위해 &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #000000;&quot;&gt;컨테이너를 포함하고 있는 컴퓨터를&lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;u&gt;&lt;b&gt; &amp;lsquo;호스트(host) 컴퓨터&amp;rsquo;&lt;/b&gt;&lt;/u&gt;&lt;/span&gt;라고 부른다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock floatLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1440&quot; data-origin-height=&quot;919&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ctFYqC/btsNKxQhF5A/vzQBVtKGjCmq4Hpf0HcizK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ctFYqC/btsNKxQhF5A/vzQBVtKGjCmq4Hpf0HcizK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ctFYqC/btsNKxQhF5A/vzQBVtKGjCmq4Hpf0HcizK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FctFYqC%2FbtsNKxQhF5A%2FvzQBVtKGjCmq4Hpf0HcizK%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;1440&quot; height=&quot;919&quot; data-origin-width=&quot;1440&quot; data-origin-height=&quot;919&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;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;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;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;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;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;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;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;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;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;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;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- 컨테이너의 독립성&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp;&amp;nbsp;▶ 디스크 (저장공간) :&amp;nbsp; 각 컨테이너마다 서로 각자의 저장 공간을 가지고 있다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&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; &amp;nbsp; &amp;nbsp; &amp;nbsp; A컨테이너 내부에서 B컨테이너 내부에 있는 파일은 접근 불가하다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start; font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; ▶&amp;nbsp;&lt;span style=&quot;color: #000000;&quot; data-token-index=&quot;0&quot;&gt;네트워크 (IP, Port)&lt;/span&gt;&amp;nbsp;: 각 컨테이너마다 고유의 네트워크를 가지고 있다. 컨테이너는 각자의 IP 주소를 가지고 있다.&lt;/span&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;h3 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #ffc1c8;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #333333; text-align: start;&quot;&gt; ★ 이미지(Image) 란? &lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;- &lt;span style=&quot;background-color: #9feec3;&quot;&gt;이미지는 프로그램을 실행하는 데 필요한 설치 과정, 설정, 버전 정보 등을 포함&lt;/span&gt;&lt;/b&gt;하고 있다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; 즉, &lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;프로그램을 실행하는 데 필요한 모든 것을 포함&lt;/b&gt;&lt;/span&gt;하고 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; 예를 들어,&amp;nbsp; MySQL 서버를 이미지로 만들었다면, 이 이미지를 Docker로 실행시키는 순간 MySQL 서버가 컨테이너&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; (Container) 환경에서 실행된다. MySQL을 일일이 설치할 필요없이 MySQL 데이터베이스를 사용할 수 있게 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; 참고하고 있는 강의에서는 &lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;닌텐도 게임칩&lt;/b&gt;&lt;/span&gt;을 예를 들어 설명해주셨다. 이보다 적절한 비유는 없는 것 같다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; 닌텐도의 여러가지 칩을 꽂아 다양한 게임을 즐길 수 있듯이 이미지는 프로그램을 실행하는데 필요한 모든 것을 포함하고&amp;nbsp; &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; 있다고 보면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #333333; text-align: start;&quot;&gt;&amp;nbsp;&lt;/span&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.inflearn.com/course/%EB%B9%84%EC%A0%84%EA%B3%B5%EC%9E%90-docker-%EC%9E%85%EB%AC%B8-%EC%8B%A4%EC%A0%84/dashboard&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.inflearn.com/course/%EB%B9%84%EC%A0%84%EA%B3%B5%EC%9E%90-docker-%EC%9E%85%EB%AC%B8-%EC%8B%A4%EC%A0%84/dashboard&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1746375625588&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;비전공자도 이해할 수 있는 Docker 입문/실전 강의 | JSCODE 박재성 - 인프런&quot; data-og-description=&quot;JSCODE 박재성 | ,   에라이, 못 해먹겠네!비전공자로 개발을 시작해 여러 회사에서 CTO로 활동하다가, 현재는 교육자로 활동하고 있는 박재성이라고 합니다. 저도 비전공자로 개발을 시작해 서버&quot; data-og-host=&quot;www.inflearn.com&quot; data-og-source-url=&quot;https://www.inflearn.com/course/%EB%B9%84%EC%A0%84%EA%B3%B5%EC%9E%90-docker-%EC%9E%85%EB%AC%B8-%EC%8B%A4%EC%A0%84/dashboard&quot; data-og-url=&quot;https://www.inflearn.com/course/%EB%B9%84%EC%A0%84%EA%B3%B5%EC%9E%90-docker-%EC%9E%85%EB%AC%B8-%EC%8B%A4%EC%A0%84&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/60SW6/hyYPc0JrJW/UIhc5IpNz4973AZr7zBeHk/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/joHTU/hyYMYh81Yc/VcK1lFD6nSEOKmmz2D8B6K/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/hNdH1/hyYPmhXf13/MwDwCLr3ygwJCkYprg4rnK/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781&quot;&gt;&lt;a href=&quot;https://www.inflearn.com/course/%EB%B9%84%EC%A0%84%EA%B3%B5%EC%9E%90-docker-%EC%9E%85%EB%AC%B8-%EC%8B%A4%EC%A0%84/dashboard&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.inflearn.com/course/%EB%B9%84%EC%A0%84%EA%B3%B5%EC%9E%90-docker-%EC%9E%85%EB%AC%B8-%EC%8B%A4%EC%A0%84/dashboard&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/60SW6/hyYPc0JrJW/UIhc5IpNz4973AZr7zBeHk/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/joHTU/hyYMYh81Yc/VcK1lFD6nSEOKmmz2D8B6K/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/hNdH1/hyYPmhXf13/MwDwCLr3ygwJCkYprg4rnK/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;비전공자도 이해할 수 있는 Docker 입문/실전 강의 | JSCODE 박재성 - 인프런&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;JSCODE 박재성 | ,   에라이, 못 해먹겠네!비전공자로 개발을 시작해 여러 회사에서 CTO로 활동하다가, 현재는 교육자로 활동하고 있는 박재성이라고 합니다. 저도 비전공자로 개발을 시작해 서버&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.inflearn.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <author>p퐝유p</author>
      <guid isPermaLink="true">https://nikeisme827.tistory.com/80</guid>
      <comments>https://nikeisme827.tistory.com/80#entry80comment</comments>
      <pubDate>Mon, 5 May 2025 01:20:50 +0900</pubDate>
    </item>
    <item>
      <title>[Docker] 2. 윈도우에 도커 데스크 탑 설치해보기</title>
      <link>https://nikeisme827.tistory.com/79</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;Docker Desktop on Windows&lt;/b&gt;는 &lt;b&gt;Windows 운영체제에서 Docker를 쉽게 사용할 수 있도록 만든 공식 GUI 및 도구 모음이다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Linux에서 동작하는 Docker 엔진을 Windows에서도 &lt;b&gt;간편하게 쓸 수 있도록 가상화 기술을 활용&lt;/b&gt;해서 실행해주는 역할을 한다.&lt;/span&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;font-family: 'Noto Serif KR';&quot;&gt;내가 &lt;b&gt;Docker Desktop on Windows 을 사용하는 이유는 우선 나의 pc 가 window 환경이기도 하고,&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;아래의 이유와 같다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;949&quot; data-start=&quot;643&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;750&quot; data-start=&quot;643&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;리눅스 기반 Docker 환경을 쉽게 실행&lt;/b&gt;&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;750&quot; data-start=&quot;677&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;750&quot; data-start=&quot;677&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Docker는 원래 Linux 전용이라, Windows에서는 가상화(WSL2 or Hyper-V)를 통해 리눅스를 구동해야 함.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;814&quot; data-start=&quot;751&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;복잡한 설정 없이 GUI로 컨테이너 관리&lt;/b&gt;&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;814&quot; data-start=&quot;784&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;814&quot; data-start=&quot;784&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;GUI에서 클릭으로 컨테이너 실행/중지/삭제 가능.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;888&quot; data-start=&quot;815&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;WSL2 통합 지원&lt;/b&gt;&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;888&quot; data-start=&quot;836&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;888&quot; data-start=&quot;836&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;WSL2를 통해 Windows와 Linux 간 파일 공유, 경로 접근이 매끄럽게 이루어짐.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;949&quot; data-start=&quot;889&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;개발환경 통합&lt;/b&gt;&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;949&quot; data-start=&quot;907&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;949&quot; data-start=&quot;907&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Visual Studio Code, Git, 터미널 등과 연동이 잘 됨.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;01. 설치 파일 다운로드&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;a href=&quot;https://docs.docker.com/desktop/install/windows-install/&quot;&gt;https://docs.docker.com/desktop/install/windows-install/&lt;/a&gt;&lt;span style=&quot;color: #555555; text-align: start;&quot;&gt;&amp;nbsp;페이지에서 설치 파일을 다운로드&lt;/span&gt;&lt;span style=&quot;color: #555555; text-align: start;&quot;&gt;&lt;/span&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;1920&quot; data-origin-height=&quot;849&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bKnlvC/btsNLmtV7E0/E0yp9o08lXPTTaYYMJpFM0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bKnlvC/btsNLmtV7E0/E0yp9o08lXPTTaYYMJpFM0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bKnlvC/btsNLmtV7E0/E0yp9o08lXPTTaYYMJpFM0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbKnlvC%2FbtsNLmtV7E0%2FE0yp9o08lXPTTaYYMJpFM0%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;1920&quot; height=&quot;849&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;849&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;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; background-color: #9feec3;&quot;&gt;02. 설치 완료 후, 로그인 화면이 뜨는데 로그인은 하지 않아도 된다.&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1277&quot; data-origin-height=&quot;724&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zmw6F/btsNK9VFRTv/nh9o9fggPdcfaWNdISQU81/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zmw6F/btsNK9VFRTv/nh9o9fggPdcfaWNdISQU81/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zmw6F/btsNK9VFRTv/nh9o9fggPdcfaWNdISQU81/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fzmw6F%2FbtsNK9VFRTv%2Fnh9o9fggPdcfaWNdISQU81%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;1277&quot; height=&quot;724&quot; data-origin-width=&quot;1277&quot; data-origin-height=&quot;724&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;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;3. wsl 커널 업데이트&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #000000;&quot;&gt;- 윈도우용 도커 데스크탑은 WSL2 또는 Hyper-V 기반으로 설치할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #000000;&quot;&gt;&amp;nbsp; 설치 파일 다운로드 하는 화면 하단에&amp;nbsp; WSL2 기반으로 설치를 진행하므로 최소 시스템 요구 사항을 확인해야한다.&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;1070&quot; data-origin-height=&quot;700&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nfhsR/btsNLZSwlhN/KY5uIdkR6iUTdLRQiPpAM0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nfhsR/btsNLZSwlhN/KY5uIdkR6iUTdLRQiPpAM0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nfhsR/btsNLZSwlhN/KY5uIdkR6iUTdLRQiPpAM0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnfhsR%2FbtsNLZSwlhN%2FKY5uIdkR6iUTdLRQiPpAM0%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;1070&quot; height=&quot;700&quot; data-origin-width=&quot;1070&quot; data-origin-height=&quot;700&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; background-color: #9feec3;&quot;&gt;04 . WSL 커널 업데이트&amp;nbsp;&lt;/span&gt;&lt;/b&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;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;WSL 커널 업데이트 안내 창을 확인하고&amp;nbsp;&lt;a href=&quot;https://learn.microsoft.com/ko-kr/windows/wsl/wsl2-kernel&quot;&gt;https://learn.microsoft.com/ko-kr/windows/wsl/wsl2-kernel&lt;/a&gt;&amp;nbsp;사이트로 이동하여 &lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&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;909&quot; data-origin-height=&quot;507&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Mmm3C/btsNKyVV7lL/hsuIh6ZipEEmI3ydrQOhLK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Mmm3C/btsNKyVV7lL/hsuIh6ZipEEmI3ydrQOhLK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Mmm3C/btsNKyVV7lL/hsuIh6ZipEEmI3ydrQOhLK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMmm3C%2FbtsNKyVV7lL%2FhsuIh6ZipEEmI3ydrQOhLK%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;507&quot; data-origin-width=&quot;909&quot; data-origin-height=&quot;507&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;span style=&quot;background-color: #9feec3; color: #000000;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;05. PowerShell를 실행하고 WSL2를 기본 버전으로 설정&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1746373377841&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;wsl --set-default-version2&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;705&quot; data-origin-height=&quot;119&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cqWdIq/btsNLc5V1kg/OCKtijNQPj6xfwWlFTVBkk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cqWdIq/btsNLc5V1kg/OCKtijNQPj6xfwWlFTVBkk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cqWdIq/btsNLc5V1kg/OCKtijNQPj6xfwWlFTVBkk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcqWdIq%2FbtsNLc5V1kg%2FOCKtijNQPj6xfwWlFTVBkk%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;705&quot; height=&quot;119&quot; data-origin-width=&quot;705&quot; data-origin-height=&quot;119&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;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #000000;&quot;&gt;06. Docker Desktop 재실행&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start; font-family: 'Noto Serif KR';&quot;&gt; 바탕화면 또는 시작 메뉴에 Docker Desktop 아이콘을 클릭하여 아래의 화면에 접속한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start; font-family: 'Noto Serif KR';&quot;&gt;화면 왼쪽 하단에 아이콘이 초록색으로 바뀌고 마우스를 올리면 &lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;&quot;Engine running&quot;&lt;/b&gt; &lt;/span&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;1269&quot; data-origin-height=&quot;717&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/m87ei/btsNKqX21Um/vl6Wxri2PqUx7hds68d0q1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/m87ei/btsNKqX21Um/vl6Wxri2PqUx7hds68d0q1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/m87ei/btsNKqX21Um/vl6Wxri2PqUx7hds68d0q1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fm87ei%2FbtsNKqX21Um%2Fvl6Wxri2PqUx7hds68d0q1%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;1269&quot; height=&quot;717&quot; data-origin-width=&quot;1269&quot; data-origin-height=&quot;717&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;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; background-color: #9feec3;&quot;&gt;07. 명령 프롬프트에서 도커 CLI 실행 여부 확인&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;명령 프롬프트를 실행하고, 도커 CLI 실행에 문제 없는지 도커 버전을 확인하는 명령어를 입력한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1746373604168&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;docker version&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;649&quot; data-origin-height=&quot;439&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xTGGO/btsNK1XOUzs/0SHh2wcpc1EsGl0dGERWmK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xTGGO/btsNK1XOUzs/0SHh2wcpc1EsGl0dGERWmK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xTGGO/btsNK1XOUzs/0SHh2wcpc1EsGl0dGERWmK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxTGGO%2FbtsNK1XOUzs%2F0SHh2wcpc1EsGl0dGERWmK%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;649&quot; height=&quot;439&quot; data-origin-width=&quot;649&quot; data-origin-height=&quot;439&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;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;08. 도커 명령어 확인&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #555555; text-align: start; font-family: 'Noto Serif KR';&quot;&gt; docker --help&amp;nbsp; 명령어로 도커 명령어 사용법과 구성을 확인해본다.&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;899&quot; data-origin-height=&quot;879&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mxvbQ/btsNJVRAGVk/gtqZbyBFBmoAEgxEGNNciK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mxvbQ/btsNJVRAGVk/gtqZbyBFBmoAEgxEGNNciK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mxvbQ/btsNJVRAGVk/gtqZbyBFBmoAEgxEGNNciK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmxvbQ%2FbtsNJVRAGVk%2FgtqZbyBFBmoAEgxEGNNciK%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;899&quot; height=&quot;879&quot; data-origin-width=&quot;899&quot; data-origin-height=&quot;879&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;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;09. 최신버전의 우분투 컨테이너에서 HelloWorld 메세지 출력해보기&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #555555; text-align: start; font-family: 'Noto Serif KR';&quot;&gt; 최신 버전의 우분투 컨테이너를 실행하고, 해당 컨테이너 쉘에서 Hello World 메시지를 출력한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #555555; text-align: start; font-family: 'Noto Serif KR';&quot;&gt;아래에 Heollo World 라고 오타를 냈는데 오타를 똑같이 맨하단에 출력한 것을 보니 잘 실행되는 것 같다. ㅎㅎㅎ...&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;833&quot; data-origin-height=&quot;115&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/owy7j/btsNK3ahSR5/YGfSb9DC6lYXSBKzj5t6d1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/owy7j/btsNK3ahSR5/YGfSb9DC6lYXSBKzj5t6d1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/owy7j/btsNK3ahSR5/YGfSb9DC6lYXSBKzj5t6d1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fowy7j%2FbtsNK3ahSR5%2FYGfSb9DC6lYXSBKzj5t6d1%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;833&quot; height=&quot;115&quot; data-origin-width=&quot;833&quot; data-origin-height=&quot;115&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;/p&gt;
&lt;figure id=&quot;og_1746374102410&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;윈도우에 도커 데스크탑 설치&quot; data-og-description=&quot;Install Docker Desktop on Windows Docker Desktop은 컨테이너화된 애플리케이션 및 마이크로서비스를 구축하고 공유할 수 있는 Mac, Linux, Windows 환경용 원클릭 설치 애플리케이션으로, 설치된 머신에서 컨테&quot; data-og-host=&quot;myanjini.tistory.com&quot; data-og-source-url=&quot;https://myanjini.tistory.com/entry/%EC%9C%88%EB%8F%84%EC%9A%B0%EC%97%90-%EB%8F%84%EC%BB%A4-%EB%8D%B0%EC%8A%A4%ED%81%AC%ED%83%91-%EC%84%A4%EC%B9%98&quot; data-og-url=&quot;https://myanjini.tistory.com/entry/%EC%9C%88%EB%8F%84%EC%9A%B0%EC%97%90-%EB%8F%84%EC%BB%A4-%EB%8D%B0%EC%8A%A4%ED%81%AC%ED%83%91-%EC%84%A4%EC%B9%98&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/gMqFi/hyYMWdzyRK/VRYng0ZCgSTD4tmtseOUwK/img.png?width=800&amp;amp;height=453&amp;amp;face=0_0_800_453,https://scrap.kakaocdn.net/dn/bRVXNx/hyYMYP1bQO/ZQehdyJt236yF56xIzouuk/img.png?width=800&amp;amp;height=453&amp;amp;face=0_0_800_453,https://scrap.kakaocdn.net/dn/ZGOG1/hyYMXcsaUZ/zZ54b0bibymK95PuQlk510/img.png?width=694&amp;amp;height=602&amp;amp;face=0_0_694_602&quot;&gt;&lt;a href=&quot;https://myanjini.tistory.com/entry/%EC%9C%88%EB%8F%84%EC%9A%B0%EC%97%90-%EB%8F%84%EC%BB%A4-%EB%8D%B0%EC%8A%A4%ED%81%AC%ED%83%91-%EC%84%A4%EC%B9%98&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://myanjini.tistory.com/entry/%EC%9C%88%EB%8F%84%EC%9A%B0%EC%97%90-%EB%8F%84%EC%BB%A4-%EB%8D%B0%EC%8A%A4%ED%81%AC%ED%83%91-%EC%84%A4%EC%B9%98&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/gMqFi/hyYMWdzyRK/VRYng0ZCgSTD4tmtseOUwK/img.png?width=800&amp;amp;height=453&amp;amp;face=0_0_800_453,https://scrap.kakaocdn.net/dn/bRVXNx/hyYMYP1bQO/ZQehdyJt236yF56xIzouuk/img.png?width=800&amp;amp;height=453&amp;amp;face=0_0_800_453,https://scrap.kakaocdn.net/dn/ZGOG1/hyYMXcsaUZ/zZ54b0bibymK95PuQlk510/img.png?width=694&amp;amp;height=602&amp;amp;face=0_0_694_602');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;윈도우에 도커 데스크탑 설치&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Install Docker Desktop on Windows Docker Desktop은 컨테이너화된 애플리케이션 및 마이크로서비스를 구축하고 공유할 수 있는 Mac, Linux, Windows 환경용 원클릭 설치 애플리케이션으로, 설치된 머신에서 컨테&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;myanjini.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1746374107920&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;비전공자도 이해할 수 있는 Docker 입문/실전 강의 | JSCODE 박재성 - 인프런&quot; data-og-description=&quot;JSCODE 박재성 | ,   에라이, 못 해먹겠네!비전공자로 개발을 시작해 여러 회사에서 CTO로 활동하다가, 현재는 교육자로 활동하고 있는 박재성이라고 합니다. 저도 비전공자로 개발을 시작해 서버&quot; data-og-host=&quot;www.inflearn.com&quot; data-og-source-url=&quot;https://www.inflearn.com/course/%EB%B9%84%EC%A0%84%EA%B3%B5%EC%9E%90-docker-%EC%9E%85%EB%AC%B8-%EC%8B%A4%EC%A0%84/dashboard&quot; data-og-url=&quot;https://www.inflearn.com/course/%EB%B9%84%EC%A0%84%EA%B3%B5%EC%9E%90-docker-%EC%9E%85%EB%AC%B8-%EC%8B%A4%EC%A0%84&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/60SW6/hyYPc0JrJW/UIhc5IpNz4973AZr7zBeHk/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/joHTU/hyYMYh81Yc/VcK1lFD6nSEOKmmz2D8B6K/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/hNdH1/hyYPmhXf13/MwDwCLr3ygwJCkYprg4rnK/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781&quot;&gt;&lt;a href=&quot;https://www.inflearn.com/course/%EB%B9%84%EC%A0%84%EA%B3%B5%EC%9E%90-docker-%EC%9E%85%EB%AC%B8-%EC%8B%A4%EC%A0%84/dashboard&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.inflearn.com/course/%EB%B9%84%EC%A0%84%EA%B3%B5%EC%9E%90-docker-%EC%9E%85%EB%AC%B8-%EC%8B%A4%EC%A0%84/dashboard&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/60SW6/hyYPc0JrJW/UIhc5IpNz4973AZr7zBeHk/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/joHTU/hyYMYh81Yc/VcK1lFD6nSEOKmmz2D8B6K/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/hNdH1/hyYPmhXf13/MwDwCLr3ygwJCkYprg4rnK/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;비전공자도 이해할 수 있는 Docker 입문/실전 강의 | JSCODE 박재성 - 인프런&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;JSCODE 박재성 | ,   에라이, 못 해먹겠네!비전공자로 개발을 시작해 여러 회사에서 CTO로 활동하다가, 현재는 교육자로 활동하고 있는 박재성이라고 합니다. 저도 비전공자로 개발을 시작해 서버&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.inflearn.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;</description>
      <author>p퐝유p</author>
      <guid isPermaLink="true">https://nikeisme827.tistory.com/79</guid>
      <comments>https://nikeisme827.tistory.com/79#entry79comment</comments>
      <pubDate>Mon, 5 May 2025 00:55:29 +0900</pubDate>
    </item>
    <item>
      <title>[Docker]1. 도커는 왜 알아야 할까?</title>
      <link>https://nikeisme827.tistory.com/78</link>
      <description>&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;517&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/drt5uD/btsNKqX2UEA/WLjbElKTk2UnKqJzDsKIHK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/drt5uD/btsNKqX2UEA/WLjbElKTk2UnKqJzDsKIHK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/drt5uD/btsNKqX2UEA/WLjbElKTk2UnKqJzDsKIHK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdrt5uD%2FbtsNKqX2UEA%2FWLjbElKTk2UnKqJzDsKIHK%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;517&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;517&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #000000; background-color: #ffc1c8;&quot;&gt;★ 도커를 많이 쓰는 이유 ?&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- 도커의 핵심 특징은&amp;nbsp; &lt;u&gt;&lt;b&gt;이식성&lt;/b&gt;&lt;/u&gt;이다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; 회사에서도 도커를 사용하고 있다. 도커를 사용하여 redis,kafka,nginx 등을 컨테이너로 띄워 관리하고 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; 회사 제품 패키지를 어느 환경에서든 쉽게 설치할 수 있다는 것에 경이로움이 있었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; 라이브러리 버전 관리도 쉽고, 일일이 설치해야한다는 번거로움을 덜고 있어 더 도커에 대해 구체적으로 파보고 싶었다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; 도커를 도시락 통에 비유하자면&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; 마치 도시락통에 밥, 반찬, 숟가락까지 먹는 데 필요한 모든 것을 한 번에 담아놓는 것처럼&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; 어디서든 열기만 하면 바로 먹을 수 있는 도시락처럼&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; 도커는 어디서든 실행 가능한 앱 패키지를 만드는 기술이라고 생각하면 된다.&amp;nbsp;&lt;/span&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;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; 도시락 통에는 밥,반찬 다 있는 것 처럼 도커는 앱이 실행되기 위한 모든 환경을 포함하고 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; 도시락통은 어디서든 다 먹을 수 있는 것 처럼 도커는 어떤 컴퓨터든 컨테이너를 실행하면 항상 똑같이 동작한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; 다른 도시락이랑 섞일 수 없는 것처럼 도커에서 컨테이너끼리는 독립적이며 서로 간섭하지 않은다는 것이 특징이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #ffc1c8;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #000000;&quot;&gt;★&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;도커와 가상머신의 차이점&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;가상화 방식&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;OS 수준 가상화 (컨테이너)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;하드웨어 수준 가상화&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;호스트 OS 공유&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;예 (컨테이너는 호스트 OS 커널 공유)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;아니요 (각 VM은 자체 OS 실행)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;부팅 속도&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;매우 빠름 (초 단위)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;느림 (분 단위, OS 부팅 필요)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;자원 사용량&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;가볍고 효율적&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;상대적으로 무거움&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;격리 수준&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;낮음 (커널 공유로 보안 이슈 가능)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;높음 (완전한 격리)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;이미지 크기&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;작음 (수십~수백 MB)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;큼 (수 GB 이상)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;운영 체제 의존성&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;호스트 OS와 컨테이너 OS가 같은 커널 필요&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;다양한 OS 설치 가능 (리눅스, 윈도우 등)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;사용 사례&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;마이크로서비스, CI/CD, 클라우드 앱 배포 등&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;복잡한 앱, 다양한 OS 테스트, 레거시 앱 등&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;- 도커&lt;/b&gt;는 빠르고 가벼운 환경에서 애플리케이션을 배포하고 실행하는 데 적합하며, &lt;b&gt;개발 및 배포 자동화&lt;/b&gt;에 강점을 가진다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;- 가상머신&lt;/b&gt;은 완전히 독립된 시스템 환경이 필요할 때 유리하며, &lt;b&gt;보안과 OS 다양성&lt;/b&gt;이 중요한 경우 사용된다.&lt;/span&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;/p&gt;
&lt;figure id=&quot;og_1746375734800&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;비전공자도 이해할 수 있는 Docker 입문/실전 강의 | JSCODE 박재성 - 인프런&quot; data-og-description=&quot;JSCODE 박재성 | ,   에라이, 못 해먹겠네!비전공자로 개발을 시작해 여러 회사에서 CTO로 활동하다가, 현재는 교육자로 활동하고 있는 박재성이라고 합니다. 저도 비전공자로 개발을 시작해 서버&quot; data-og-host=&quot;www.inflearn.com&quot; data-og-source-url=&quot;https://www.inflearn.com/course/%EB%B9%84%EC%A0%84%EA%B3%B5%EC%9E%90-docker-%EC%9E%85%EB%AC%B8-%EC%8B%A4%EC%A0%84/dashboard&quot; data-og-url=&quot;https://www.inflearn.com/course/%EB%B9%84%EC%A0%84%EA%B3%B5%EC%9E%90-docker-%EC%9E%85%EB%AC%B8-%EC%8B%A4%EC%A0%84&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/60SW6/hyYPc0JrJW/UIhc5IpNz4973AZr7zBeHk/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/joHTU/hyYMYh81Yc/VcK1lFD6nSEOKmmz2D8B6K/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/hNdH1/hyYPmhXf13/MwDwCLr3ygwJCkYprg4rnK/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781&quot;&gt;&lt;a href=&quot;https://www.inflearn.com/course/%EB%B9%84%EC%A0%84%EA%B3%B5%EC%9E%90-docker-%EC%9E%85%EB%AC%B8-%EC%8B%A4%EC%A0%84/dashboard&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.inflearn.com/course/%EB%B9%84%EC%A0%84%EA%B3%B5%EC%9E%90-docker-%EC%9E%85%EB%AC%B8-%EC%8B%A4%EC%A0%84/dashboard&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/60SW6/hyYPc0JrJW/UIhc5IpNz4973AZr7zBeHk/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/joHTU/hyYMYh81Yc/VcK1lFD6nSEOKmmz2D8B6K/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781,https://scrap.kakaocdn.net/dn/hNdH1/hyYPmhXf13/MwDwCLr3ygwJCkYprg4rnK/img.png?width=1200&amp;amp;height=781&amp;amp;face=0_0_1200_781');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;비전공자도 이해할 수 있는 Docker 입문/실전 강의 | JSCODE 박재성 - 인프런&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;JSCODE 박재성 | ,   에라이, 못 해먹겠네!비전공자로 개발을 시작해 여러 회사에서 CTO로 활동하다가, 현재는 교육자로 활동하고 있는 박재성이라고 합니다. 저도 비전공자로 개발을 시작해 서버&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.inflearn.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <author>p퐝유p</author>
      <guid isPermaLink="true">https://nikeisme827.tistory.com/78</guid>
      <comments>https://nikeisme827.tistory.com/78#entry78comment</comments>
      <pubDate>Mon, 5 May 2025 00:28:43 +0900</pubDate>
    </item>
    <item>
      <title>[코딩테스트] 역전 홈런으로 경기 이겨서 도파민 돌아서 푸는 코테 문제 - 프로그래머스 / 숫자 문자열과 영단어 / 크레인 인형 뽑기 게임 ﻿</title>
      <link>https://nikeisme827.tistory.com/74</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;해냈다 해냈어 두산이 해냈어&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스벅에서 과제랑 이것저것 하면서 무려 4시간 반동안 경기 봤는데 다이슨에 기가 다 빨린 것 같은 너낌이다....&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 이겨서 너어어어무 조으다 다 괜찮아진다 ㅎㅎㅎ헤헤헤헤헿&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;악바리로 경기하는 선수들 모습에 자극받아 다시 놑북을 핀건 아니지만,,,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래도 수수수수퍼 도파민이 돌아서 코테 문제 2개나 풀었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;역시나, 이번 코테 문제를 풀면서 부족함을 메웠다. 다시 한번 리마인딩하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[문제1]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1743948753743&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;프로그래머스&quot; data-og-description=&quot;SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프&quot; data-og-host=&quot;programmers.co.kr&quot; data-og-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/81301&quot; data-og-url=&quot;https://programmers.co.kr/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bsP06p/hyYBavUzVD/08dzYAN0Mtov6uRP15KGKk/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960,https://scrap.kakaocdn.net/dn/ZFzie/hyYCedm3iM/QMjJH0Nw16zJUcb2d1knS0/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/81301&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/81301&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bsP06p/hyYBavUzVD/08dzYAN0Mtov6uRP15KGKk/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960,https://scrap.kakaocdn.net/dn/ZFzie/hyYCedm3iM/QMjJH0Nw16zJUcb2d1knS0/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;프로그래머스&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;programmers.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;풀이&lt;/p&gt;
&lt;pre id=&quot;code_1743948905276&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.util.*;

class Solution {
    public int solution(String s) {
        int answer = 0;

        // 영단어 숫자를 숫자 문자열로 매핑하기 위한 해시맵 생성
        Map&amp;lt;String, String&amp;gt; map = new HashMap&amp;lt;&amp;gt;();
        map.put(&quot;zero&quot;, &quot;0&quot;);
        map.put(&quot;one&quot;, &quot;1&quot;);
        map.put(&quot;two&quot;, &quot;2&quot;);
        map.put(&quot;three&quot;, &quot;3&quot;);
        map.put(&quot;four&quot;, &quot;4&quot;);
        map.put(&quot;five&quot;, &quot;5&quot;);
        map.put(&quot;six&quot;, &quot;6&quot;);
        map.put(&quot;seven&quot;, &quot;7&quot;);
        map.put(&quot;eight&quot;, &quot;8&quot;);
        map.put(&quot;nine&quot;, &quot;9&quot;);

        // 입력 문자열 s에 대해 영단어 숫자를 대응하는 숫자 문자열로 변환
        for (String key : map.keySet()) {
            // 예: &quot;one4seveneight&quot; &amp;rarr; &quot;14seveneight&quot; &amp;rarr; &quot;1478&quot;
            s = s.replaceAll(key, map.get(key));
        }

        // 최종적으로 변환된 숫자 문자열을 정수형으로 변환
        answer = Integer.parseInt(s);

        // 결과 반환
        return answer;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[인텔리전스 하신 분들의 풀이]&lt;/p&gt;
&lt;pre id=&quot;code_1743948976402&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Solution {
    public int solution(String s) {
        String[] strArr = {&quot;zero&quot;, &quot;one&quot;, &quot;two&quot;, &quot;three&quot;, &quot;four&quot;, &quot;five&quot;, &quot;six&quot;, &quot;seven&quot;, &quot;eight&quot;, &quot;nine&quot;};
        for(int i = 0; i &amp;lt; strArr.length; i++) {
            s = s.replaceAll(strArr[i], Integer.toString(i));
        }
        return Integer.parseInt(s);
    }
}&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;굳이 HashMap 으로 안해도 된다. 내가 너무 복잡하게 생각했나보다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래도 HashMap의 개념 정립을 하게된 계기가 되었다.&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;b&gt;[문제 2]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;크레인 인형 뽑기 게임 &lt;/b&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal; color: #263747; text-align: left;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li style=&quot;list-style-type: none; color: #ffffff;&quot;&gt;크레인 ff형뽑기 게zz크레인 인형뽑기&lt;/li&gt;
&lt;/ol&gt;
&lt;div style=&quot;color: #263747; text-align: left;&quot;&gt;
&lt;ul style=&quot;list-style-type: disc; color: #000000;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: none; color: #000000;&quot;&gt;
&lt;div style=&quot;color: #263747; text-align: left;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;figure id=&quot;og_1743949085381&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;프로그래머스&quot; data-og-description=&quot;SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프&quot; data-og-host=&quot;programmers.co.kr&quot; data-og-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/64061&quot; data-og-url=&quot;https://programmers.co.kr/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/b7rDRu/hyYBfRA1ua/apa5a539KENuAJUW41UQB1/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960,https://scrap.kakaocdn.net/dn/befLVU/hyYCiNDQ4I/2cRsMsgikUpSylvMAmA6N0/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/64061&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/64061&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/b7rDRu/hyYBfRA1ua/apa5a539KENuAJUW41UQB1/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960,https://scrap.kakaocdn.net/dn/befLVU/hyYCiNDQ4I/2cRsMsgikUpSylvMAmA6N0/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;프로그래머스&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;programmers.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1743949195900&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.util.*;

class Solution {
    public int solution(int[][] board, int[] moves) {
        int answer = 0; // 터뜨려서 사라진 인형 개수 누적

        Stack&amp;lt;Integer&amp;gt; stack = new Stack&amp;lt;&amp;gt;(); // 뽑은 인형을 담을 바구니(스택)

        // moves 배열을 순회하며 하나씩 처리
        for (int move : moves) {
            int col = move - 1; // 배열 인덱스는 0부터 시작하므로 1을 빼줌 (열 번호)

            // 해당 열(column)을 위에서부터 아래로 훑음
            for (int row = 0; row &amp;lt; board.length; row++) {
                // 인형이 있는 경우 (0이 아니면 인형이 존재)
                if (board[row][col] != 0) {
                    int doll = board[row][col]; // 뽑은 인형
                    board[row][col] = 0; // 뽑았으므로 빈 칸(0)으로 설정

                    // 바구니(stack)에 동일한 인형이 연속으로 있으면 제거
                    if (!stack.isEmpty() &amp;amp;&amp;amp; stack.peek() == doll) {
                        stack.pop(); // 인형 터뜨리기
                        answer += 2; // 두 개가 사라지므로 +2
                    } else {
                        stack.push(doll); // 바구니에 인형 넣기
                    }

                    break; // 해당 열에서 인형을 하나 뽑았으면 더 이상 아래는 탐색하지 않음
                }
            }
        }

        return answer; // 터진 인형의 총 개수 반환
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[인텔리하신 분들의 풀이]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;뭔가 내가 푼거랑 비스무리해서 위로를 삼는다.&lt;/p&gt;
&lt;pre id=&quot;code_1743949242409&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.util.Stack;

class Solution {
    public int solution(int[][] board, int[] moves) {
        int answer = 0;
        Stack&amp;lt;Integer&amp;gt; stack = new Stack&amp;lt;&amp;gt;();
        for (int move : moves) {
            for (int j = 0; j &amp;lt; board.length; j++) {
                if (board[j][move - 1] != 0) {
                    if (stack.isEmpty()) {
                        stack.push(board[j][move - 1]);
                        board[j][move - 1] = 0;
                        break;
                    }
                    if (board[j][move - 1] == stack.peek()) {
                        stack.pop();
                        answer += 2;
                    } else
                        stack.push(board[j][move - 1]);
                    board[j][move - 1] = 0;
                    break;
                }
            }
        }
        return answer;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스택에 관한 문제 하나 더 풀자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번주 한주도 존버하자 언젠간 또 금욜 오겠지????&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;끝.&lt;/p&gt;</description>
      <category>차곡차곡/Algorithms</category>
      <author>p퐝유p</author>
      <guid isPermaLink="true">https://nikeisme827.tistory.com/74</guid>
      <comments>https://nikeisme827.tistory.com/74#entry74comment</comments>
      <pubDate>Sun, 6 Apr 2025 23:26:01 +0900</pubDate>
    </item>
    <item>
      <title>나의 험난한 가상머신(VM)설치 여정</title>
      <link>https://nikeisme827.tistory.com/73</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;⭐&amp;nbsp;CentOS&amp;nbsp;설치&amp;nbsp;시작을&amp;nbsp;위한&amp;nbsp;설치&amp;nbsp;파일&amp;nbsp;다운로드 &lt;br /&gt;&lt;br /&gt;1.&amp;nbsp;Oracle&amp;nbsp;VirtualBox&amp;nbsp;:&amp;nbsp;VirtualBox-7.1.6-167084-Win.exe&amp;nbsp;다운로드 &lt;br /&gt;나는&amp;nbsp;window10Home&amp;nbsp;을&amp;nbsp;사용하고&amp;nbsp;있다.&amp;nbsp;이&amp;nbsp;버전은&amp;nbsp;hyper-v&amp;nbsp;를&amp;nbsp;제공하지&amp;nbsp;않는다는&amp;nbsp;절망적인&amp;nbsp;정보를&amp;nbsp;얻었다. &lt;br /&gt;하지만&amp;nbsp;나중에&amp;nbsp;설치를&amp;nbsp;할&amp;nbsp;수&amp;nbsp;있다는&amp;nbsp;글을&amp;nbsp;보았다.&amp;nbsp;좀&amp;nbsp;더&amp;nbsp;알아볼걸,,,,,&amp;nbsp;아냐&amp;nbsp;이제라도&amp;nbsp;알아서&amp;nbsp;다행이야&amp;nbsp;럭키비키자나 &lt;br /&gt;(해당&amp;nbsp;글&amp;nbsp;-&amp;nbsp;&lt;a href=&quot;https://blog.naver.com/toruin84/221936206258)&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://blog.naver.com/toruin84/221936206258)&lt;/a&gt;&lt;br /&gt;그래서&amp;nbsp;VirtualBox-7.1.6-167084-Win.exe를&amp;nbsp;설치하여&amp;nbsp;Oracle&amp;nbsp;virtualBox를&amp;nbsp;설치하여&amp;nbsp;가상화&amp;nbsp;머신을&amp;nbsp;만들어보도&amp;nbsp;록&amp;nbsp;하겠다. &lt;br /&gt;2.&amp;nbsp;centOS-Stream-9-latest-x86_64-dvd1.iso&amp;nbsp;다운로드 &lt;br /&gt;현재&amp;nbsp;centOS&amp;nbsp;사이트에서는&amp;nbsp;9와&amp;nbsp;10버전을&amp;nbsp;다운로드&amp;nbsp;받을&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp;안정성을&amp;nbsp;위해&amp;nbsp;9버전을&amp;nbsp;다운로드&amp;nbsp;받았다. &lt;br /&gt;3.&amp;nbsp;putty.exe&amp;nbsp;다운로드 &lt;br /&gt;원래는&amp;nbsp;형형색깔이&amp;nbsp;있는&amp;nbsp;친근한&amp;nbsp;mobaXterm&amp;nbsp;을&amp;nbsp;선호한다.&amp;nbsp;하지만&amp;nbsp;putty&amp;nbsp;를&amp;nbsp;많이&amp;nbsp;사용하는&amp;nbsp;것&amp;nbsp;같아&amp;nbsp;선택했다. &lt;br /&gt;나의&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;VM&amp;nbsp;(가상화&amp;nbsp;머신)&amp;nbsp;만들기 &lt;br /&gt;1.&amp;nbsp;새로&amp;nbsp;만들기를&amp;nbsp;선택하여&amp;nbsp;가상화&amp;nbsp;머신을&amp;nbsp;만든다. &lt;br /&gt;&lt;br /&gt;(모두&amp;nbsp;같은&amp;nbsp;D:&amp;nbsp;경로로&amp;nbsp;설정해야&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;637&quot; data-origin-height=&quot;248&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zTmIV/btsM3oeck16/qvhvC9FrbQ28a9ZRPzIKvK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zTmIV/btsM3oeck16/qvhvC9FrbQ28a9ZRPzIKvK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zTmIV/btsM3oeck16/qvhvC9FrbQ28a9ZRPzIKvK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzTmIV%2FbtsM3oeck16%2FqvhvC9FrbQ28a9ZRPzIKvK%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;637&quot; height=&quot;248&quot; data-origin-width=&quot;637&quot; data-origin-height=&quot;248&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;632&quot; data-origin-height=&quot;173&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/coowbb/btsM19vi45J/qzFVrpfRqqAoK8JzKldgh1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/coowbb/btsM19vi45J/qzFVrpfRqqAoK8JzKldgh1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/coowbb/btsM19vi45J/qzFVrpfRqqAoK8JzKldgh1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcoowbb%2FbtsM19vi45J%2FqzFVrpfRqqAoK8JzKldgh1%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;632&quot; height=&quot;173&quot; data-origin-width=&quot;632&quot; data-origin-height=&quot;173&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;2.&amp;nbsp;가상&amp;nbsp;머신에&amp;nbsp;CentOS9&amp;nbsp;설치하기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;956&quot; data-origin-height=&quot;591&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bjQOnL/btsM3mUZqhz/I3DukEssxoTCgXlIsTARb0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bjQOnL/btsM3mUZqhz/I3DukEssxoTCgXlIsTARb0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bjQOnL/btsM3mUZqhz/I3DukEssxoTCgXlIsTARb0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbjQOnL%2FbtsM3mUZqhz%2FI3DukEssxoTCgXlIsTARb0%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;956&quot; height=&quot;591&quot; data-origin-width=&quot;956&quot; data-origin-height=&quot;591&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;3.&amp;nbsp;SSH&amp;nbsp;사용하여&amp;nbsp;서버&amp;nbsp;접속하기 &lt;br /&gt;ip를&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;449&quot; data-origin-height=&quot;439&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bsLMub/btsM1eD9BEP/aQ5FEM5ZzJXUlS3ZIDycTk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bsLMub/btsM1eD9BEP/aQ5FEM5ZzJXUlS3ZIDycTk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bsLMub/btsM1eD9BEP/aQ5FEM5ZzJXUlS3ZIDycTk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbsLMub%2FbtsM1eD9BEP%2FaQ5FEM5ZzJXUlS3ZIDycTk%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;449&quot; height=&quot;439&quot; data-origin-width=&quot;449&quot; data-origin-height=&quot;439&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;연결이&amp;nbsp;안된다.....&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;661&quot; data-origin-height=&quot;421&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c2ZT0r/btsM1N0AzKv/gH7MCxtOJwlOlxr8NzkXN0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c2ZT0r/btsM1N0AzKv/gH7MCxtOJwlOlxr8NzkXN0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c2ZT0r/btsM1N0AzKv/gH7MCxtOJwlOlxr8NzkXN0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc2ZT0r%2FbtsM1N0AzKv%2FgH7MCxtOJwlOlxr8NzkXN0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;661&quot; height=&quot;421&quot; data-origin-width=&quot;661&quot; data-origin-height=&quot;421&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;ip&amp;nbsp;a&amp;nbsp;명령어로&amp;nbsp;ip&amp;nbsp;먼저&amp;nbsp;확인하자.&amp;nbsp;ip&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;829&quot; data-origin-height=&quot;136&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bWlbzC/btsM19vi506/6VItGxO4JkgZnj0PIdYDLk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bWlbzC/btsM19vi506/6VItGxO4JkgZnj0PIdYDLk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bWlbzC/btsM19vi506/6VItGxO4JkgZnj0PIdYDLk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbWlbzC%2FbtsM19vi506%2F6VItGxO4JkgZnj0PIdYDLk%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;136&quot; data-origin-width=&quot;829&quot; data-origin-height=&quot;136&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;rpm&amp;nbsp;-q&amp;nbsp;openssh-server&amp;nbsp;로&amp;nbsp;ssh&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;339&quot; data-origin-height=&quot;45&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ckBOaC/btsM3kJFywc/6QOKKO7o3KK24VXVdNBBRK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ckBOaC/btsM3kJFywc/6QOKKO7o3KK24VXVdNBBRK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ckBOaC/btsM3kJFywc/6QOKKO7o3KK24VXVdNBBRK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FckBOaC%2FbtsM3kJFywc%2F6QOKKO7o3KK24VXVdNBBRK%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;45&quot; data-origin-width=&quot;339&quot; data-origin-height=&quot;45&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;ss&amp;nbsp;-tln&amp;nbsp;|&amp;nbsp;grep&amp;nbsp;:22&amp;nbsp;로&amp;nbsp;22번&amp;nbsp;포트&amp;nbsp;열려있는지&amp;nbsp;확인.&amp;nbsp;역시&amp;nbsp;포트가&amp;nbsp;닫혀있었다.&amp;nbsp;아무것도&amp;nbsp;안나왔다. &lt;br /&gt;&lt;br /&gt;아래와&amp;nbsp;같이&amp;nbsp;실행하면&amp;nbsp;22번&amp;nbsp;포트가&amp;nbsp;열리고,&amp;nbsp;putty&amp;nbsp;로&amp;nbsp;접속이&amp;nbsp;잘된다. &lt;br /&gt;&lt;br /&gt;sudo&amp;nbsp;firewall-cmd&amp;nbsp;--permanent&amp;nbsp;--add-service=ssh&amp;nbsp;:&amp;nbsp;입력해서&amp;nbsp;SSH&amp;nbsp;연결을&amp;nbsp;허용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;sudo firewall-cmd --reload&lt;span style=&quot;background-color: #0d1117; color: #f0f6fc; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;: 방화벽 설정을 다시 로드&lt;/span&gt;&lt;br /&gt;sudo systemctl status sshd&lt;span style=&quot;background-color: #0d1117; color: #f0f6fc; text-align: start;&quot;&gt;: ssh 켜져있는지 확인 (active 면 성공!)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;687&quot; data-origin-height=&quot;107&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cbmfM6/btsM3n0FWE9/GlYMpQvMgnn4jTaja3FZB0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cbmfM6/btsM3n0FWE9/GlYMpQvMgnn4jTaja3FZB0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cbmfM6/btsM3n0FWE9/GlYMpQvMgnn4jTaja3FZB0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcbmfM6%2FbtsM3n0FWE9%2FGlYMpQvMgnn4jTaja3FZB0%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;687&quot; height=&quot;107&quot; data-origin-width=&quot;687&quot; data-origin-height=&quot;107&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;ip를&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;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;199&quot; data-origin-height=&quot;25&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b0QyQr/btsM11dfhqJ/H5wTd8kQzuxdEi6lrUf2e0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b0QyQr/btsM11dfhqJ/H5wTd8kQzuxdEi6lrUf2e0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b0QyQr/btsM11dfhqJ/H5wTd8kQzuxdEi6lrUf2e0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb0QyQr%2FbtsM11dfhqJ%2FH5wTd8kQzuxdEi6lrUf2e0%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;199&quot; height=&quot;25&quot; data-origin-width=&quot;199&quot; data-origin-height=&quot;25&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;SSH&amp;nbsp;를&amp;nbsp;root&amp;nbsp;계정으로&amp;nbsp;접속하기 &lt;br /&gt;그런데&amp;nbsp;온전히&amp;nbsp;나만&amp;nbsp;사용하는&amp;nbsp;건데도&amp;nbsp;root&amp;nbsp;로&amp;nbsp;접속이&amp;nbsp;안된다.&amp;nbsp;다시&amp;nbsp;centOS&amp;nbsp;로&amp;nbsp;돌아간다&amp;nbsp;흑흑흑흑흑 &lt;br /&gt;&lt;br /&gt;기본적으로&amp;nbsp;CentOS는&amp;nbsp;root&amp;nbsp;계정의&amp;nbsp;SSH&amp;nbsp;원격&amp;nbsp;접속을&amp;nbsp;차단하도록&amp;nbsp;설정되어&amp;nbsp;있다고&amp;nbsp;한다.&amp;nbsp;root&amp;nbsp;계정에게&amp;nbsp;권한을&amp;nbsp;주자. &lt;br /&gt;&lt;br /&gt;sudo&amp;nbsp;passwd&amp;nbsp;root&amp;nbsp;:&amp;nbsp;입력하여&amp;nbsp;비밀번호&amp;nbsp;설정 &lt;br /&gt;&lt;br /&gt;sudo&amp;nbsp;vi&amp;nbsp;/etc/ssh/sshd_config &lt;br /&gt;열어서&amp;nbsp;아래&amp;nbsp;속성을&amp;nbsp;추가 &lt;br /&gt;PermitRootLogin&amp;nbsp;yes&amp;nbsp;&amp;nbsp;&amp;lt;--&amp;nbsp;추가&amp;nbsp;또는&amp;nbsp;수정 &lt;br /&gt;PasswordAuthentication&amp;nbsp;yes&amp;nbsp;&amp;nbsp;&amp;lt;--&amp;nbsp;필요하면&amp;nbsp;yes로&amp;nbsp;변경 &lt;br /&gt;&lt;br /&gt;다시&amp;nbsp;방화벽&amp;nbsp;재부팅! &lt;br /&gt;sudo&amp;nbsp;firewall-cmd&amp;nbsp;--reload&amp;nbsp;:&amp;nbsp;방화벽&amp;nbsp;설정을&amp;nbsp;다시&amp;nbsp;로드 &lt;br /&gt;sudo&amp;nbsp;systemctl&amp;nbsp;status&amp;nbsp;sshd:&amp;nbsp;ssh&amp;nbsp;켜져있는지&amp;nbsp;확인&amp;nbsp;(active&amp;nbsp;면&amp;nbsp;성공!) &lt;br /&gt;&lt;br /&gt;너무&amp;nbsp;잘된다.&amp;nbsp;(positive)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;202&quot; data-origin-height=&quot;49&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cQegRU/btsM1Lg7owe/aeMKNvy8NafIfEnDi93u91/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cQegRU/btsM1Lg7owe/aeMKNvy8NafIfEnDi93u91/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cQegRU/btsM1Lg7owe/aeMKNvy8NafIfEnDi93u91/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcQegRU%2FbtsM1Lg7owe%2FaeMKNvy8NafIfEnDi93u91%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;202&quot; height=&quot;49&quot; data-origin-width=&quot;202&quot; data-origin-height=&quot;49&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>차곡차곡</category>
      <author>p퐝유p</author>
      <guid isPermaLink="true">https://nikeisme827.tistory.com/73</guid>
      <comments>https://nikeisme827.tistory.com/73#entry73comment</comments>
      <pubDate>Sun, 30 Mar 2025 23:43:17 +0900</pubDate>
    </item>
    <item>
      <title>[ 정보 처리 기사 필기 ] 화면 설계</title>
      <link>https://nikeisme827.tistory.com/71</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;표준 및 지침에 따라 UI를 제작하기 위해서 &lt;b&gt;설계도&lt;/b&gt;가 필요하다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;background-color: #ffc1c8;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;★ &lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;설계도는 결과물에 대해 미리보기 기능을 한다.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&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;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;☆ &lt;span style=&quot;background-color: #9feec3;&quot;&gt;와이어프레임&lt;/span&gt; : 뼈대 ( 레이아웃 ) 배치, 화면 단위&lt;/b&gt;&lt;/span&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;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;☆ &lt;span style=&quot;background-color: #9feec3;&quot;&gt;목업&lt;/span&gt; : 실제 화면과 유사,&amp;nbsp; 기능 구현 아님&lt;/b&gt;&lt;/span&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;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;☆ &lt;span style=&quot;background-color: #9feec3;&quot;&gt;스토리보드&lt;/span&gt; : 와이어 프레임 + 콘텐츠 설명 ( Description ), 이동경로&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;&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; 작업 지침서 활용 ( Description은 세부적 작성 필요 )&amp;nbsp;&lt;/b&gt;&lt;/span&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;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;☆ &lt;span style=&quot;background-color: #9feec3;&quot;&gt;프로토타입&lt;/span&gt; : 또 나왔네, 인터렉션 적용 ( 동적인 형태 )&lt;/b&gt;&lt;/span&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;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;☆ &lt;span style=&quot;background-color: #9feec3;&quot;&gt;유스케이스&lt;/span&gt; : 사용자 요구사항 ( 기능적 ) 을 다이어그램 형식으로 문서화&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;&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; 각각의 유스케이스에 대한 명세서 작성&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; background-color: #ffc1c8;&quot;&gt;&lt;b&gt;★ UI 요구사항 확인&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;☆ 기능 : 무엇을 실행하는지, 동사형으로 정리&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;☆ 품질 : 품질, 서비스, 감성적인 부분&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;☆ 제약 : 비용과 데드라인, 규제 등&lt;/span&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;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;★ 정황 시나리오 작성&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- 6하원칙, 이야기 형식, 완성된 서비스를 상상&lt;/span&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;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;★ 요구사항 작성&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- 정황 시나리오를 토대로 작성&amp;nbsp;&lt;/span&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;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;★&amp;nbsp; 요약&lt;/b&gt;&lt;/span&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;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;- &lt;span style=&quot;background-color: #9feec3;&quot;&gt;개인적 인터뷰&lt;/span&gt;를 통해 가능한 많은 사람들과 인터뷰를 진행한다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;- 인터뷰를 통해 &lt;span style=&quot;background-color: #9feec3;&quot;&gt;사업적, 기술적 요구사항&lt;/span&gt;을 명확히 한다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;- &lt;span style=&quot;background-color: #9feec3;&quot;&gt;인터뷰 후, 리서치를 진행&lt;/span&gt;해야 효율적이다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;- 활동 사항을 정의할 때는서로 &lt;span style=&quot;background-color: #9feec3;&quot;&gt;협의를 통해 진행&lt;/span&gt;한다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;- 요구사항의 작성은 &lt;span style=&quot;background-color: #9feec3;&quot;&gt;사용자 중심&lt;/span&gt;으로 하여 개발에 편리하도록 한다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;- UI 요구사항 중 순서는 중요하지 않다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;- 정확 시나리오는 &lt;span style=&quot;background-color: #9feec3;&quot;&gt;완성된 서비스를 상상&lt;/span&gt;하며 &lt;span style=&quot;background-color: #9feec3;&quot;&gt;6하원칙과 이야기 형식&lt;/span&gt;으로 작성한다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;- 요구사항은 &lt;span style=&quot;background-color: #9feec3;&quot;&gt;정황 시나리오를 토대로 작성&lt;/span&gt;한다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;background-color: #ffc1c8;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;★&lt;span&gt; 품질 요구사항&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; background-color: #9feec3;&quot;&gt;&lt;b&gt;☆&amp;nbsp;기능&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;- 적정한 기능이 정확하게 + 호환, 보안&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;- 적절성, 정확, 상호운용, 보안, 호환&lt;/b&gt;&lt;/span&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;font-family: 'Noto Serif KR'; background-color: #9feec3;&quot;&gt;&lt;b&gt;☆&amp;nbsp;사용&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;- 얼마나 쉽고 편한지&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;- 이해, 학습, 운용, 친밀&lt;/b&gt;&lt;/span&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;font-family: 'Noto Serif KR'; background-color: #9feec3;&quot;&gt;&lt;b&gt;☆ 신뢰&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;- 고장이 나도 문제 없어!&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;- 성숙성, 고장 허용성, 회복성&lt;/b&gt;&lt;/span&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;font-family: 'Noto Serif KR'; background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;b&gt;☆&amp;nbsp;유지보수&lt;/b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;&lt;b&gt;-&amp;nbsp; 개선 및 확장&lt;/b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;&lt;b&gt;- 분석, 변경, 시험, 안정&lt;/b&gt;&lt;/b&gt;&lt;/span&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;font-family: 'Noto Serif KR'; background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;b&gt;☆&amp;nbsp;이식&lt;/b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;&lt;b&gt;- 다른 환경에서 적응&lt;/b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;&lt;b&gt;- 적용, 설치, 대체, 공존&lt;/b&gt;&lt;/b&gt;&lt;/span&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;font-family: 'Noto Serif KR'; background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;b&gt;☆&amp;nbsp;효율&lt;/b&gt;&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;- 한정된 시간, 자원으로 많은 일 처리&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- 시간, 자원&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;background-color: #ffc1c8;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;★&lt;span&gt;&lt;span&gt; UI&amp;nbsp;프로토타입&amp;nbsp;제작&amp;nbsp;및&amp;nbsp;검토&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;★&amp;nbsp;UI&amp;nbsp;프로토타입&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- 동적인 형태 ( 실제 동작하는 것처럼)의 테스트 모델&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- 필수 기능을 포함, 간단하게, 실 사용자 테스트로 기능 검증&lt;/span&gt;&lt;/b&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;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;장점 : 이해와 오류발견이 쉽다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;단점 : 자원 소모, 생략 가능성&lt;/span&gt;&lt;/b&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;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;☆ &lt;/b&gt;종류&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- 페이퍼 ( 손으로 ) : 저렴, 즉시, 간단&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- 디지털 (SW 로) : 결과와 비슷, 테스트 및 수정, 어려움&lt;/span&gt;&lt;/b&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;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;☆ &lt;/b&gt;고려사항&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- 계획 : 목적 -&amp;gt; 환경 -&amp;gt; 핵심UI -&amp;gt; 인원 -&amp;gt; 검증 -&amp;gt; 해결 -&amp;gt; 가이드&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- 작성 : 범위확인 - 목표확인 - 자원확인&lt;/span&gt;&lt;/b&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;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;☆ &lt;/b&gt;제작단계&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;요구사항 분석 - 요구사항 작성 ( 프로토타입)&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;사용자 테스트 및 수정 - 사용자 피드백 및 승인 ( 반복 )&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;background-color: #ffc1c8;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;★&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;UI 설계서&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;☆&lt;span&gt; 표지 : 프로젝트 ( 시스템 ) 명&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;☆&lt;span&gt; 개정 이력 : 초안작성 이후 변경할 때마다 버전 0 .1 증가&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;☆&lt;span&gt; 요구사항 정의서 : 요구사항 별 적용여부 기록&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;☆&lt;span&gt; 시스템 구조 : 전체 시스템 ( 사용자, 관리자 등 ) 의 설계 구조&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;☆&lt;span&gt; 사이트 맵 : 전체 콘텐츠 메뉴별 구성 + 표 형태로 작성&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;☆&lt;span&gt; 프로세스 정의서 : 사용자 입장에서 작업이 진행되는 순서도&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;☆&lt;span&gt; 화면 설계 : 각 화면별로 표지 + 스토리 보드&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;background-color: #ffc1c8;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;★&lt;span&gt;&lt;span&gt;&lt;span&gt; 유용성평가, 상세설계 , 감성공학&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;☆ 유용성 평가&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;뜻 : 사용자 입장에서 얼마나 유용한지&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;실행 ( 기능 ) : 불필요, 중복, 불편, 어려운&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;결과 ( 평가 ) : 즉각적이지 않은 피드백, 결과 이해, 파악이 어려움&lt;/span&gt;&lt;/b&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;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;☆ 상세설계&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;시나리오 : 순서도나 계층구조로 작성&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;일반규칙 : 기능, 구조, 인터렉션, 예외처리 ( 이후 세부기능 정의)&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;기대효과 : 긍정적인 문장과 단어 ( 완전, 일관, 이해 )&lt;/span&gt;&lt;/b&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;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;☆ 감성공학&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;HCI : 편리하고 안전한 시스템 개발 ( 최적의 UX가 목표)&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;UX : 시스템 이용 경험. 주관적임 ( 객관적인 UI 편리성)&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;감성공학 : 감성적, 인간친화적 개발&lt;/span&gt;&lt;/b&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;figure data-ke-type=&quot;video&quot; data-ke-style=&quot;alignCenter&quot; data-video-host=&quot;youtube&quot; data-video-url=&quot;https://www.youtube.com/watch?v=rph5xrdcXRc&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/cLSV4i/hyRoErkyr8/VEfktS7f8p7brL5lckHw90/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/rph5xrdcXRc&quot; width=&quot;860&quot; height=&quot;484&quot; frameborder=&quot;&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;
&lt;figcaption&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <author>p퐝유p</author>
      <guid isPermaLink="true">https://nikeisme827.tistory.com/71</guid>
      <comments>https://nikeisme827.tistory.com/71#entry71comment</comments>
      <pubDate>Wed, 25 Jan 2023 10:45:20 +0900</pubDate>
    </item>
    <item>
      <title>[정보 처리 기사 필기 ] UI 표준 및 지침</title>
      <link>https://nikeisme827.tistory.com/70</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;※ 표준 - 공통적인 것&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;※&amp;nbsp;지침 - 꼭 지켜야하는 것&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;★ 웹 표준&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- 웹 접근성 : 장애가 있는 사람들도 동등하게 이용 가능&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- 크로스 브라우징 : 어느 환경 ( 브라우저, 플랫폼)에서도 이용 가능&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;☆ 웹 접근성을 지키기 위한 지침&lt;/span&gt;&lt;/b&gt;&lt;/h3&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;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- 인식 (대체)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp;대상을 판단할 수 있어야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; EX ) 시각 장애인을 위한 음성 안내&lt;/span&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;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- 운용 (포인팅 )&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp;서비스를 이용할 때, 편안해야한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp;EX ) 마우스 대신 키보드나 음성&lt;/span&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;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- 이해 ( 논리적 )&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; 결과적으로 납득이 가야한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; EX ) 로그인 하는데 로그인에 대한 메시지가 생성되어 확인이 되도록 함.&lt;/span&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;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- 견고함&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; EX ) 제작에 필요한 문법들을 준수하며 개발해야한다.&amp;nbsp;&lt;/span&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;font-family: 'Noto Serif KR';&quot;&gt;정부 시스템 - 누구나 평등하게 정보 습득&lt;/span&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;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;☆ 문법 준수&lt;/span&gt;&lt;/b&gt; : 보편적, 보통 표현&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;☆ 비표준 지양&lt;/b&gt;&lt;/span&gt; : 불가피할 경우, 대체 정보 제공&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;☆ 호환성&lt;/span&gt;&lt;/b&gt; : 결제, 인증 기능 등&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure data-ke-type=&quot;video&quot; data-ke-style=&quot;alignCenter&quot; data-video-host=&quot;youtube&quot; data-video-url=&quot;https://www.youtube.com/watch?v=1lIRsZ6_XFY&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/Pgw8K/hyRoBmDyXK/EYKYPqWCldeVJxziOYU8D0/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/1lIRsZ6_XFY&quot; width=&quot;860&quot; height=&quot;484&quot; frameborder=&quot;&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;
&lt;figcaption&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <author>p퐝유p</author>
      <guid isPermaLink="true">https://nikeisme827.tistory.com/70</guid>
      <comments>https://nikeisme827.tistory.com/70#entry70comment</comments>
      <pubDate>Wed, 25 Jan 2023 10:31:18 +0900</pubDate>
    </item>
    <item>
      <title>[정보 처리 기사 필기] 사용자 인터페이스</title>
      <link>https://nikeisme827.tistory.com/69</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; background-color: #ffc1c8;&quot;&gt;★ UI (User Interface )&amp;nbsp; 란?&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;-&amp;nbsp; 각&amp;nbsp;사용자와&amp;nbsp;시스템간의&amp;nbsp;매게체&amp;nbsp;역할을&amp;nbsp;하는&amp;nbsp;모든&amp;nbsp;것&lt;/span&gt;&lt;/b&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;font-family: 'Noto Serif KR';&quot;&gt;★ 사용자 인터페이스 3가지 분야 : &lt;b&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;제어 / 구성 / 기능&lt;/span&gt;&lt;/b&gt;&lt;/span&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;font-family: 'Noto Serif KR';&quot;&gt;★ 사용자 인터페이스 특징&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;- 만족도에 큰 영향을 끼치기 때문에, 가장 많이 변경됨&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;- 편리성과 가독성, 이해도를 높인다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;- 최소한의 노력으로 결과를 얻을 수 있도록 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;- 소프트웨어 아키텍처를 숙지해야 한다.&lt;/span&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;font-family: 'Noto Serif KR';&quot;&gt;★ 사용자 인터페이스의 구분&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; 1. CLI ( Command Line Interface ) - ex. 텍스트&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; 2. GUI ( Graphic User Interface ) - ex. 마우스&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; 3. NUI ( Natural User Interface ) -&amp;nbsp; ex. 말, 행동&lt;/span&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;font-family: 'Noto Serif KR';&quot;&gt;★ 사용자 인터페이스 기본 원칙 : 직관 / 유효 /&amp;nbsp; 학습 / 유연&lt;/span&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;font-family: 'Noto Serif KR';&quot;&gt;★ 사용자 인터페이스의 설계 지침 ( 긍정적 )&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; - 사용자 중심, 일관성, 단순성, 결과예측 가능, 표준화, 접근성&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; - 명확성, 가시성, 오류발생 해결&amp;nbsp;&lt;/span&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure data-ke-type=&quot;video&quot; data-ke-style=&quot;alignCenter&quot; data-video-host=&quot;youtube&quot; data-video-url=&quot;https://www.youtube.com/watch?v=x-c0mWZSOzQ&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/nAhwr/hyRoOlXnuX/mw70u4miqwnzGsDszXq8a0/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/x-c0mWZSOzQ&quot; width=&quot;860&quot; height=&quot;484&quot; frameborder=&quot;&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;
&lt;figcaption&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;※ 참고 영상&lt;/p&gt;</description>
      <author>p퐝유p</author>
      <guid isPermaLink="true">https://nikeisme827.tistory.com/69</guid>
      <comments>https://nikeisme827.tistory.com/69#entry69comment</comments>
      <pubDate>Wed, 25 Jan 2023 09:42:34 +0900</pubDate>
    </item>
    <item>
      <title>20230112 정보 처리 기사 필기 - 1과목 ( 소프트웨어 설계)</title>
      <link>https://nikeisme827.tistory.com/67</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;background-color: #ffc1c8;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;1장. 요구사항 확인&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;소프트웨어 생명 주기&lt;/b&gt;&lt;/span&gt; : 소프트웨어 개발 과정을 단계별로 나눈 것&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;1. 폭포수 모델 &lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- 각 단계를 &lt;b&gt;한번씩만&lt;/b&gt; 거침 &lt;b&gt;(되돌릴 수 없음).&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- 단계별 철저한 검증 필요 / 매뉴얼 작성 필요&lt;/span&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;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;2. 프로토타입 모델&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- 기능적 인터페이스 중심으로 &lt;b&gt;견본 개발 후 최종 개발&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- 추후 발견 될 오류 방지&lt;/span&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;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;3. 나선형 모델&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- &lt;b&gt;계획 -&amp;gt; 분석(검증) -&amp;gt; 개발 -&amp;gt; 평가(오류방지) 단계 반복&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- 폭포수와 프로토타입의 장점 흡수하여 &lt;b&gt;점진적 개발&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- &lt;b&gt;대규모&lt;/b&gt; 소프트웨어 개발에 용이&lt;/span&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;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;4. 애자일 모델&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- 요구사항 반영 및 &lt;b&gt;고객과의 의사소통 빈도를 높이는 것&lt;/b&gt; 목표&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- 여러 개발 방법을 아우르는 모델&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;background-color: #ffc1c8;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;★ 1장. 요구사항 확인 - 06. 요구사항 정의 분석 확인&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;☆ 요구사항 &lt;/b&gt;&lt;/span&gt;&lt;b&gt;:&lt;/b&gt; 서비스에 대한 설명 및 제약 조건&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- &lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;기능&lt;/b&gt;&lt;/span&gt; : 기능 자체&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- &lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;비기능&lt;/b&gt;&lt;/span&gt; : 기능의 품질, 제약 사항&lt;/span&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;font-family: 'Noto Serif KR';&quot;&gt;- &lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;사용자&lt;/b&gt;&lt;/span&gt; : 쉬운 표현 사용&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- &lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;시스템&lt;/b&gt;&lt;/span&gt; : 개발자 입장, 전문 용어&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; background-color: #9feec3;&quot;&gt;&lt;b&gt;☆&lt;/b&gt;요구사항 개발 프로세스&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;&lt;b&gt;&amp;nbsp; &amp;nbsp;☆ &lt;/b&gt;도&lt;/b&gt;출 ( 의사소통 ) -&amp;gt; &lt;b&gt;분&lt;/b&gt;석 -&amp;gt; &lt;b&gt;명&lt;/b&gt;세(문서화) -&amp;gt; &lt;b&gt;확&lt;/b&gt;인&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;b&gt;☆ &lt;/b&gt;분석&lt;/b&gt;&lt;/span&gt; : 타당성 조사, 특정 기준으로 분류&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;개념 모델링&lt;/b&gt;&lt;/span&gt; : 단순화, 개념적 표현, 객체간 관계와 &lt;u&gt;&lt;b&gt;종속성&lt;/b&gt;&lt;/u&gt;분석&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;협상&lt;/b&gt;&lt;/span&gt; : ( 기능과 비기능, 필요자원, 서로 ) 의 요구사항이 &lt;u&gt;&lt;b&gt;충돌&lt;/b&gt;&lt;/u&gt;하는 경우&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;정형분석&lt;/b&gt;&lt;/span&gt; : 마지막 단계, 구문과 의미를 갖는 언어 사용, &lt;u&gt;&lt;b&gt;수학적 기호&lt;/b&gt;&lt;/u&gt;로 표현&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;b&gt;☆ &lt;/b&gt;확인&lt;/b&gt;&lt;/span&gt; : 검증&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp;&lt;b&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;검토&lt;/span&gt;&lt;/b&gt; : 일반적, 고객대표 포함&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;모델 검증&lt;/b&gt;&lt;/span&gt; : &lt;u&gt;&lt;b&gt;정적 ( 논리적)&lt;/b&gt; &lt;/u&gt;검증, 실행 안함&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;프로토타이핑&lt;/b&gt;&lt;/span&gt; : 지속적인 프로토타입 작성, 사전 피드백&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&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; (단점 : 프로토타입에만 집중, 비용 부담, 과대평가)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;인수테스트&lt;/b&gt;&lt;/span&gt; : 사용자 입장에서 요구사항 체크 (계획 필요)&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;background-color: #ffc1c8;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;★ 1장. 요구사항 확인 - 07. UML ( Unified Modeling Language )&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; background-color: #9feec3;&quot;&gt;&lt;b&gt;☆ UML ( Unified Modeling Language )&lt;/b&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- 원활한 의사소통을 위해 표준화된 모델링 언어&amp;nbsp;&lt;/span&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;font-family: 'Noto Serif KR';&quot;&gt;※ 클객컴배복패 / 유시커상활타&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 136px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 17px; text-align: center;&quot; colspan=&quot;2&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;구조적 다이어그램&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 17px; text-align: center;&quot; colspan=&quot;2&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;행위 다이어그램&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 25%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;종류&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;키워드&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;종류&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;키워드&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 25%; height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;클래스&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;구조&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;유스케이스&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;모델링&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 25%; height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;객체&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;관계&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;시퀀스&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;메시지&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 25%; height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;컴포넌트&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;구현, 인터페이스&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;커뮤니케이션&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;메시지 + 연관관계&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 25%; height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;배치&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;구현, 위치&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;상태&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;상태 변화&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 25%; height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;복합체 구조&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;내부구조&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;활동&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;로직 흐름&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 25%; height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;패키지&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;그룹&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;타이밍&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;시간 제약&lt;/span&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;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; background-color: #9feec3;&quot;&gt;&lt;b&gt;☆&lt;span&gt; UML 구성 요소&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt; : &lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;사물 / 관계 / 다이어그램&lt;/b&gt;&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;※ 사관다&lt;/span&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;font-family: 'Noto Serif KR';&quot;&gt;사물 : 특정 대상&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- 구조 : 요소 / 행동 : 행위 / 그룹 : 묶음 / 주해 : 설명&lt;/span&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;font-family: 'Noto Serif KR';&quot;&gt;관계 : 연관, 의존, 일반화, 실체화, 집합, 포함&lt;/span&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;font-family: 'Noto Serif KR';&quot;&gt;◎ 물리적인 자원의 위치를 표시하는 것으로 구현 단계에서 사용되는 것은?&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;b&gt;- 배치&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;◎ 사물의 종류 중, ( 구조, 행동, 주해 ) 를 제외한 나머지 하나는 ?&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;b&gt;- 그룹&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;◎( 시퀀스, 상태, 배치, 활동 ) 중, 동적인 행위를 표현하기 위한 것이 아닌 것은?&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;b&gt;- 배치&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;◎ UML 다이어그램 중, 구현 단계에서 사용하기 적절한 것은?&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;b&gt;- 컴포넌트 , 배치&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;◎ 의존, 실체화 관계에서 처럼, 일시적인 관계를 표현할 때 사용되는 선은?&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;b&gt;- 점선 화살표&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;◎ 다중도 표현에서 ( '다수', '또는' ) 에 해당하는 기호는?&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;b&gt;- * / ....&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;◎ 자동차와 열쇠의 관계를 표현하기 가장 적절한 관계는?&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp;&lt;b&gt; - 포함&lt;/b&gt;&lt;/span&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>
      <author>p퐝유p</author>
      <guid isPermaLink="true">https://nikeisme827.tistory.com/67</guid>
      <comments>https://nikeisme827.tistory.com/67#entry67comment</comments>
      <pubDate>Thu, 12 Jan 2023 17:14:09 +0900</pubDate>
    </item>
    <item>
      <title>[Java] JVM의 메모리 구조</title>
      <link>https://nikeisme827.tistory.com/66</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;background-color: #ffc1c8;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;★ JVM이란?&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- JVM 은 Java virtual Machine의 약자로 &lt;b&gt;'자바를 실행하기 위한 가상 기계'&lt;/b&gt;라고 할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;자바를 실행하기 위한 가상 컴퓨터라고 할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;자바가 속도가 느리다는 단점이 있는데 Java 애플리케이션은 JVM을 한 번 더 거치고, 하드웨어에 맞게 완전히 컴파일 된 상태가 아니고 실행 시에 해석 되기 때문이다.&amp;nbsp;&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;627&quot; data-origin-height=&quot;705&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cjCLbF/btrURT6cld7/ufKOyZM4DFEQdVkEG7MHfk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cjCLbF/btrURT6cld7/ufKOyZM4DFEQdVkEG7MHfk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cjCLbF/btrURT6cld7/ufKOyZM4DFEQdVkEG7MHfk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcjCLbF%2FbtrURT6cld7%2FufKOyZM4DFEQdVkEG7MHfk%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;627&quot; height=&quot;705&quot; data-origin-width=&quot;627&quot; data-origin-height=&quot;705&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;background-color: #ffc1c8;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;★ JVM 메모리 구조&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;3가지 주요 영역&lt;/span&gt;&lt;/b&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;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;1. 메서드 영역 (method area)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- 프로그램 실행 중 어떤 클래스가 사용되면, JVM은 &lt;span style=&quot;background-color: #9feec3;&quot;&gt;해당 클래스의 클래스파일을 읽어서 분석 후, &lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;클래스에 대한 정보를 이곳에 저장&lt;/span&gt;한다. 이 때, 클래스의 클래스 변수(calss variable)도 이 영역에 함께 생성된다.&lt;/span&gt;&lt;/b&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;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;2. 힙 (heap)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- &lt;span style=&quot;background-color: #9feec3;&quot;&gt;인스턴스가 생성되는 공간.&lt;/span&gt; 프로그램 실행 중 생성되는 인스턴스는 모두 이곳에 생성된다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;즉, 인스턴스 변수들이 생성되는 공간이다.&lt;/span&gt;&lt;/b&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;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;3. 호출 스택 (call statck 또는 execution stack)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- 호출 스택은 &lt;span style=&quot;background-color: #9feec3;&quot;&gt;메서드의 작업에 필요한 메모리 공간을 제공&lt;/span&gt;한다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;메서드가 호출되면, 호출 스택에 호출된 메서드를 위한 메모리가 할당 된다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;이 메모리는 메서드가 작업을 수행하는 동안 지역변수(매개 변수)들과 연산의 중간결과 등을 저장하는데 사용된다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;그리고 메서드가 작업을 마치면 할당되었던 &lt;span style=&quot;background-color: #9feec3;&quot;&gt;메모리 공간은 반환되어 비워진다.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>차곡차곡/Java</category>
      <author>p퐝유p</author>
      <guid isPermaLink="true">https://nikeisme827.tistory.com/66</guid>
      <comments>https://nikeisme827.tistory.com/66#entry66comment</comments>
      <pubDate>Thu, 29 Dec 2022 00:24:36 +0900</pubDate>
    </item>
    <item>
      <title>[Java] 변수와 메서드</title>
      <link>https://nikeisme827.tistory.com/65</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;background-color: #ffc1c8;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;★ 선언 위치에 따른 변수의 종류&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&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;font-family: 'Noto Serif KR';&quot;&gt;변수의 종류&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; background-color: #9feec3;&quot;&gt;1. 클래스 변수&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; background-color: #9feec3;&quot;&gt;2. 인스턴스 변수&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; background-color: #9feec3;&quot;&gt;3. 지역 변수&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;&quot;&gt;변수의 종류를 결정 짓는 기준은 &lt;span style=&quot;background-color: #9feec3;&quot;&gt;'&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt; 변수의 선언된 위치'&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;&quot;&gt;멤버 변수를 제외한 나머지 변수들은 모두 지역변수&lt;/span&gt;&lt;span style=&quot;&quot;&gt;멤버 변수 중 static이 붙은 것이 클래스 변수, 붙지 않은 것이 인스턴스 변수&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1672150781303&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Variables 
{
	int iv; // 인스턴스 변수
    static int cv; // 클래스 변수(static 변수, 공유변수)
    
    void method()
    {
    	int lv = 0; // 지역 변수
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 100px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;변수의 종류&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;선언 위치&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;생성 시기&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;클래스 변수&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 40px;&quot; rowspan=&quot;2&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;클래스 영역&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;클래스가 메모리에 올라갈 때&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;인스턴스 변수&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;인스턴스가 생성되었을 때&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 40px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 40px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;지역 변수&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 40px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;클래스 이외의 영역&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;(메서드, 생성자, 초기화 블럭 내부)&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 40px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;변수 선언문이 수행되었을 때&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;★ 인스턴스 변수&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- 클래스 영역에 선언되며, &lt;span style=&quot;background-color: #9feec3;&quot;&gt;인스턴스를 생성할 때 만들어진다.&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;인스턴스는 독립적인 저장공간을 가지므로&lt;span style=&quot;background-color: #9feec3;&quot;&gt; 서로 다른 값을 가질 수 있다.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;인스턴스 마다 고유한 상태를 유지해야하는 속성의 경우, 인스턴스 변수로 선언한다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;span&gt;★&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;클래스 변수&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- 선언하는 방법은 &lt;span style=&quot;background-color: #9feec3;&quot;&gt;static&lt;/span&gt;을 붙이기만 하면 된다.&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;클래스 변수는 모든 인스턴스가 공통된 저장공간(변수)을 공유햐게 된다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;인스턴스를 생성하지 않고도 언제라도 바로 사용할 수 있다.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;( 형태 : 클래스 이름. 클래스 변수)&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;span&gt;★&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;지역 변수&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;메서드 내에 선언되어 &lt;span style=&quot;background-color: #9feec3;&quot;&gt;메서드 내에서만 사용 가능&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;for 문 또는 while문의 블럭 내에 선언된 지역변수는 블럭&amp;nbsp; {&amp;nbsp; } 내에서만 사용 가능&lt;/span&gt;&lt;/b&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>
      <author>p퐝유p</author>
      <guid isPermaLink="true">https://nikeisme827.tistory.com/65</guid>
      <comments>https://nikeisme827.tistory.com/65#entry65comment</comments>
      <pubDate>Tue, 27 Dec 2022 23:27:58 +0900</pubDate>
    </item>
    <item>
      <title>[Java] 객체지향프로그래밍 / 클래스와 객체</title>
      <link>https://nikeisme827.tistory.com/64</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;background-color: #ffc1c8;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;★ 객체 지향 이론&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- 기본 개념은 ' 실제 세계는 사물(객체)로 이루어져 있으며, 발생하는 모든 사건들은 사물간의 상호작용이다.&quot;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;실제 세계를 컴퓨터 속에 옮겨 놓은 것과 같은 가상세계를 구현하고, 이 가상세계에서 모의실험을 함으로써 많은 시간과 비용을 절약할 수 있었다.&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; background-color: #ffc1c8;&quot;&gt;&lt;b&gt;★ 객체지향언어 특징&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;1. 코드의 재사용성이 높다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;2. 코드의 관리가 용이하다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;3.신뢰성이 높은 프로그래밍을 가능하게 한다.&lt;/b&gt;&lt;/span&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;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; background-color: #ffc1c8;&quot;&gt;&lt;b&gt;★ 클래스란?&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;- 클래스란 ' 객체를 정의해 놓은 것' 또는 ' 객체의 설계도 또는 틀' 이다.&lt;/b&gt;&lt;/span&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;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;클래스의 정의 : 클래스란 객체를 정해놓은 것&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;클래스의 용도 : 클래스는 객체를 생성하는데 사용&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; background-color: #ffc1c8;&quot;&gt;&lt;b&gt;★ 객체란?&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;- 객체란 ' 실제로 존재하는 것' 이다. 객체지향이론에서는 사물과 같은 유형적인 것 뿐 아니라. 개념이나 논리같은 무형적인 것도 포함된다.&lt;/b&gt;&lt;/span&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;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;객체의 정의 :&amp;nbsp; 실제로 존재하는 것. 사물 또는 개념&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;객체의 용도 : 객체가 가지고 있는 기능과 속성에 따라 다름&lt;/b&gt;&lt;/span&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;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;유형의 객체 : 책상,의자, 자동차, Tv 와 같은 사물&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;무형의 객체 : 수학공식, 프로그렘 에러와 같은 논리와 개념&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; background-color: #ffc1c8;&quot;&gt;&lt;b&gt;★ 객체와 인스턴스&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;인스턴스(instance) :&lt;/b&gt; &lt;b&gt;어떤 클래스로부터 만들어진 객체&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;인스턴스화 : 클래스로부터 객체를 만드는 과정&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; background-color: #ffc1c8;&quot;&gt;&lt;b&gt;★ 객체의 구성 요소 - 속성과 기능&lt;/b&gt;&lt;/span&gt;&lt;/h2&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;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;속성(property) : 멤버변수(member variable), 특성(attribute),&amp;nbsp; 필드(field), 상태(state)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;기능 (function) : 메서드(method) , 함수(function), 행위(behavior)&lt;/b&gt;&lt;/span&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;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;ex ) Tv의 속성과 기능&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Tv의 속성 : 크기, 길이, 높이, 색상, 볼륨, 채널&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Tv의 기능 : 켜기,끄기, 볼륨 높이기, 볼륨 낮추기, 채널 변경하기 등&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;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; background-color: #ffc1c8;&quot;&gt;&lt;b&gt;★ 프로그래밍 관점에서 클래스의 정의와 의미&lt;/b&gt;&lt;/span&gt;&lt;/h2&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;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;1. 클래스 - 데이터와 함수의 결합&lt;/b&gt;&lt;/span&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;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;* 변수 : 하나의 데이터를 저장할 수 있는 공간&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;* 배열 : 같은 종류의 여러 데이터를 하나의 집합으로 저장할 수 있는 공간&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;* 구조체 : 서로 관련된 여러 데이터를 종류에 관계없이 하나의 집합으로 저장할 수 있는 공간&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;* 클래스: 데이터와 함수의 결합 ( 구조체 + 함수 )&lt;/b&gt;&lt;/span&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;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;2. 클래스 - 사용자정의 타입(user-defined type)&lt;/b&gt;&lt;/span&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;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;* 프로그래머가 서로 관련된 변수들을 묶어서 하나의 타입으로 새로 추가하는 것을 사용자 정의 타입이라고 한다.&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;</description>
      <category>차곡차곡/Java</category>
      <author>p퐝유p</author>
      <guid isPermaLink="true">https://nikeisme827.tistory.com/64</guid>
      <comments>https://nikeisme827.tistory.com/64#entry64comment</comments>
      <pubDate>Thu, 22 Dec 2022 19:47:52 +0900</pubDate>
    </item>
    <item>
      <title>[Java] 형식화된 출력 - printf( )</title>
      <link>https://nikeisme827.tistory.com/63</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;★ printf ( ) 란?&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- &lt;span style=&quot;background-color: #9feec3;&quot;&gt;'지시자(specifier)'를 통해 변수의 값을 여러 가지 형식으로 변환하여 출력하는 기능&lt;/span&gt;을 가지고 있다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;'지시자'는 값을 어떻게 출력할 것인지를 지정해주는 역할을 한다.&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;정수형 변수에 저장된 값을 10진 정수로 출력할 때는 지시자 '%d'를 사용하며, &lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;변수의 값을 지정된 형식으로 변환해서 지시자 대신 넣는다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;예 ) int 타입의 변수 age의 값이 14일 때,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; printf ( ) 는 지시자 '%d' 대신 14를 넣어서 출력한다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;★ println( ) 과 printf ( ) 차이는 ?&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- 평소 화면에 출력할 때, println( )을 써왔는데 단점은 변수의 값을 그대로 출력하므로 값을 변환하지 않으면 다른 형식으로 출력할 수 없다. &lt;span style=&quot;background-color: #9feec3;&quot;&gt;같은 값이라도 다른 형식으로 출력하고 싶을 때, printf( ) 를 사용&lt;/span&gt;한다.&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;println( )과 달리 printf ( ) 는 출력 후 줄바꿈을 하지 않는다&lt;/span&gt;. &lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;줄바꿈을 하고 싶다면&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;지시자 ' %n '&lt;/span&gt;을 따로 넣어줘야한다.&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;예 ) 소수점 둘째자리까지만 출력하고 싶을 때, 정수를 16진수나 8진수를 출력하고 싶을 때&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1671696316583&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt; System.out.printf(&quot;age:%d&quot;, age); 
 System.out.printf(&quot;age:%d&quot;, 14);
 System.out.printf(&quot;age:14&quot;); // &quot;age : 14 &quot; 가 화면에 출력된다.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;만약 출력하는 값이 2개라면, 지시자도 2개를 사용해야하고, &lt;span style=&quot;background-color: #9feec3;&quot;&gt;출력될 값과 지시자의 순서는 일치&lt;/span&gt;해야한다. &lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;3개 이상의 값도 &lt;span style=&quot;background-color: #9feec3;&quot;&gt;지시자를 지정해서 출력할 수 있으며 개수 제한은 없다.&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1671696472013&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;System.out.printf(&quot;age:%d year:%d&quot;, age, year);
System.out.printf(&quot;age:%d year:%d&quot;, age, year,14,2017); 
// &quot;age:14 year:2017&quot; 이 화면에 출력된다.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 159px;&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: 18.721%; text-align: center; height: 21px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;지시자&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 81.2789%; text-align: center; height: 21px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;설명&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 18.721%; height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;%b&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 81.2789%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;불리언(boolean) 형식으로 출력&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 18.721%; height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;%d&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 81.2789%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;10진 (demical) 정수의 형식으로 출력&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 14px;&quot;&gt;
&lt;td style=&quot;width: 18.721%; height: 14px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;%o&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 81.2789%; height: 14px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;8진 (octal) 정수의 형식으로 출력&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 18.721%; height: 18px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;%x, %X&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 81.2789%; height: 18px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;16진(hexa - demical) 정수의 형식으로 출력&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 18.721%; height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;%f&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 81.2789%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;부동 소수점(floating - point)&amp;nbsp; 표현식의 형식으로 출력&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 18.721%; height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;%e,%E&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 81.2789%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;지수 ( exponent) 표현식의 형식으로 출력&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 18.721%; height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;%c&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 81.2789%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;문자 (character)로 출력&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;width: 18.721%; text-align: center; height: 21px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;%s&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 81.2789%; height: 21px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;문자열 (string) 로 출력&lt;/b&gt;&lt;/span&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;</description>
      <category>차곡차곡/Java</category>
      <author>p퐝유p</author>
      <guid isPermaLink="true">https://nikeisme827.tistory.com/63</guid>
      <comments>https://nikeisme827.tistory.com/63#entry63comment</comments>
      <pubDate>Thu, 22 Dec 2022 17:21:26 +0900</pubDate>
    </item>
    <item>
      <title>[기타] 자바 관련 문제 - 시험 복습</title>
      <link>https://nikeisme827.tistory.com/62</link>
      <description>&lt;blockquote data-ke-style=&quot;style2&quot;&gt;사전 질문 복습&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;얻는 게 많은 시험이었다. 기본을 정말 붕어빵 끝 부분처럼 빠싹하게 알고싶다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;1번 문제&lt;/span&gt;&lt;/b&gt;&lt;/blockquote&gt;
&lt;pre id=&quot;code_1670845256542&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;1. public class Score implements Comparable&amp;lt;Score&amp;gt; {
2.     private int point;
3.     public Score(int point) { this.point = point; }
4. // insert code here
5. }

Which method will complete this class?&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;A. public int compareTo(Object o){/*more code here*/}&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;B. public int compareTo(Score other){/*more code here*/}&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;C. public int compare(Score s1,Score s2){/*more code here*/}&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;D. public int compare(Object o1,Object o2){/*more code here*/}&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;답 : B&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;★ Comparable&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- 객체의 정렬 기준을 정의하는 방법 중 하나가 정렬 대상 클래스를 자바에서 기본적으로 제공하고 있는 Comparable 인터페이스를 구현하도록 하도록 변경하는 것이다. &lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;&quot;&gt;&lt;b&gt;Comparable 인터페이스의 comparableTo( ) 메서드를 통해 인자로 넘어온 같은 타입의 다른 객체와 대소 비교가 가능하다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;&quot;&gt;&lt;b&gt;출력하는 값&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;&quot;&gt;&lt;b&gt;Case 1. 메서드를 호출한 객체 &amp;lt; 인자로 넘어온 객체 : 음수&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;&quot;&gt;&lt;b&gt;Case 2. 메서드를 호출한 객체 = 인자로 넘어온 객체 : 0&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;&quot;&gt;&lt;b&gt;Case 3. 메서드를 호출한 객체 &amp;gt; 인자로 넘어온 객체 : 양수&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;★ Comparator&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span style=&quot;&quot;&gt;&lt;b&gt;- 정렬 대상 클래스의 코드를 직접 수정할 수 없는 경우거나 다른 정렬 기준으로 정렬하고 싶을 때 사용한다.&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;&quot;&gt;&lt;b&gt;Comparator인터페이스의 구현체를 Arrays.sort( )나 Collections.sort( ) 와 같은 정렬 메서드의 추가 인자로 넘기면 정렬 기준을 누락된 클래스의 객체나 기존 정렬을 무시하고, 새로운 정렬 기준으로 넘길 수 있다.&amp;nbsp;&lt;/b&gt;&lt;/span&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;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;2번 문제&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/blockquote&gt;
&lt;pre id=&quot;code_1670846250268&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt; class Atom {
      Atom() { System.out.print(&quot;atom &quot;); }
 }

   class Rock extends Atom {
       Rock(String type) { System.out.print(type); }
     }

 public class Mountain extends Rock {
     Mountain() {
         super(&quot;granite &quot;);
         new Rock(&quot;granite &quot;);
     }
     public static void main(String[] a) { new Mountain(); }
 }

What is the result?&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;
&lt;div&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;A. Compilation fails.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;B. atom granite&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;C. granite granite&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;D. atom granite granite&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;E. An exception is thrown at runtime.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;F. atom granite atom granite&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;답 : F&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;span style=&quot;&quot;&gt;&lt;b&gt;★ Super의 역할&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- 상속받은 부모 클래스의 변수명이나 클래스 변수를 참조&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- 부모 클래스 생성자를 호출한다.&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;3번 문제&lt;/span&gt;&lt;/b&gt;&lt;/blockquote&gt;
&lt;pre id=&quot;code_1670846796797&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Line {
     public class Point { public int x,y;}
     public Point getPoint() { return new Point(); }
}

class Triangle {
    public Triangle() {
       // insert code here
   }
 }

Which code, inserted at line 16, correctly retrieves a local instance of a Point object?&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;A. Point p = Line.getPoint();&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;B. Line.Point p = Line.getPoint();&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;C. Point p = (new Line()).getPoint();&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;D. Line.Point p = (new Line()).getPoint();&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;background-color: #9feec3; font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;★ 내부 클래스&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- 외부 클래스명.내부 클래스명 객체명 = new 외부클래스명.내부 클래스명();&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; 내부 클래스를 이용하는 이유는 '캡슐화' 때문.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; 예를 들어, A라는 클래스가 있는데 이 클래스에는 b라는 작업이 많이 사용된다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; 이럴 때, B라는 클래스를 만들어 놓으면 간단하게 사용할 수 있다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; 그런데 A 이외에 다른 클래스에 B라는 작업이 필요 없다면 B 클래스를 노출 시키고 싶지 않을 것이다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; 즉, 내부 구현을 감추고 싶을 때 내부 클래스를 사용하면 될 것이다.&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;4번 문제&lt;/span&gt;&lt;/b&gt;&lt;/blockquote&gt;
&lt;pre id=&quot;code_1670847687844&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;StringBuilder sb1 = new StringBuilder(&quot;123&quot;);
String s1 = &quot;123&quot;;
// insert code here
System.out.println(sb1 + &quot; &quot; + s1);

Which code fragment, inserted at line 24, outputs &quot;123abc 123abc&quot;?&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;
&lt;div&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;A. sb1.append(&quot;abc&quot;); s1.append(&quot;abc&quot;);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;B. sb1.append(&quot;abc&quot;); s1.concat(&quot;abc&quot;);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;C. sb1.concat(&quot;abc&quot;); s1.append(&quot;abc&quot;);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;D. sb1.concat(&quot;abc&quot;); s1.concat(&quot;abc&quot;);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;E. sb1.append(&quot;abc&quot;); s1 = s1.concat(&quot;abc&quot;);&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;F. sb1.concat(&quot;abc&quot;); s1 = s1.concat(&quot;abc&quot;);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;G. sb1.append(&quot;abc&quot;); s1 = s1 + s1.concat(&quot;abc&quot;);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;H. sb1.concat(&quot;abc&quot;); s1 = s1 + s1.concat(&quot;abc&quot;);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;background-color: #9feec3; font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;★ StringBuilder란?&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;StringBuilder는 문자열을 버퍼에 담아 그 안에서 추가,수정, 삭제 작업을 할 수 있도록 도와주는 클래스이다.&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;기존 String 변수에 새로운 값을 넣어서 수정할 수 도 있지만, 새로운 문자열로 변경될 경우,새로운 스트링 객체로 리턴된다. 그래서 StringBuilder를 이용하면 새로운 객체를 만들지 않고도 자유롭게 문자 변경 작업을 할 수 있는 것이 장점이다.&amp;nbsp;&lt;/span&gt;&lt;/b&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;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;답이 E인 이유는 StringBuilder에는 concat이 없고, String에는 append가 없다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;&quot;&gt;&lt;b&gt;Concat함수는 연결을 해주는 함수고 Append는 문자열 끝에 문자열을 추가하는 함수이다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;&quot;&gt;&lt;b&gt;칼럼이 같은 여러 개 데이터 프레임을 세로로 결합할 때, Concat과 Append를 많이 쓴다.&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;&quot;&gt;&lt;b&gt;append는 세로로만 결합할 수 있지만, concat은 가로,세로 모두 결합할 수 있다.&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;&quot;&gt;&lt;b&gt;concat함수가 더 빠르다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;5번 문제&lt;/span&gt;&lt;/b&gt;&lt;/blockquote&gt;
&lt;pre id=&quot;code_1670906861369&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;interface Animal { void makeNoise(); }

class Horse implements Animal {
     Long weight = 1200L;
     public void makeNoise() { System.out.println(&quot;whinny&quot;); }
 }

   public class Icelandic extends Horse {
       public void makeNoise() { System.out.println(&quot;vinny&quot;); }
	   public static void main(String[] args) {
       Icelandic i1 = new Icelandic();
       Icelandic i2 = new Icelandic();
       Icelandic i3 = new Icelandic();
       i3 = i1; i1 = i2; i2 = null; i3 = i1;
     }
        }

When line 15 is reached, how many objects are eligible for the garbage collector?&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;A. 0&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;B. 1&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;C. 2&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;D. 3&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;E. 4&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;F. 6&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;background-color: #9feec3; font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;★ garbage collector란?&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- 프로그램을 개발할 때 유효하지 않은 메모리인 garbage가 발생하게 된다. Java는 개발자가 메모리를 직접 해지해 주는 일이 없다. 그 이유는 garbage collector 가 메모리를 알아서 정리해주기 때문이다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;i1=A,&amp;nbsp;i2=B&amp;nbsp;and&amp;nbsp;i3=C;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #232629;&quot;&gt;After&amp;nbsp;&lt;/span&gt;i3 = i1&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;i1=A,&amp;nbsp;i2=B&amp;nbsp;and&amp;nbsp;i3=A&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;After&amp;nbsp;i1 = i2&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;i1=B,&amp;nbsp;i2=B&amp;nbsp;and&amp;nbsp;i3=A;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;After&amp;nbsp;i2 = null:&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;i1=B,&amp;nbsp;i2=null&amp;nbsp;and&amp;nbsp;i3=A;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;After&amp;nbsp;i3 = i1&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;i1=B,&amp;nbsp;i2=null&amp;nbsp;and&amp;nbsp;i3=B&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;총 4개&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;5번 문제&lt;/span&gt;&lt;/b&gt;&lt;/blockquote&gt;
&lt;pre id=&quot;code_1670907633211&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class Pass {
     public static void main(String [] args) {
        	int x = 5;
        	Pass p = new Pass();
         p.doStuff(x);
         System.out.print(&quot; main x = &quot; + x);
     }

     void doStuff(int x) {
         System.out.print(&quot; doStuff x = &quot; + x++);
     }
 }

What is the result?&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;
&lt;div&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;A. Compilation fails.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;B. An exception is thrown at runtime.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;C. doStuff x = 6 main x = 6&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;D. doStuff x = 5 main x = 5&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;E. doStuff x = 5 main x = 6&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;F. doStuff x = 6 main x = 5&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;background-color: #9feec3; font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;★ 인스턴스 변수 / 지역 변수&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;인스턴스 변수 : 클래스 내에서 선언된 것&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;메소드 내에서 선언한 것은 인스턴스 변수에 포함되지 않는다. 인스턴스 변수는 그 변수가 속한 객체 안에서 존재.&lt;/span&gt;&lt;/b&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;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;지역 변수 : 메소드 내에서 선언된 것&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;메소드 매개변수도 지역변수에 포함, 지역 변수는 임시 메소드가 스택에 들어 있는 동안만 살아 있다.&lt;/span&gt;&lt;/b&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;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;'인스턴스 변수'는 클래스 내에서 선언되고, &lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;'지역 변수' 는 메소드 내에서 선언&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;지역변수는 사용하기 전, 반드시 초기화해야한다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;기본 값이 없어서 초기화 하기 전, 사용하려고 하면 반드시 컴파일 과정에서 오류가 난다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;6번 문제&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #99cefa;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Serif KR';&quot;&gt;Which Man class properly represents the relationship &amp;ldquo;Man has a best friend who is a Dog&amp;rdquo;?&lt;/span&gt;&lt;/b&gt;&lt;/span&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;background-color: #ffffff; color: #000000;&quot;&gt;A. class Man extends Dog { }&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;B. class Man implements Dog { }&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;C. class Man { private BestFriend dog; }&lt;/span&gt;&lt;br /&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;D. class Man { private Dog bestFriend; }&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;E. class Man { private Dog&amp;lt;bestFriend&amp;gt; }&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;F. class Man { private BestFriend&amp;lt;dog&amp;gt; }&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;background-color: #9feec3; font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;★인터페이스 정의와 구현&lt;/b&gt;&lt;/span&gt;&lt;/h2&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;background-color: #ffffff; color: #000000; font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp;public interface Pet {...} // 정의&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; public class Dog extends Canine implements Pet {...} // 구현&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;7번 문제&lt;/span&gt;&lt;/b&gt;&lt;/blockquote&gt;
&lt;pre id=&quot;code_1670908421340&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt; class Animal { public String noise() { return &quot;peep&quot;; } }

12. class Dog extends Animal {
13.     public String noise() { return &quot;bark&quot;; }
14. }

15. class Cat extends Animal {
16.     public String noise() { return &quot;meow&quot;; }
17. } ...

30. Animal animal = new Dog();
31. Cat cat = (Cat)animal;
32. System.out.println(cat.noise());

What is the result?&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;
&lt;div&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;A. peep&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;B. bark&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;C. meow&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;D. Compilation fails&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;E. An exception is thrown at runtime.&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Cat 자료형이 메모리에 올라간 적이 없다.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;형변환 에러는 런타임시에 발생&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;8번 문제&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;pre id=&quot;code_1670908751011&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt; public class KungFu {
2.       public static void main(String[] args) {
3.           Integer x = 400;
4.           Integer y = x;
5.           x++;
6.           StringBuilder sb1 = new StringBuilder(&quot;123&quot;);
7.           StringBuilder sb2 = sb1;
8.           sb1.append(&quot;5&quot;);
9.           System.out.println((x==y) + &quot; &quot; + (sb1==sb2));
10.     }
11. }&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;
&lt;div&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;A. true true&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;B. false true&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;C. true false&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;D. false false&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;E. Compilation fails.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;F. An exception is thrown at runtime.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;9번 문제&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;pre id=&quot;code_1670908921102&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;1.   public class GC {
2.       private Object o;
3.       private void doSomethingElse(Object obj) { o = obj; }
4.       public void doSomething() {
5.           Object o = new Object();
6.           doSomethingElse(o);
7.           o = new Object();
8.           doSomethingElse(null);
9.           o = null;
10.     }
11. }

When the doSomething method is called, after which line does the Object created in line 5 become available for garbage collection?&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;
&lt;div&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;A. Line 5&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;B. Line 6&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;C. Line 7&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;D. Line 8&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;E. Line 9&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;F. Line 10&lt;/span&gt;&lt;/span&gt;&lt;/div&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;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;dosomethingElse(null);메소드를 호출하면서 null을 파라미터로 넘긴다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;그러면서 오브젝트 o가 null 값을 가지게 된다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;10번 문제&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1670910862053&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt; public class HeapObject implements Serializable , Cloneable {
       private final String name;
       public HeapObject(String name) {
           this. name = name;
       }

       @Override
       protected HeapObject clone() throws CloneNotSupportedException {
           return (HeapObject)super.clone();
       }

     public static void main(String[] args) throws CloneNotSupportedException, IOException, ClassNotFoundException {
         HeapObject t1 = new HeapObject(&quot;test&quot;);
         HeapObject t2 = t1.clone();
         HeapObject t3 = serializeAndDeserialize(t1);
         HeapObject t4 = t1;
     }

     private static HeapObject serializeAndDeserialize(HeapObject t1) throws IOException, ClassNotFoundException {
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         ObjectOutputStream oos = new ObjectOutputStream(baos);
         oos.writeObject(t1);
         ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()));
         return (HeapObject)ois.readObject();
     }
}

line 15에서 heap에 존재하는 HeapObject의 instance 수는?&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;
&lt;div&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;A. 1&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;B. 2&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;C. 3&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;D. 4&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;background-color: #9feec3; font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;★ clone 메서드&lt;/b&gt;&lt;/span&gt;&lt;/h2&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;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;Java의 최상위 클래스인 Object에는 객체를 복제하는 clone 메서드가 존재한다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;이 메서드의 역할은 기존 객체의 데이터를 보존하기 위해서이다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;Java의 모든 클래스에는 Object에서 파생되기 때문에 모든 클래스의 인스턴스는 clone( )을 사용할 수 있다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;&quot;&gt;&lt;b&gt;clone 메서드를 호출하려면 해당 객체의 클래스가 Cloneable 인터페이스를 구현해야한다.&lt;/b&gt;&lt;/span&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;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;11번 문제&lt;/span&gt;&lt;/b&gt;&lt;/b&gt;
&lt;pre id=&quot;code_1670911201663&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class MonitorCount {
	public static synchronized void foo1() {};
    public synchronized void foo2() {}
      public void foo3() {
         synchronized (this) {
         }
     }
           synchronized (getClass()) {
          }
     }
     public void foo5() {
         synchronized (new Object()) {
         }
     }
     public void foo6() {
         synchronized (new Object()) {
         }
     }
 }&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>차곡차곡/Java</category>
      <author>p퐝유p</author>
      <guid isPermaLink="true">https://nikeisme827.tistory.com/62</guid>
      <comments>https://nikeisme827.tistory.com/62#entry62comment</comments>
      <pubDate>Tue, 13 Dec 2022 15:13:01 +0900</pubDate>
    </item>
    <item>
      <title>[Java] 알고리즘 대소문자 변환</title>
      <link>https://nikeisme827.tistory.com/61</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; background-color: #9feec3;&quot;&gt;&lt;b&gt;★ StuDY&amp;nbsp; 에서 sTUdy 로 변경해보자.&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1670684676998&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Main {
    public String solution(String str){
        String answer=&quot;&quot;;

        for(char x : str.toCharArray()){
            if(x == Character.isLowerCase()) answer +=Character.toUpperCase(x);

            else answer += Character.toLowerCase(x);
        }
        return answer;
    }

    public static void main(String[] args){
        Main T = new Main();
        Scanner kb = new Scanner(System.in);
        String str=kb.next();
        System.out.println(T.solution(str));
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #9feec3; font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;★ Str.toCharArray( )&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;-&amp;nbsp; 문자열을 한글자씩 분리해서 char타입의&amp;nbsp; 배열에 넣어주는 메소드&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;-&amp;nbsp; char형 배열을 합쳐서 하나의 String(문자열)로 만들 수 있다.&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1670684917355&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;String s2 = new String (charArr);&lt;/code&gt;&lt;/pre&gt;</description>
      <category>차곡차곡/Algorithms</category>
      <author>p퐝유p</author>
      <guid isPermaLink="true">https://nikeisme827.tistory.com/61</guid>
      <comments>https://nikeisme827.tistory.com/61#entry61comment</comments>
      <pubDate>Sun, 11 Dec 2022 00:09:49 +0900</pubDate>
    </item>
    <item>
      <title>[JAVA] 프로그래머스 - 문자열 반복 출력</title>
      <link>https://nikeisme827.tistory.com/60</link>
      <description>&lt;figure id=&quot;og_1669120816970&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;프로그래머스&quot; data-og-description=&quot;코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.&quot; data-og-host=&quot;programmers.co.kr&quot; data-og-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/120825&quot; data-og-url=&quot;https://programmers.co.kr/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/GtH8U/hyQE3dIyQR/37fg2L8VzUL3UmXoqOT4NK/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/bsL9Dn/hyQE7HbfX3/fxsiNsnZwRqiNtGoWebF6K/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/120825&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/120825&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/GtH8U/hyQE3dIyQR/37fg2L8VzUL3UmXoqOT4NK/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/bsL9Dn/hyQE7HbfX3/fxsiNsnZwRqiNtGoWebF6K/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;프로그래머스&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;programmers.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;575&quot; data-origin-height=&quot;370&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bMesAQ/btrRSQSbUNm/SXWzDRp1h7zlxOLAZEWVPK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bMesAQ/btrRSQSbUNm/SXWzDRp1h7zlxOLAZEWVPK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bMesAQ/btrRSQSbUNm/SXWzDRp1h7zlxOLAZEWVPK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbMesAQ%2FbtrRSQSbUNm%2FSXWzDRp1h7zlxOLAZEWVPK%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;575&quot; height=&quot;370&quot; data-origin-width=&quot;575&quot; data-origin-height=&quot;370&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>차곡차곡/Algorithms</category>
      <author>p퐝유p</author>
      <guid isPermaLink="true">https://nikeisme827.tistory.com/60</guid>
      <comments>https://nikeisme827.tistory.com/60#entry60comment</comments>
      <pubDate>Tue, 22 Nov 2022 21:40:39 +0900</pubDate>
    </item>
    <item>
      <title>[JAVA] 프로그래머스 가위바위보</title>
      <link>https://nikeisme827.tistory.com/59</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1669119750469&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;프로그래머스&quot; data-og-description=&quot;코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.&quot; data-og-host=&quot;programmers.co.kr&quot; data-og-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/120839&quot; data-og-url=&quot;https://programmers.co.kr/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/eDj2O/hyQE71sMca/8K872nThRI5venB7FiE7b0/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/cE6wYd/hyQE0gXOID/X4FUD2vC1FPB19fJgzWdU1/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/120839&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/120839&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/eDj2O/hyQE71sMca/8K872nThRI5venB7FiE7b0/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/cE6wYd/hyQE0gXOID/X4FUD2vC1FPB19fJgzWdU1/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;프로그래머스&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;programmers.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;533&quot; data-origin-height=&quot;416&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/byvbum/btrRPBIVix9/LRO52pmOhmkv9o2UsiZkPk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/byvbum/btrRPBIVix9/LRO52pmOhmkv9o2UsiZkPk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/byvbum/btrRPBIVix9/LRO52pmOhmkv9o2UsiZkPk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbyvbum%2FbtrRPBIVix9%2FLRO52pmOhmkv9o2UsiZkPk%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;533&quot; height=&quot;416&quot; data-origin-width=&quot;533&quot; data-origin-height=&quot;416&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 id=&quot;charati&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; background-color: #9feec3;&quot;&gt;charAt(i) 함수란?&lt;/span&gt;&lt;/b&gt;&lt;/h3&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;background-color: #ffffff; color: #212529; font-family: 'Noto Serif KR';&quot;&gt;String 타입의 데이터(문자열) 타입인 문자 ▶ char 타입으로 변환할 때 사용하는 함수&lt;/span&gt;&lt;/p&gt;</description>
      <category>차곡차곡/Algorithms</category>
      <author>p퐝유p</author>
      <guid isPermaLink="true">https://nikeisme827.tistory.com/59</guid>
      <comments>https://nikeisme827.tistory.com/59#entry59comment</comments>
      <pubDate>Tue, 22 Nov 2022 21:24:40 +0900</pubDate>
    </item>
    <item>
      <title>[JAVA] 프로그래머스 삼각형의 완성조건(1)</title>
      <link>https://nikeisme827.tistory.com/58</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1669117941475&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;프로그래머스&quot; data-og-description=&quot;코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.&quot; data-og-host=&quot;programmers.co.kr&quot; data-og-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/120889&quot; data-og-url=&quot;https://programmers.co.kr/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/WGP4e/hyQFdUSmYw/YJbX4n5hyXNpWKTGWOtuNK/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/n9R1g/hyQE3kqznC/Z50WknvbczJW39IjdMHyOK/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/120889&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/120889&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/WGP4e/hyQFdUSmYw/YJbX4n5hyXNpWKTGWOtuNK/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/n9R1g/hyQE3kqznC/Z50WknvbczJW39IjdMHyOK/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;프로그래머스&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;programmers.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;575&quot; data-origin-height=&quot;318&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MHVjN/btrRRCN3YOD/O8KuZbuot2sN2w9BoJjaPk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MHVjN/btrRRCN3YOD/O8KuZbuot2sN2w9BoJjaPk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MHVjN/btrRRCN3YOD/O8KuZbuot2sN2w9BoJjaPk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMHVjN%2FbtrRRCN3YOD%2FO8KuZbuot2sN2w9BoJjaPk%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;575&quot; height=&quot;318&quot; data-origin-width=&quot;575&quot; data-origin-height=&quot;318&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;</description>
      <category>차곡차곡/Algorithms</category>
      <author>p퐝유p</author>
      <guid isPermaLink="true">https://nikeisme827.tistory.com/58</guid>
      <comments>https://nikeisme827.tistory.com/58#entry58comment</comments>
      <pubDate>Tue, 22 Nov 2022 20:58:27 +0900</pubDate>
    </item>
    <item>
      <title>[Java] 신고 결과 받기 _ 프로그래머스 코딩 테스트 문제_문자열,해시</title>
      <link>https://nikeisme827.tistory.com/57</link>
      <description>&lt;figure id=&quot;og_1668087901929&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;프로그래머스&quot; data-og-description=&quot;코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.&quot; data-og-host=&quot;programmers.co.kr&quot; data-og-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/92334&quot; data-og-url=&quot;https://programmers.co.kr/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/noan7/hyQwz5kNKx/aOL4he2V69EjeF7ZIcXgk1/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/coYzug/hyQxFCPSky/3dgXTpGDiMlfzRzgU33JSk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/92334&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/92334&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/noan7/hyQwz5kNKx/aOL4he2V69EjeF7ZIcXgk1/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/coYzug/hyQxFCPSky/3dgXTpGDiMlfzRzgU33JSk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;프로그래머스&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;programmers.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;전체 코드&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1668089737170&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.util.*;

class KaKaoReport {
    public int[] solution(String[] id_list, String[] report, int k) {

        int[] answer = new int[id_list.length];

        // 1. 중복제거
        HashSet&amp;lt;String&amp;gt; reportSet = new HashSet&amp;lt;String&amp;gt;();
        for (String rep : report) reportSet.add(rep);

        // 2. report에서 각 사람이 신고 당한 횟수를 counthash로 정의하기
        HashMap&amp;lt;String,ArrayList&amp;lt;String&amp;gt;&amp;gt; notifyListHash = new HashMap&amp;lt;&amp;gt;();

        for(String rep :reportSet) {
            int blankIdx = rep.indexOf(&quot; &quot;);
            String reporter = rep.substring(0,blankIdx);
            String reportee = rep.substring(blankIdx+1);

            ArrayList&amp;lt;String&amp;gt; reporterList = notifyListHash.getOrDefault(reportee,null);
            if(reporterList==null) reporterList = new ArrayList&amp;lt;&amp;gt;();

            reporterList.add(reporter);
            notifyListHash.put(reportee,reporterList);
        }

        // 3.notifyListHash를 기반으로 reportHash 만들기
        HashMap&amp;lt;String,Integer&amp;gt; reporterHash = new HashMap&amp;lt;&amp;gt;();

        for (ArrayList&amp;lt;String&amp;gt;notifyList : notifyListHash.values())
            if(notifyList.size()&amp;gt;=k)
                for(String reporter : notifyList)
                    reporterHash.put(reporter,reporterHash.getOrDefault(reporter,0)+1);

        // 4. reporterHash 정보를 answer에 옮겨담기
        for (int i=0; i&amp;lt;id_list.length; i++)
            answer[i] = reporterHash.getOrDefault(id_list[i],0);

        return answer;
    }

    public static void main(String[] args){
        KaKaoReport sol = new KaKaoReport();
        String[] id_list = {&quot;muzi&quot;, &quot;frodo&quot;, &quot;apeach&quot;, &quot;neo&quot;};
        String[] report = {&quot;muzi frodo&quot;,&quot;apeach frodo&quot;,&quot;frodo neo&quot;,&quot;muzi neo&quot;,&quot;apeach muzi&quot;};
        int k = 2;
        // String[] id_list = {&quot;con&quot;, &quot;ryan&quot;};
        // String[] report = {&quot;ryan con&quot;, &quot;ryan con&quot;, &quot;ryan con&quot;, &quot;ryan con&quot;};
        // int k = 3;
        sol.solution(id_list, report, k);
    }


}

// 1. [&quot;muzi&quot;, &quot;frodo&quot;, &quot;apeach&quot;, &quot;neo&quot;] 4명의 사용자 정보가 주어짐

// 2. 중복을 제거해야한다.

// Why? 무지가 프로도를 여러번 신고 가능하나 딱 한번만 인정된다. 앞단에서 전처리로 끝내버리면 훨씬 수월하다.
// HashSet으로 옮기는 순간 중복 제거된다.

// 3. 신고자 목록을 관리
// - NotifyListHash key : 신고 당한 사람(String) / value : 신고 한사람 (ArrayList)
// 이것이 몇번 신고 당했는지 횟수를 알 수 있음. k 이상이면 ArrayList에 있는 사람에게 신고 결과를 알려주면 됨

// 4. 신고 결과를 알려주기 위한 reporterHash
// 신고를 한 사람이 결과를 몇 번 받았느냐 알려줄 수 있음. (  k이상일 때만 신고 결과 알려줄 수 있음)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;1. report를 hashSet을 이용하여 중복 제거한다.&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&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;553&quot; data-origin-height=&quot;199&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/81F8O/btrQSYZjHRK/dAd9qgaJe2r5UojJ4vj7hk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/81F8O/btrQSYZjHRK/dAd9qgaJe2r5UojJ4vj7hk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/81F8O/btrQSYZjHRK/dAd9qgaJe2r5UojJ4vj7hk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F81F8O%2FbtrQSYZjHRK%2FdAd9qgaJe2r5UojJ4vj7hk%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;553&quot; height=&quot;199&quot; data-origin-width=&quot;553&quot; data-origin-height=&quot;199&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;721&quot; data-origin-height=&quot;65&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HLYsz/btrQUu3Uhmf/yVDKwpx61IcyFcE7A7kLA0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HLYsz/btrQUu3Uhmf/yVDKwpx61IcyFcE7A7kLA0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HLYsz/btrQUu3Uhmf/yVDKwpx61IcyFcE7A7kLA0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHLYsz%2FbtrQUu3Uhmf%2FyVDKwpx61IcyFcE7A7kLA0%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;65&quot; data-origin-width=&quot;721&quot; data-origin-height=&quot;65&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;테스트 케이스 2 결과가&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;114&quot; data-origin-height=&quot;35&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/N4X2z/btrQUACUs9S/4fpPkwZVqIPXPIcjQ6rG81/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/N4X2z/btrQUACUs9S/4fpPkwZVqIPXPIcjQ6rG81/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/N4X2z/btrQUACUs9S/4fpPkwZVqIPXPIcjQ6rG81/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FN4X2z%2FbtrQUACUs9S%2F4fpPkwZVqIPXPIcjQ6rG81%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;114&quot; height=&quot;35&quot; data-origin-width=&quot;114&quot; data-origin-height=&quot;35&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;이렇게 하나로 나온다.&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;2.&amp;nbsp; report에서 각 사람이 신고 당한 횟수를 countHash로 정한다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&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;684&quot; data-origin-height=&quot;333&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ZJqTc/btrQTD1y7ha/K40rAqg2LXUahBRzLBc0w0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ZJqTc/btrQTD1y7ha/K40rAqg2LXUahBRzLBc0w0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ZJqTc/btrQTD1y7ha/K40rAqg2LXUahBRzLBc0w0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZJqTc%2FbtrQTD1y7ha%2FK40rAqg2LXUahBRzLBc0w0%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;684&quot; height=&quot;333&quot; data-origin-width=&quot;684&quot; data-origin-height=&quot;333&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;신고한 사람을 reporter / 신고 당한 사람을 reportee로&amp;nbsp; 구분하였다.&amp;nbsp;&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;618&quot; data-origin-height=&quot;179&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/XWqwL/btrQUCgqy2T/P189dj85A67DtiK0wVORdk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/XWqwL/btrQUCgqy2T/P189dj85A67DtiK0wVORdk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/XWqwL/btrQUCgqy2T/P189dj85A67DtiK0wVORdk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXWqwL%2FbtrQUCgqy2T%2FP189dj85A67DtiK0wVORdk%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;179&quot; data-origin-width=&quot;618&quot; data-origin-height=&quot;179&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;reporter만 출력&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&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;621&quot; data-origin-height=&quot;180&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/AoCHM/btrQTph5Ytb/k1AkhOhnlKSiW7rkzCXXZ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/AoCHM/btrQTph5Ytb/k1AkhOhnlKSiW7rkzCXXZ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/AoCHM/btrQTph5Ytb/k1AkhOhnlKSiW7rkzCXXZ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAoCHM%2FbtrQTph5Ytb%2Fk1AkhOhnlKSiW7rkzCXXZ1%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;180&quot; data-origin-width=&quot;621&quot; data-origin-height=&quot;180&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;reportee만 출력&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;3. notiftListHash를 기반으로 reportHash 만들기&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&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;946&quot; data-origin-height=&quot;229&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b3m5Uo/btrQVajHFOf/wCVuZsZWhKApG8hcoTqda1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b3m5Uo/btrQVajHFOf/wCVuZsZWhKApG8hcoTqda1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b3m5Uo/btrQVajHFOf/wCVuZsZWhKApG8hcoTqda1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb3m5Uo%2FbtrQVajHFOf%2FwCVuZsZWhKApG8hcoTqda1%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;946&quot; height=&quot;229&quot; data-origin-width=&quot;946&quot; data-origin-height=&quot;229&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&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;921&quot; data-origin-height=&quot;122&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/X0Ztb/btrQU9d1slP/YVCIMINsZu9qNmvOxcyYGK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/X0Ztb/btrQU9d1slP/YVCIMINsZu9qNmvOxcyYGK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/X0Ztb/btrQU9d1slP/YVCIMINsZu9qNmvOxcyYGK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FX0Ztb%2FbtrQU9d1slP%2FYVCIMINsZu9qNmvOxcyYGK%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;921&quot; height=&quot;122&quot; data-origin-width=&quot;921&quot; data-origin-height=&quot;122&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;4. reporterHash 정보를 answer에 옮겨담는다.&amp;nbsp;&lt;/span&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;734&quot; data-origin-height=&quot;158&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/OM75L/btrQUVAaS55/za4DVrSOHNmDIZRfNPhNAK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/OM75L/btrQUVAaS55/za4DVrSOHNmDIZRfNPhNAK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/OM75L/btrQUVAaS55/za4DVrSOHNmDIZRfNPhNAK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOM75L%2FbtrQUVAaS55%2Fza4DVrSOHNmDIZRfNPhNAK%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;158&quot; data-origin-width=&quot;734&quot; data-origin-height=&quot;158&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;그럼 이렇게 담겨져 테스트에 통과하게 된다.&amp;nbsp;&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;1088&quot; data-origin-height=&quot;213&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/PXR79/btrQTGDTIoJ/k6EBA9QlZZQBbkLc8lweg1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/PXR79/btrQTGDTIoJ/k6EBA9QlZZQBbkLc8lweg1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/PXR79/btrQTGDTIoJ/k6EBA9QlZZQBbkLc8lweg1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPXR79%2FbtrQTGDTIoJ%2Fk6EBA9QlZZQBbkLc8lweg1%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;1088&quot; height=&quot;213&quot; data-origin-width=&quot;1088&quot; data-origin-height=&quot;213&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;★ 알게된 것&lt;/b&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;getOrDefault(&lt;/b&gt;&lt;span style=&quot;background-color: #fcfcfc; color: #666666;&quot;&gt;Object&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #666666;&quot;&gt;key,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #fcfcfc; color: #666666;&quot;&gt;V DefaultValue&lt;/span&gt;&lt;b&gt;)&lt;/b&gt;&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;key :&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;값을 가져와야 하는 요소의&amp;nbsp;&lt;b&gt;키&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;defaultValue :&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;지정된 키로 매핑된 값이 없는 경우 반환되어야&lt;span&gt;&amp;nbsp;&lt;/span&gt;하는&lt;span&gt;&amp;nbsp;&lt;b&gt;기본값&lt;/b&gt;&lt;/span&gt;&lt;span&gt;&lt;b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;★ 참고 자료&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;figure data-ke-type=&quot;video&quot; data-ke-style=&quot;alignCenter&quot; data-video-host=&quot;youtube&quot; data-video-url=&quot;https://www.youtube.com/watch?v=ncCUNOJUn9Q&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/bmENU1/hyQwzdaVND/AdQBF3tWHWyc8IQK7kMDH0/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/ncCUNOJUn9Q&quot; width=&quot;860&quot; height=&quot;484&quot; frameborder=&quot;&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;
&lt;figcaption&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>차곡차곡/Algorithms</category>
      <author>p퐝유p</author>
      <guid isPermaLink="true">https://nikeisme827.tistory.com/57</guid>
      <comments>https://nikeisme827.tistory.com/57#entry57comment</comments>
      <pubDate>Thu, 10 Nov 2022 23:19:36 +0900</pubDate>
    </item>
    <item>
      <title>[Java] 신규 아이디 추천 - 프로그래머스 코딩테스트 문제_정규식 표현</title>
      <link>https://nikeisme827.tistory.com/56</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;[문제]&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;신규 유저가 입력한 아이디를 나타내는 new_id가 매개변수로 주어질 때, &quot;네오&quot;가 설계한 7단계의 처리 과정을 거친 후의 추천 아이디를 return 하도록 solution 함수를 완성해 주세요.&lt;/span&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;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;[제한사항]&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;new_id는 길이 1 이상 1,000 이하인 문자열입니다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;new_id는 알파벳 대문자, 알파벳 소문자, 숫자, 특수문자로 구성되어 있습니다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;new_id에 나타날 수 있는 특수문자는&amp;nbsp;-_.~!@#$%^&amp;amp;*()=+[{]}:?,&amp;lt;&amp;gt;/&amp;nbsp;로 한정됩니다.&lt;/span&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;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;[입출력 예]&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;no&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;new_id&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;result&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;예1&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&quot;...!@BaT#*..y.abcdefghijklm&quot;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&quot;bat.y.abcdefghi&quot;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;예2&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&quot;z-+.^.&quot;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&quot;z-+.^.&quot;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;예3&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&quot;=.=&quot;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&quot;aaa&quot;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;예4&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&quot;123_.def&quot;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&quot;123_.def&quot;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;예5&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&quot;abcdefghijklmn.p&quot;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&quot;abcdefghijklmn&quot;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;background-color: #ffc1c8; font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;★ 주요 정규식 표현&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;- 정규표현식의 기본형태 :&amp;nbsp; &lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;String.replaceAll('From', 'To')&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 85px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;[ ]&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 17px; text-align: center;&quot;&gt;or : 대괄호의 모든 문자&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;[^]&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 17px; text-align: center;&quot;&gt;not : 대괄호 안의 문자 외의 모든 문자&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;^[ ]&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 17px; text-align: center;&quot;&gt;대괄호 안의 문자로 시작하는 문자열&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;[ ]$&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 17px; text-align: center;&quot;&gt;대괄호 안의 문자로 끝나는 문자열&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;+&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 17px; text-align: center;&quot;&gt;1개 이상의 문자&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;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- 단계별 정규 표현식 적용&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 145px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 8.91471%; height: 20px; text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;1단계&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 36.5891%; height: 20px; text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;소문자로 치환&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 54.4961%; height: 20px; text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;toLowerCase()&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 8.91471%; height: 20px; text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;2단계&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 36.5891%; height: 20px; text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;소문자,숫자,빼기(-),밑줄(_),마침표(.)&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 54.4961%; height: 20px; text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;[^a-z0-9\-_.]&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 8.91471%; height: 20px; text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;3단계&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 36.5891%; height: 20px; text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;마침표(.)가 2번 이상&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 54.4961%; height: 20px; text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;\.+&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 8.91471%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;4단계&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 36.5891%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;마침표(.)가 처음이나 끝에 위치하면 제거&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 54.4961%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;^[.]|[.]$&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 8.91471%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;5단계&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 36.5891%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;빈 문자열이라면, new_id에 &quot;a&quot; 대입&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 54.4961%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;isEmpty&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 8.91471%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;6-1단계&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 36.5891%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;길이가 16자 이상&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 54.4961%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;substring&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 8.91471%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;6-2단계&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 36.5891%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;마침표(.)가 new_id의 끝에 위치한다면&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 54.4961%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;[.]$&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 8.91471%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;7단계&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 36.5891%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;길이가 2자 이하&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 54.4961%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;while&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;pre id=&quot;code_1668008081505&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class IdRecommend2 {

    public String solution(String new_id) {
        // 1
        String answer = new_id.toLowerCase();
        // 2
        answer = answer.replaceAll(&quot;[^-_.a-z0-9]&quot;, &quot;&quot;);
        // 3
        answer = answer.replaceAll(&quot;\\.+&quot;, &quot;.&quot;);
        // 4
        answer = answer.replaceAll(&quot;^[.]|[.]$&quot;, &quot;&quot;);
        // 5
        if (answer.equals(&quot;&quot;))
            answer = &quot;a&quot;;
        // 6
        if (answer.length() &amp;gt; 15) {
            answer = answer.substring(0, 15);
            answer = answer.replaceAll(&quot;[.]$&quot;, &quot;&quot;);
        }
        // 7
        while (answer.length() &amp;lt; 3)
            answer += answer.charAt(answer.length() - 1);

        return answer;
    }


    public static void main(String[] args) {
        IdRecommend sol = new IdRecommend();
        System.out.print(sol.solution(&quot;...!@BaT#*..y.abcdefghijklm&quot;));
    }


}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>차곡차곡/Algorithms</category>
      <author>p퐝유p</author>
      <guid isPermaLink="true">https://nikeisme827.tistory.com/56</guid>
      <comments>https://nikeisme827.tistory.com/56#entry56comment</comments>
      <pubDate>Thu, 10 Nov 2022 00:35:57 +0900</pubDate>
    </item>
    <item>
      <title>[Java] 신규 아이디 추천 - 프로그래머스 코딩테스트 문제(1)</title>
      <link>https://nikeisme827.tistory.com/55</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1667983137964&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;프로그래머스&quot; data-og-description=&quot;코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.&quot; data-og-host=&quot;programmers.co.kr&quot; data-og-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/72410&quot; data-og-url=&quot;https://programmers.co.kr/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/OEXmx/hyQwNgXbr5/nEBCQq5wQZfjPiMJWigqpK/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/sqQG8/hyQvhjGQ28/Ka9EM6t5I5ZlpdOyS7KtdK/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/72410&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/72410&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/OEXmx/hyQwNgXbr5/nEBCQq5wQZfjPiMJWigqpK/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/sqQG8/hyQvhjGQ28/Ka9EM6t5I5ZlpdOyS7KtdK/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;프로그래머스&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;programmers.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;[&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;문제]&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;신규 유저가 입력한 아이디를 나타내는 new_id가 매개변수로 주어질 때, &quot;네오&quot;가 설계한 7단계의 처리 과정을 거친 후의 추천 아이디를 return 하도록 solution 함수를 완성해 주세요.&lt;/span&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;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;[제한사항]&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;new_id는 길이 1 이상 1,000 이하인 문자열입니다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;new_id는 알파벳 대문자, 알파벳 소문자, 숫자, 특수문자로 구성되어 있습니다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;new_id에 나타날 수 있는 특수문자는&amp;nbsp;-_.~!@#$%^&amp;amp;*()=+[{]}:?,&amp;lt;&amp;gt;/&amp;nbsp;로 한정됩니다.&lt;/span&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;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;[입출력 예]&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 116px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;&lt;b&gt;no&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;&lt;b&gt;new_id&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;&lt;b&gt;result&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;&lt;b&gt;예1&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&quot;...!@BaT#*..y.abcdefghijklm&quot;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&quot;bat.y.abcdefghi&quot;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;&lt;b&gt;예2&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&quot;z-+.^.&quot;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&quot;z-+.^.&quot;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;&lt;b&gt;예3&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&quot;=.=&quot;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&quot;aaa&quot;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;&lt;b&gt;예4&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&quot;123_.def&quot;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&quot;123_.def&quot;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 19px;&quot;&gt;&lt;b&gt;예5&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 19px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&quot;abcdefghijklmn.p&quot;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 19px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&quot;abcdefghijklmn&quot;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;pre id=&quot;code_1668004685893&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class IdRecommend {

    public String solution(String new_id) {

        // 1.모든 대문자를 대응되는 소문자로 치환
        String answer = &quot;&quot;;
        new_id = new_id.toLowerCase();

        // 2.알파벳 소문자, 숫자, 빼기(-), 밑줄(_), 마침표(.)를 제외한 모든 문자를 제거
        for (int i = 0; i &amp;lt; new_id.length(); i++) {
            char ch = new_id.charAt(i);
            if (Character.isAlphabetic(ch) ||
                    Character.isDigit(ch) ||
                    ch == '-' || ch == '_' || ch == '.')
                answer += ch;
        }

        // 3.마침표(.)가 2번 이상 연속된 부분을 하나의 마침표(.)로 치환
        while (answer.indexOf(&quot;..&quot;) != -1)
            answer = answer.replace(&quot;..&quot;, &quot;.&quot;);


        // 4.마침표(.)가 처음이나 끝에 위치한다면 제거
        if (!answer.isEmpty() &amp;amp;&amp;amp; answer.charAt(0) == '.')
            answer = answer.substring(1);
        if (!answer.isEmpty() &amp;amp;&amp;amp; answer.charAt(answer.length() - 1) == '.')
            answer = answer.substring(0, answer.length() - 1);


        // 5.빈 문자열이라면, new_id에 &quot;a&quot;를 대입
        if (answer.isEmpty())
            answer = &quot;a&quot;;

        // 6.길이가 16자 이상이면, new_id의 첫 15개의 문자를 제외한 나머지 문자들을 모두 제거
        //  만약 제거 후 마침표(.)가 new_id의 끝에 위치한다면 끝에 위치한 마침표(.) 문자를 제거
        if (answer.length() &amp;gt; 15) {
            answer = answer.substring(0, 15);
            if (answer.charAt(answer.length() - 1) == '.')
                answer = answer.substring(0, answer.length() - 1);
        }

        // 7. 길이가 2자 이하라면, new_id의 마지막 문자를 new_id의 길이가 3이 될 때까지 반복해서 끝에 붙입니다.
        while (answer.length() &amp;lt; 3)
            answer += answer.charAt(answer.length() - 1);

        return answer;
    }

    public static void main(String[] args) {
        IdRecommend sol = new IdRecommend();
        System.out.print(sol.solution(&quot;...!@BaT#*..y.abcdefghijklm&quot;));
    }


}&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;toLowerCase&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- 대상 문자열을 소문자로 변환&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;toUpperCase&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- 대상 문자열을 대문자로 변환&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;charAt&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- String으로 저장된 문자열을 한 글자만 선택해서 char타입으로 변환&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;Character.isAlphabetic&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;-&amp;nbsp; 명시된 char 값이 문자인지 여부를 판단하여 true/false 반환&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;Character.isDigit&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- 명시된 char 값이 숫자인지 여부를 판단하여 true/false 반환&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;indexOf&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- 특정 문자나 문자열이 앞에서부터 처음 발견되는 인덱스 반환&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- 찾지 못했을 경우 &quot;-1&quot; 반환&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;substring&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- 문자열의 특정 부분을 잘라내는데 사용&lt;/span&gt;&lt;/p&gt;</description>
      <category>차곡차곡/Algorithms</category>
      <author>p퐝유p</author>
      <guid isPermaLink="true">https://nikeisme827.tistory.com/55</guid>
      <comments>https://nikeisme827.tistory.com/55#entry55comment</comments>
      <pubDate>Wed, 9 Nov 2022 23:58:18 +0900</pubDate>
    </item>
    <item>
      <title>[JAVA] 엔티티 매핑 (6) - 필드와 컬럼 매핑 어노테이션 레퍼런스</title>
      <link>https://nikeisme827.tistory.com/54</link>
      <description>&lt;pre id=&quot;code_1658578634289&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Entity
@Table(name=&quot;MEMBER&quot;, uniqueConstraints = {@UniqueConstraint( //추가
		name = &quot;NAME_AGE_UNIQUE&quot;,
		columnNames = {&quot;NAME&quot;,&quot;AGE&quot;})})
public class Member {

	@Id
	@Column(name=&quot;ID&quot;)
	private String id;
	
	@Column(name= &quot;NAME&quot;, nullable = false, length=10 ) // 추가
	private String username;
	
	private Integer age;
	
	//==추가==
	@Enumerated(EnumType.STRING)
	private RoleType roleType;
	
	@Temporal(TemporalType.TIMESTAMP)
	private Date createDate;
	
	@Temporal(TemporalType.TIMESTAMP)
	private Date lastModifiedDate;
	
	@Lob
	private String description;
	
	
	//Getter,Setter
    .....
	
}&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;table style=&quot;border-collapse: collapse; width: 97.9074%; height: 262px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;분류&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;매핑 어노테이션&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;설명&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 120px;&quot; rowspan=&quot;5&quot;&gt;필드와 컬럼 매핑&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;@Column&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;컬럼을 매핑한다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;@Enumerated&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;자바의 enum 타입을 매핑한다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;@Temporal&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;날짜 타입을 매핑한다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;@Lob&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;BLOB,CLOB타입을 매핑한다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 40px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 40px;&quot;&gt;@Transient&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 40px;&quot;&gt;특정 필드를 데이터베이스에 매핑하지 않는다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 40px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 40px;&quot;&gt;기타&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 40px;&quot;&gt;@ Access&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 40px;&quot;&gt;JPA가 엔티티에 접근하는 방식을 지정한다.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;</description>
      <category>차곡차곡/Algorithms</category>
      <author>p퐝유p</author>
      <guid isPermaLink="true">https://nikeisme827.tistory.com/54</guid>
      <comments>https://nikeisme827.tistory.com/54#entry54comment</comments>
      <pubDate>Mon, 25 Jul 2022 14:40:43 +0900</pubDate>
    </item>
    <item>
      <title>[JAVA] 엔티티 매핑 (4) - 기본 키 매핑</title>
      <link>https://nikeisme827.tistory.com/53</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;기본 키를 애플리케이션에서 직접 할당하는 대신,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;데이터베이스가 생성해주는 값을 사용하려면 어떻게 매핑해야할까?&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; background-color: #ffc1c8;&quot;&gt;★ 기본 키 매핑&lt;/span&gt;&lt;/b&gt;&lt;/h2&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;font-family: 'Noto Serif KR';&quot;&gt;- JPA가 제공하는 데이터베이스 기본 키 생성 전략&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp;1. IDENTITY : 기본 키 생성을 데이터베이스에 위임한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp;2. SEQUENCE : 데이터베이스 시퀀스를 사용해 기본키를 할당한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp;3. TABLE : 키 생성 테이블을 사용한다.&lt;/span&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;font-family: 'Noto Serif KR';&quot;&gt;하지만 데이터베이스 벤더마다 지원하는 방식이 다르다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;오라클은 시퀀스 제공하지만 My SQL은 시퀀스를 제공하지 않는 것 처럼 다 다르다.&lt;/span&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;font-family: 'Noto Serif KR';&quot;&gt;- 기본 키를 직접 할당하려면 @Id만 사용하면 되고,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp;자동 생성 전략 사용 시, @Id 에 @GenerateValue를 추가하고 원하는 키 생성 전략을 선택하면 된다,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;☆ 기본 키 직접 할당 전략&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;기본 키 직접 할당 전략은 &lt;u&gt;&lt;b&gt;em.persist( ) 로 엔티티를 저장하기 전에 애플리케이션에서 기본 키를 직접 할당하는 방법&lt;/b&gt;&lt;/u&gt;이다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1658577592126&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Id
@Column(name = &quot;id&quot;)
private String id;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;&lt;u&gt;@Id 적용 기능 자바 타입&lt;/u&gt;&lt;/b&gt;은&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;1. 자바 기본형&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;2. 자바 래펴(Wrapper)형&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;3. String&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;4. java.util.Date&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;5. java.sql.Date&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;6. java.math.BigDecimal&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;7. java.math.BigInteger&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;이다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1658577845426&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Board board = new Board();
board.setId(&quot;id1&quot;) // 기본키 직접 할당
em.persist(board);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; background-color: #9feec3;&quot;&gt;☆ IDENTITY 전략&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; - 데이터베이스에 엔티티를 저장해서 식별자 값 획득 후 영속성 컨텍스트에 저장한다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; 테이블에 데이터를 저장해야 식별자 값을 획득할 수 있다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; background-color: #9feec3;&quot;&gt;☆ TABLE 전략&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp;- 데이터베이스 시퀀스 생성용 테이블에서 식별자 값을 획득 후 영속성 컨텍스에 저장한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;☆ SEQUENCE&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;- &amp;nbsp;데이터베이스 시퀀스에서 식별자 값을 획득 후 영속성 컨텍스에 저장한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;a href=&quot;http://www.kyobobook.co.kr/product/detailViewKor.laf?ejkGb=KOR&amp;amp;mallGb=KOR&amp;amp;barcode=9788960777330&amp;amp;orderClick=LAG&amp;amp;Kc=&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;http://www.kyobobook.co.kr/product/detailViewKor.laf?ejkGb=KOR&amp;amp;mallGb=KOR&amp;amp;barcode=9788960777330&amp;amp;orderClick=LAG&amp;amp;Kc=&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1658578462146&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;book&quot; data-og-title=&quot;자바 ORM 표준 JPA 프로그래밍 - 교보문고&quot; data-og-description=&quot;스프링 데이터 예제 프로젝트로 배우는 전자정부 표준 데이터베이스 프레임 | ★ 이 책에서 다루는 내용 ★■ JPA 기초 이론과 핵심 원리■ JPA로 도메인 모델을 설계하는 과정을 예제 중심으로 &quot; data-og-host=&quot;www.kyobobook.co.kr&quot; data-og-source-url=&quot;http://www.kyobobook.co.kr/product/detailViewKor.laf?ejkGb=KOR&amp;amp;mallGb=KOR&amp;amp;barcode=9788960777330&amp;amp;orderClick=LAG&amp;amp;Kc=&quot; data-og-url=&quot;http://www.kyobobook.co.kr/product/detailViewKor.laf?mallGb=KOR&amp;amp;ejkGb=KOR&amp;amp;barcode=9788960777330&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/FdY5t/hyPbSxkiZn/EPeWqBazEtpwl8tiK3S611/img.jpg?width=458&amp;amp;height=609&amp;amp;face=0_0_458_609&quot;&gt;&lt;a href=&quot;http://www.kyobobook.co.kr/product/detailViewKor.laf?ejkGb=KOR&amp;amp;mallGb=KOR&amp;amp;barcode=9788960777330&amp;amp;orderClick=LAG&amp;amp;Kc=&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;http://www.kyobobook.co.kr/product/detailViewKor.laf?ejkGb=KOR&amp;amp;mallGb=KOR&amp;amp;barcode=9788960777330&amp;amp;orderClick=LAG&amp;amp;Kc=&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/FdY5t/hyPbSxkiZn/EPeWqBazEtpwl8tiK3S611/img.jpg?width=458&amp;amp;height=609&amp;amp;face=0_0_458_609');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;자바 ORM 표준 JPA 프로그래밍 - 교보문고&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;스프링 데이터 예제 프로젝트로 배우는 전자정부 표준 데이터베이스 프레임 | ★ 이 책에서 다루는 내용 ★■ JPA 기초 이론과 핵심 원리■ JPA로 도메인 모델을 설계하는 과정을 예제 중심으로&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.kyobobook.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>차곡차곡/Java</category>
      <category>identity</category>
      <category>JPA 기본키 매핑 전략</category>
      <category>sequence</category>
      <category>table</category>
      <author>p퐝유p</author>
      <guid isPermaLink="true">https://nikeisme827.tistory.com/53</guid>
      <comments>https://nikeisme827.tistory.com/53#entry53comment</comments>
      <pubDate>Sat, 23 Jul 2022 21:15:15 +0900</pubDate>
    </item>
    <item>
      <title>[JAVA] 엔티티 매핑 (3) - DDL 생성 기능</title>
      <link>https://nikeisme827.tistory.com/52</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; background-color: #ffc1c8;&quot;&gt;★ DDL 생성 기능&lt;/span&gt;&lt;/h2&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;font-family: 'Noto Serif KR';&quot;&gt;- &lt;u&gt;&lt;b&gt;회원 이름은 필수로 입력되어야 하고, 10자를 초과하면 안 된다는 제약조건이 추가&lt;/b&gt;&lt;/u&gt;되었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; 스키마 자동 생성하기를 통해 만들어지는 DDL에 이 제약조건을 추가해보자.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1658576256692&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Entity
@Table(name=&quot;MEMBER&quot;, uniqueConstraints = {@UniqueConstraint( //추가
		name = &quot;NAME_AGE_UNIQUE&quot;,
		columnNames = {&quot;NAME&quot;,&quot;AGE&quot;})})
public class Member {

	@Id
	@Column(name=&quot;ID&quot;)
	private String id;
	
	@Column(name= &quot;NAME&quot;, nullable = false, length=10 ) // 추가
	private String username;
	
	private Integer age;
    
    ....
    
    }&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1658576346076&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Column(name= &quot;NAME&quot;, nullable = false, length=10 ) // 추가
	private String username;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- 위의 해석은&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp;@Column 매핑 정보의 &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp;nullable 속성 값을 falase로 지정 : &lt;span&gt;not null 제약조건 추가&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp;length = 10 : 글자 수 10자로 제한&lt;/span&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;font-family: 'Noto Serif KR';&quot;&gt;- 하지만 이런 기능들은 단지 DDL을 자동 생성할 때만 사용되고 JPA의 실행 로직에는 영향을 주지 않는다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp;따라서 스키마 자동 생성 기능을 사용하지 않고, 직접&amp;nbsp; ddl을 만든다면 사용할 이유가 없다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;http://www.kyobobook.co.kr/product/detailViewKor.laf?ejkGb=KOR&amp;amp;mallGb=KOR&amp;amp;barcode=9788960777330&amp;amp;orderClick=LAG&amp;amp;Kc=&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;http://www.kyobobook.co.kr/product/detailViewKor.laf?ejkGb=KOR&amp;amp;mallGb=KOR&amp;amp;barcode=9788960777330&amp;amp;orderClick=LAG&amp;amp;Kc=&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1658576817319&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;book&quot; data-og-title=&quot;자바 ORM 표준 JPA 프로그래밍 - 교보문고&quot; data-og-description=&quot;스프링 데이터 예제 프로젝트로 배우는 전자정부 표준 데이터베이스 프레임 | ★ 이 책에서 다루는 내용 ★■ JPA 기초 이론과 핵심 원리■ JPA로 도메인 모델을 설계하는 과정을 예제 중심으로 &quot; data-og-host=&quot;www.kyobobook.co.kr&quot; data-og-source-url=&quot;http://www.kyobobook.co.kr/product/detailViewKor.laf?ejkGb=KOR&amp;amp;mallGb=KOR&amp;amp;barcode=9788960777330&amp;amp;orderClick=LAG&amp;amp;Kc=&quot; data-og-url=&quot;http://www.kyobobook.co.kr/product/detailViewKor.laf?mallGb=KOR&amp;amp;ejkGb=KOR&amp;amp;barcode=9788960777330&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/FdY5t/hyPbSxkiZn/EPeWqBazEtpwl8tiK3S611/img.jpg?width=458&amp;amp;height=609&amp;amp;face=0_0_458_609&quot;&gt;&lt;a href=&quot;http://www.kyobobook.co.kr/product/detailViewKor.laf?ejkGb=KOR&amp;amp;mallGb=KOR&amp;amp;barcode=9788960777330&amp;amp;orderClick=LAG&amp;amp;Kc=&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;http://www.kyobobook.co.kr/product/detailViewKor.laf?ejkGb=KOR&amp;amp;mallGb=KOR&amp;amp;barcode=9788960777330&amp;amp;orderClick=LAG&amp;amp;Kc=&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/FdY5t/hyPbSxkiZn/EPeWqBazEtpwl8tiK3S611/img.jpg?width=458&amp;amp;height=609&amp;amp;face=0_0_458_609');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;자바 ORM 표준 JPA 프로그래밍 - 교보문고&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;스프링 데이터 예제 프로젝트로 배우는 전자정부 표준 데이터베이스 프레임 | ★ 이 책에서 다루는 내용 ★■ JPA 기초 이론과 핵심 원리■ JPA로 도메인 모델을 설계하는 과정을 예제 중심으로&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.kyobobook.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>차곡차곡/Java</category>
      <author>p퐝유p</author>
      <guid isPermaLink="true">https://nikeisme827.tistory.com/52</guid>
      <comments>https://nikeisme827.tistory.com/52#entry52comment</comments>
      <pubDate>Sat, 23 Jul 2022 20:47:12 +0900</pubDate>
    </item>
    <item>
      <title>[JAVA] 엔티티 매핑 (2) - 데이터베이스 스키마 자동 생성</title>
      <link>https://nikeisme827.tistory.com/51</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;테이블을 먼저 생성하고, 그 다음 엔티티를 생성했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;하지만 데이터베이스 스키마 자동생성을 통해 엔티티만 만들고 테이블은 자동 생성 할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;background-color: #ffc1c8;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;★ 데이터베이스 스키마 자동 생성&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; - JPA는 이 매핑 정보와 데이터베이스 방언을 사용해서 데이터베이스 스키마를 생성한다.&lt;/span&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;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; ※ 데이터베이스 방언이란?&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; -&amp;nbsp; SQL 표준을 지키지 않거나 특정 데이터베이스만의 고유한 기능을 '방언'이라고 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; JPA는 특정베이스에 종속적이지 않은 기술. 따라서 다른 데이터베이스로 교체 가능하다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; 만약 종속적이면 데이터베이스 교체하기 어렵다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; 따라서, 하이버네이트 등의&amp;nbsp; JPA 구현체들은 다양한 데이터베이스 방언 클래스를 제공한다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;☆ 스키마 자동 생성하는 법&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp;&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;201&quot; data-origin-height=&quot;71&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cExV4J/btrH2ida1OT/qxDklSQPBYX7bKukNNTmeK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cExV4J/btrH2ida1OT/qxDklSQPBYX7bKukNNTmeK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cExV4J/btrH2ida1OT/qxDklSQPBYX7bKukNNTmeK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcExV4J%2FbtrH2ida1OT%2FqxDklSQPBYX7bKukNNTmeK%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;201&quot; height=&quot;71&quot; data-origin-width=&quot;201&quot; data-origin-height=&quot;71&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;persistence.xml 에 다음 속성을 추가한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1658569468123&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt; &amp;lt;property name=&quot;hibernate.hbm2ddl.auto&quot; value=&quot;create&quot; /&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;결과는 애플리케이션 실행 시점에 &lt;b&gt;&lt;u&gt;데이터베이스 테이블을 자동으로 생성&lt;/u&gt;&lt;/b&gt;한다.&amp;nbsp;&lt;/span&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;span style=&quot;font-family: 'Noto Serif KR'; background-color: #9feec3;&quot;&gt;☆ 콘솔에 실행되는 테이블 생성 DDL을 출력하는 법&lt;/span&gt;&lt;/b&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;font-family: 'Noto Serif KR';&quot;&gt;테이블이 자동으로 잘 생성되었는지 확인하기 위해 콘솔에 나타나는 법은&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1658569703847&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;property name=&quot;hibernate.show_sql&quot; value=&quot;true&quot; /&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;이 속성을 &lt;b&gt;&lt;u&gt;true로 설정&lt;/u&gt;&lt;/b&gt;해주면 된다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;290&quot; data-origin-height=&quot;60&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mf1DY/btrH5dCeu0i/hYQHFoBqzBMaoe6PdDKeiK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mf1DY/btrH5dCeu0i/hYQHFoBqzBMaoe6PdDKeiK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mf1DY/btrH5dCeu0i/hYQHFoBqzBMaoe6PdDKeiK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fmf1DY%2FbtrH5dCeu0i%2FhYQHFoBqzBMaoe6PdDKeiK%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;290&quot; height=&quot;60&quot; data-origin-width=&quot;290&quot; data-origin-height=&quot;60&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;328&quot; data-origin-height=&quot;242&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cXGQ9U/btrH0v5GweH/09lfJFCKN49DVy3uC1mgsK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cXGQ9U/btrH0v5GweH/09lfJFCKN49DVy3uC1mgsK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cXGQ9U/btrH0v5GweH/09lfJFCKN49DVy3uC1mgsK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcXGQ9U%2FbtrH0v5GweH%2F09lfJFCKN49DVy3uC1mgsK%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;242&quot; data-origin-width=&quot;328&quot; data-origin-height=&quot;242&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;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;실행된 결과를 보자. 기존 테이블을 삭제하고 다시 생성한 것을 볼 수 있다.&amp;nbsp;&lt;/span&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;font-family: 'Noto Serif KR';&quot;&gt;- 스키마 자동 생성 기능의 장점은 개발자가 테이블을 직접 생성하는 수고를 덜 수 있다는 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; 하지만 자동 생성 기능이 만든 DDL은 운영 황경에서 사용할 만큼 완벽하지 않으므로&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &lt;u&gt;&lt;b&gt;개발 환경에서 사용하거나 매핑을 어떻게 해야 하는지 참고하는 정도로만 사용하는 것이 좋다고 한다.&lt;/b&gt;&lt;/u&gt;&lt;/span&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;span style=&quot;font-family: 'Noto Serif KR'; background-color: #9feec3;&quot;&gt;☆ hibernate.hbm2ddl.auto 속성 정리&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 191px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 12.907%; height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;옵션&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 87.093%; height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;속성&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 37px;&quot;&gt;
&lt;td style=&quot;width: 12.907%; height: 37px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;create&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 87.093%; height: 37px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;기존 테이블 삭제 후 새로 생성. &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;DROP + CREATE&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 37px;&quot;&gt;
&lt;td style=&quot;width: 12.907%; height: 37px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;create-drop&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 87.093%; height: 37px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;create 속성에 더하여 애플리케이션 종료 시 생성한 DDL 을 제거한다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;DROP + CREATE+DROP&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 40px;&quot;&gt;
&lt;td style=&quot;width: 12.907%; height: 40px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;update&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 87.093%; height: 40px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;데이터베이스 테이블과 엔티티 매핑정보를 비교하여 변경 사항만 수정한다.&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 40px;&quot;&gt;
&lt;td style=&quot;width: 12.907%; height: 40px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;validate&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 87.093%; height: 40px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;데이터베이스 테이블과 엔티티 매핑정보를 비교하여 차이가 있을 시&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;경고를 남기고 애플리케이션을 실행하지 않는다.&amp;nbsp; 이 설정은 DDL을 수정하지 않는다.&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 12.907%; height: 17px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;none&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 87.093%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;자동 생성 기능을 사용하지 않으려면 hibernate.hbm2ddl.auto 속성 자체를 삭제하거나&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;유효하지 않은 옵션 값을 주면 된다.&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>차곡차곡/Java</category>
      <category>DDL 생성 콘솔 출력</category>
      <category>JPA</category>
      <category>데이터베이스 스키마 자동 생성</category>
      <author>p퐝유p</author>
      <guid isPermaLink="true">https://nikeisme827.tistory.com/51</guid>
      <comments>https://nikeisme827.tistory.com/51#entry51comment</comments>
      <pubDate>Sat, 23 Jul 2022 19:16:01 +0900</pubDate>
    </item>
    <item>
      <title>[Java] 엔티티 매핑 (1) - @Entity / @Table / 그 외 다양한 매핑</title>
      <link>https://nikeisme827.tistory.com/50</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000; background-color: #ffc1c8;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;★ @Entity란?&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- JPA를 사용해서 테이블과 매핑할 클래스는 @Entity를 꼭 붙여야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; background-color: #9feec3;&quot;&gt;☆ @Entity 속성&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;1. name : JPA에서 사용할 엔티티 이름을 지정해야한다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 설정하지 않으면 클래스 이름 그대로 사용하는 걸로 인식한다.&lt;/span&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;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; background-color: #9feec3;&quot;&gt;☆&amp;nbsp;@Entity 주의사항&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;1. 기본 생성자는 필수 (파라미터가 없는 public 또는 protected 생성자)&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1658466192839&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public member () // 기본 생성자

//임의의 생성자
public Member(String name){
	this.name = name
}&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;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;2. final, enum,interface,inner 클래스에는 사용 불가&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;3. 저장할 필드에 final 사용불가&lt;/span&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;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;background-color: #ffc1c8;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;★ @Table란?&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- @Table은 엔티티와 매핑할 테이블을 지정한다. 이를 생략하면 매핑한 엔티티 이름을 테이블 이름으로 사용한다.&lt;/span&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;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; background-color: #9feec3;&quot;&gt;☆&amp;nbsp;@Entity 속성&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 137px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 9.84497%; height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;속성&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 56.8216%; height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;기능&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;기본값&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 9.84497%; height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;name&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 56.8216%; height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;매핑할 테이블 이름&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;엔티티 이름을 사용한다.&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 40px;&quot;&gt;
&lt;td style=&quot;width: 9.84497%; height: 40px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;catalog&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 56.8216%; height: 40px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;catalog 기능이 있는 데이터베이스에서 catalog를 매핑한다.&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 40px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 9.84497%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;schema&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 56.8216%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;schema 기능이 있는 데이터베이스에서 schema를 매핑한다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;DDL 생성 시에 유니크 제약조건을 만든다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;2개 이상의 복합 유니크 제약조건도 가능하다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;스키마 자동 생성 기능을 사용해서 DDL을 만들 때만 사용된다.&amp;nbsp;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;※ DDL(Data Definition Language] - 데이터 정의어&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;데이터 베이스를 정의하는 언어 / 데이터 생성,수정,삭제 등 전체 골격을 만드는 역할&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;ex ) CREATE, ALTER,DROP,TRUNCATE&lt;/span&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;font-family: 'Noto Serif KR';&quot;&gt;출처 : &lt;a href=&quot;https://cbw1030.tistory.com/71&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://cbw1030.tistory.com/71&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;★ 그 외 다양한 매핑&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; - 회원 관리 프로그램에서 다음과 같은 요구사항이 추가해야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; 1. 회원은 일반회원 / 관리자 로 구분&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; 2. 회원 가입일과 수정일 생성&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; 3. 회원을 설명할 수 있는 필드 생성. 이 필드는 길이 제한 없음&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1658566759111&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package jpabook.start;

import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.UniqueConstraint;



@Entity
@Table(name=&quot;MEMBER&quot;, uniqueConstraints = {@UniqueConstraint( //추가
		name = &quot;NAME_AGE_UNIQUE&quot;,
		columnNames = {&quot;NAME&quot;,&quot;AGE&quot;})})
public class Member {

	@Id
	@Column(name=&quot;ID&quot;)
	private String id;
	
	@Column(name= &quot;NAME&quot;, nullable = false, length=10 ) // 추가
	private String username;
	
	private Integer age;
	
	//==추가==
	@Enumerated(EnumType.STRING)
	private RoleType roleType;
	
	@Temporal(TemporalType.TIMESTAMP)
	private Date createDate;
	
	@Temporal(TemporalType.TIMESTAMP)
	private Date lastModifiedDate;
	
	@Lob
	private String description;
	
	
	//Getter,Setter
	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public Integer getAge() {
		return age;
	}

	public void setAge(Integer age) {
		this.age = age;
	}

	public RoleType getRoleType() {
		return roleType;
	}

	public void setRoleType(RoleType roleType) {
		this.roleType = roleType;
	}

	public Date getCreateDate() {
		return createDate;
	}

	public void setCreateDate(Date createDate) {
		this.createDate = createDate;
	}

	public Date getLastModifiedDate() {
		return lastModifiedDate;
	}

	public void setLastModifiedDate(Date lastModifiedDate) {
		this.lastModifiedDate = lastModifiedDate;
	}

	public String getDescription() {
		return description;
	}

	public void setDescription(String description) {
		this.description = description;
	}
	
}&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;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;1.&amp;nbsp; roleType&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; - 자바의&amp;nbsp; enum을 사용해서 회원 타입을 구분한다. 이때 쓰이는 어노테이션은 &lt;b&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;@Enumerated&lt;/span&gt;&lt;/b&gt;이다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; 일반 회원은 USER, 관리자는 ADMIN&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;2. createdDate,lastModifiedDate&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; - 자바의 날짜 타입은 &lt;b&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;@Temporal&lt;/span&gt;&lt;/b&gt;을 사용해서 매핑한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;3. description&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; - 회원을 설명하는 필드는 길이 제한이 없다. 그래서 VARCHAR타입 대신에 CLOB타입으로 저장해야한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;b&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;@Lob&lt;/span&gt;&lt;/b&gt;을 사용하면 CLOB,BLOB 타입을 매핑할 수 있다.&lt;/span&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; &amp;nbsp; &amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 이 책을 바탕으로 학습했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;http://www.kyobobook.co.kr/product/detailViewKor.laf?ejkGb=KOR&amp;amp;mallGb=KOR&amp;amp;barcode=9788960777330&amp;amp;orderClick=LAG&amp;amp;Kc=&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;http://www.kyobobook.co.kr/product/detailViewKor.laf?ejkGb=KOR&amp;amp;mallGb=KOR&amp;amp;barcode=9788960777330&amp;amp;orderClick=LAG&amp;amp;Kc=&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1658567178470&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;book&quot; data-og-title=&quot;자바 ORM 표준 JPA 프로그래밍 - 교보문고&quot; data-og-description=&quot;스프링 데이터 예제 프로젝트로 배우는 전자정부 표준 데이터베이스 프레임 | ★ 이 책에서 다루는 내용 ★■ JPA 기초 이론과 핵심 원리■ JPA로 도메인 모델을 설계하는 과정을 예제 중심으로 &quot; data-og-host=&quot;www.kyobobook.co.kr&quot; data-og-source-url=&quot;http://www.kyobobook.co.kr/product/detailViewKor.laf?ejkGb=KOR&amp;amp;mallGb=KOR&amp;amp;barcode=9788960777330&amp;amp;orderClick=LAG&amp;amp;Kc=&quot; data-og-url=&quot;http://www.kyobobook.co.kr/product/detailViewKor.laf?mallGb=KOR&amp;amp;ejkGb=KOR&amp;amp;barcode=9788960777330&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/FdY5t/hyPbSxkiZn/EPeWqBazEtpwl8tiK3S611/img.jpg?width=458&amp;amp;height=609&amp;amp;face=0_0_458_609&quot;&gt;&lt;a href=&quot;http://www.kyobobook.co.kr/product/detailViewKor.laf?ejkGb=KOR&amp;amp;mallGb=KOR&amp;amp;barcode=9788960777330&amp;amp;orderClick=LAG&amp;amp;Kc=&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;http://www.kyobobook.co.kr/product/detailViewKor.laf?ejkGb=KOR&amp;amp;mallGb=KOR&amp;amp;barcode=9788960777330&amp;amp;orderClick=LAG&amp;amp;Kc=&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/FdY5t/hyPbSxkiZn/EPeWqBazEtpwl8tiK3S611/img.jpg?width=458&amp;amp;height=609&amp;amp;face=0_0_458_609');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;자바 ORM 표준 JPA 프로그래밍 - 교보문고&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;스프링 데이터 예제 프로젝트로 배우는 전자정부 표준 데이터베이스 프레임 | ★ 이 책에서 다루는 내용 ★■ JPA 기초 이론과 핵심 원리■ JPA로 도메인 모델을 설계하는 과정을 예제 중심으로&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.kyobobook.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>차곡차곡/Java</category>
      <author>p퐝유p</author>
      <guid isPermaLink="true">https://nikeisme827.tistory.com/50</guid>
      <comments>https://nikeisme827.tistory.com/50#entry50comment</comments>
      <pubDate>Sat, 23 Jul 2022 18:06:37 +0900</pubDate>
    </item>
    <item>
      <title>[Java] 영속성 관리 - (5) 준영속</title>
      <link>https://nikeisme827.tistory.com/49</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; background-color: #ffc1c8;&quot;&gt;&lt;b&gt;★&amp;nbsp; 준영속이란?&lt;/b&gt;&lt;/span&gt;&lt;/h2&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #9feec3; font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;☆ 영속 상태의 엔티티를 준영속 상태로 만드는 방법&lt;/b&gt;&lt;/span&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;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;1. em.detach(entity) : 특정 엔티티만 준영속 상태로 전환한다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;2.&amp;nbsp; em.clear( ) : 영속성 컨텍스트를 완전히 초기화한다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;3.&amp;nbsp; em.close( ) : 영속성 컨텍스트를 종료한다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; background-color: #9feec3;&quot;&gt;&lt;b&gt;☆ 준영속 상태의 특징&lt;/b&gt;&lt;/span&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;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;1. 거의 비영속 상태에 가깝다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- 영속 컨텍스트가 관리하지 않는다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; 그래서 1차 캐시, 쓰기 지연 등등 영속성 컨텍스트가 제공하는 어떠한 기능도 동작하지 않는다.&lt;/span&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;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;2. 식별자 값을 가지고 있다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- 준영속 상태는 이미 한 번 영속 상태였으므로 반드시 식별자 값을 가지고 있다.&lt;/span&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;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;3. 지연 로딩을 할 수 없다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;-&amp;nbsp; 준영속 상태는 영속성 컨텍스가 더는 관리하지 않으므로 지연 로딩시 문제가 발생한다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; background-color: #9feec3;&quot;&gt;&lt;b&gt;☆ 병합: merge( )&lt;/b&gt;&lt;/span&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;font-family: 'Noto Serif KR';&quot;&gt;- &lt;u&gt;&lt;b&gt;준영속 상태의 엔티티를 다시 영속 상태로 변경하려면 병합을 사용&lt;/b&gt;&lt;/u&gt;하면 된다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; merge( ) 메소드는 준영속 상태의 엔티티를 받아서 그 정보로 새로운 영속 상태의 엔티티를 반환한다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1658045200047&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class ExamMergeMain {

	EntityManagerFactory emf = 
			Persistence.createEntityManagerFactory((&quot;jpabook&quot;);

	public static void main(String[] args) {

		Member member = createMember(&quot;memberA&quot;, &quot;회원1&quot;);

		member.setUsername(&quot;회원명변경&quot;);

		mergeMember(member);
	}

	static Member createMember(String id, String username) {
		// == 영속성 컨텍스트1 시작 ==//

		EntityManager em1 = emf.createEntityManager();

		EntityTransaction tx1 = em1.getTransaction();

		tx1.begin();

		Member member = new Member();
		member.setId(id);
		member.setUsername(username);

		em1.persist(member);
		tx1.commit();

		em1.close(); // 영속성 컨텍스트1 종료,
						// member 엔티티는 준영속 상태가 된다.
		// == 영속성 컨텍스트1 종료 ==//

		return member;
	}

	static void mergeMember(Member member) {
		// == 영속성 컨텍스트2 시작 ==//

		EntityManager em2 = emf.createEntityManager();

		EntityTransaction tx2 = em2.getTransaction();

		tx2.begin();
		Member mergeMember = em2.merge(member);
		tx2.commit();

		// 준영속 상태
		System.out.println(&quot;member = &quot; + member.getUsername());

		// 영속 상태
		System.out.println(&quot;mergeMember = &quot; + mergeMember.getUsername());

		System.out.println(&quot;em2 contains member = &quot; + em2.contains(member));

		System.out.println(&quot;em2 contains mergeMember = &quot; + em2.contains(mergeMember));
		em2.close(); // 영속성 컨텍스트2 종료,

		// == 영속성 컨텍스트2 종료 ==//

	}

}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;http://www.kyobobook.co.kr/product/detailViewKor.laf?ejkGb=KOR&amp;amp;mallGb=KOR&amp;amp;barcode=9788960777330&amp;amp;orderClick=LAG&amp;amp;Kc=&quot;&gt;http://www.kyobobook.co.kr/product/detailViewKor.laf?ejkGb=KOR&amp;amp;mallGb=KOR&amp;amp;barcode=9788960777330&amp;amp;orderClick=LAG&amp;amp;Kc=&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1658045363469&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;book&quot; data-og-title=&quot;자바 ORM 표준 JPA 프로그래밍 - 교보문고&quot; data-og-description=&quot;스프링 데이터 예제 프로젝트로 배우는 전자정부 표준 데이터베이스 프레임 | ★ 이 책에서 다루는 내용 ★■ JPA 기초 이론과 핵심 원리■ JPA로 도메인 모델을 설계하는 과정을 예제 중심으로 &quot; data-og-host=&quot;www.kyobobook.co.kr&quot; data-og-source-url=&quot;http://www.kyobobook.co.kr/product/detailViewKor.laf?ejkGb=KOR&amp;amp;mallGb=KOR&amp;amp;barcode=9788960777330&amp;amp;orderClick=LAG&amp;amp;Kc=&quot; data-og-url=&quot;http://www.kyobobook.co.kr/product/detailViewKor.laf?mallGb=KOR&amp;amp;ejkGb=KOR&amp;amp;barcode=9788960777330&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/R7UAg/hyO7Acz32P/Wnu2rSgE8VX9b5c4dGdMW1/img.jpg?width=458&amp;amp;height=609&amp;amp;face=0_0_458_609&quot;&gt;&lt;a href=&quot;http://www.kyobobook.co.kr/product/detailViewKor.laf?ejkGb=KOR&amp;amp;mallGb=KOR&amp;amp;barcode=9788960777330&amp;amp;orderClick=LAG&amp;amp;Kc=&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;http://www.kyobobook.co.kr/product/detailViewKor.laf?ejkGb=KOR&amp;amp;mallGb=KOR&amp;amp;barcode=9788960777330&amp;amp;orderClick=LAG&amp;amp;Kc=&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/R7UAg/hyO7Acz32P/Wnu2rSgE8VX9b5c4dGdMW1/img.jpg?width=458&amp;amp;height=609&amp;amp;face=0_0_458_609');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;자바 ORM 표준 JPA 프로그래밍 - 교보문고&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;스프링 데이터 예제 프로젝트로 배우는 전자정부 표준 데이터베이스 프레임 | ★ 이 책에서 다루는 내용 ★■ JPA 기초 이론과 핵심 원리■ JPA로 도메인 모델을 설계하는 과정을 예제 중심으로&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.kyobobook.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>차곡차곡/Java</category>
      <author>p퐝유p</author>
      <guid isPermaLink="true">https://nikeisme827.tistory.com/49</guid>
      <comments>https://nikeisme827.tistory.com/49#entry49comment</comments>
      <pubDate>Sun, 17 Jul 2022 17:07:08 +0900</pubDate>
    </item>
    <item>
      <title>[JAVA] JPA 영속성 관리 (4) - 플러시 (flush)</title>
      <link>https://nikeisme827.tistory.com/48</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #000000; background-color: #ffc1c8;&quot;&gt;&lt;b&gt;★&amp;nbsp; 플러시(flush)란?&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- 플러시는 영속성 컨텍스트의 변경 내용을 데이터베이스에 반영한다.&amp;nbsp;&lt;/span&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;span style=&quot;font-family: 'Noto Serif KR'; background-color: #9feec3;&quot;&gt;☆ 플러시 실행 후, 결과&lt;/span&gt;&lt;/b&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;font-family: 'Noto Serif KR';&quot;&gt;1. 변경 감지가 동작해서 영속성 컨텍스트 내의 모든 엔티티를 스냅샷과 비교 후, 엔티티를 찾는다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; &amp;nbsp;수정된 엔티티는 수정 쿼리를 만들어 쓰기 지연 SQL 저장소에 등록한다.&lt;/span&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;font-family: 'Noto Serif KR';&quot;&gt;2. 쓰기 지연 SQL 저장소의 쿼리를 데이터베이스에 전송한다.&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; background-color: #9feec3;&quot;&gt;☆ 영속성 컨텍스트를 플러시하는 방법&lt;/span&gt;&lt;/b&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;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;1. em.flush()를 직접 호출한다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- 직접 호출은 영속성 컨텍스트를 강제로 플러시한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; 테스트나 다른 프레임워크와 JPA를 함께 사용할 때를 제외하고 거의 사용하지 않는다.&amp;nbsp;&lt;/span&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;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;2. 트랜잭션 커밋 시 플러시가 자동 호출된다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- 트랜잭션만 커밋하면 어떤 데이터도 데이터베이스에 반영되지 않는다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; 그래서 트랜잭션 커밋 전에 꼭 플러시를 호출해서 영속성 컨텍스트의 변경 내용을 데이터베이스에 반영해야한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp; 이런 문제를 방지하기 위해 JPA는 플러시를 자동 호출해야한다.&lt;/span&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;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;3. JPQL 쿼리 실행 시 플러시가 자동 호출된다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;- JPQL이나 Crieterial 같은 객체자향 쿼리를 호출할 때도 플러시가 실행된다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; background-color: #9feec3;&quot;&gt;☆ 플러시 모드 옵션&lt;/span&gt;&lt;/b&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; javax.persistence.FlushModeType을 사용하면 된다.&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;1. FlushModeType.AUTO : 커밋이나 쿼리를 실행할 때 프러시(기본값)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; - 플러시 모드를 별도로 설정하지 않으면 AUTO로 동작&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&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;2. FlushModeType.COMMIT: 커밋할 때만 플러시&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&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;&lt;a href=&quot;http://www.kyobobook.co.kr/product/detailViewKor.laf?ejkGb=KOR&amp;amp;mallGb=KOR&amp;amp;barcode=9788960777330&amp;amp;orderClick=LAG&amp;amp;Kc=&quot;&gt;http://www.kyobobook.co.kr/product/detailViewKor.laf?ejkGb=KOR&amp;amp;mallGb=KOR&amp;amp;barcode=9788960777330&amp;amp;orderClick=LAG&amp;amp;Kc=&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1658043574485&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;book&quot; data-og-title=&quot;자바 ORM 표준 JPA 프로그래밍 - 교보문고&quot; data-og-description=&quot;스프링 데이터 예제 프로젝트로 배우는 전자정부 표준 데이터베이스 프레임 | ★ 이 책에서 다루는 내용 ★■ JPA 기초 이론과 핵심 원리■ JPA로 도메인 모델을 설계하는 과정을 예제 중심으로 &quot; data-og-host=&quot;www.kyobobook.co.kr&quot; data-og-source-url=&quot;http://www.kyobobook.co.kr/product/detailViewKor.laf?ejkGb=KOR&amp;amp;mallGb=KOR&amp;amp;barcode=9788960777330&amp;amp;orderClick=LAG&amp;amp;Kc=&quot; data-og-url=&quot;http://www.kyobobook.co.kr/product/detailViewKor.laf?mallGb=KOR&amp;amp;ejkGb=KOR&amp;amp;barcode=9788960777330&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/R7UAg/hyO7Acz32P/Wnu2rSgE8VX9b5c4dGdMW1/img.jpg?width=458&amp;amp;height=609&amp;amp;face=0_0_458_609&quot;&gt;&lt;a href=&quot;http://www.kyobobook.co.kr/product/detailViewKor.laf?ejkGb=KOR&amp;amp;mallGb=KOR&amp;amp;barcode=9788960777330&amp;amp;orderClick=LAG&amp;amp;Kc=&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;http://www.kyobobook.co.kr/product/detailViewKor.laf?ejkGb=KOR&amp;amp;mallGb=KOR&amp;amp;barcode=9788960777330&amp;amp;orderClick=LAG&amp;amp;Kc=&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/R7UAg/hyO7Acz32P/Wnu2rSgE8VX9b5c4dGdMW1/img.jpg?width=458&amp;amp;height=609&amp;amp;face=0_0_458_609');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;자바 ORM 표준 JPA 프로그래밍 - 교보문고&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;스프링 데이터 예제 프로젝트로 배우는 전자정부 표준 데이터베이스 프레임 | ★ 이 책에서 다루는 내용 ★■ JPA 기초 이론과 핵심 원리■ JPA로 도메인 모델을 설계하는 과정을 예제 중심으로&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.kyobobook.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>차곡차곡/Java</category>
      <author>p퐝유p</author>
      <guid isPermaLink="true">https://nikeisme827.tistory.com/48</guid>
      <comments>https://nikeisme827.tistory.com/48#entry48comment</comments>
      <pubDate>Sun, 17 Jul 2022 16:39:46 +0900</pubDate>
    </item>
  </channel>
</rss>