<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>인지용</title>
    <link>https://clear-clouds.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Fri, 14 Aug 2026 15:28:49 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>인지용</managingEditor>
    <image>
      <title>인지용</title>
      <url>https://tistory1.daumcdn.net/tistory/4619516/attach/1f252cef975e4de694df9c5f8c452a6d</url>
      <link>https://clear-clouds.tistory.com</link>
    </image>
    <item>
      <title>[백준] 2257 화학식량 [python, 실버1, 스택]</title>
      <link>https://clear-clouds.tistory.com/200</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/2257&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.acmicpc.net/problem/2257&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1769131084995&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import sys

def input():
    return sys.stdin.readline().strip()

formula = list(input())
stack = []

for i in formula:
    if i == '(':
        stack.append(i)
    elif i == ')':
        temp = 0

        while stack:
            a = stack.pop()
            if a == '(':
                break
            else:
                temp += a
        stack.append(temp)
        
    elif i == 'H':
        stack.append(1)
    elif i == 'C':  
        stack.append(12)
    elif i == 'O':
        stack.append(16)
    else:
        stack.append(stack.pop() * int(i))

print(sum(stack))&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;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&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;&quot;)&quot; 가 나온다면 &quot;(&quot; 가 나올 때 까지의 모든 값을 스택에서 꺼내 전부 더한 뒤, 결과를 스택에 다시 넣는다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&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;숫자가 나온다면 스택 맨 마지막 값과 곱해주면 됨.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; 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;/p&gt;
&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;
&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>알고리즘</category>
      <author>인지용</author>
      <guid isPermaLink="true">https://clear-clouds.tistory.com/200</guid>
      <comments>https://clear-clouds.tistory.com/200#entry200comment</comments>
      <pubDate>Fri, 23 Jan 2026 10:38:26 +0900</pubDate>
    </item>
    <item>
      <title>[백준] 27497 알파벳 블록 [python, 실버1, 스택]</title>
      <link>https://clear-clouds.tistory.com/198</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/27497&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.acmicpc.net/problem/27497&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1768974390931&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import sys
from collections import deque

def input():
    return sys.stdin.readline().strip()

n = int(input())
dq = deque([])
orders = []

for i in range(n):
    arr = input().split()
    command = int(arr[0])

    if command == 1:
        dq.append(arr[1])
        orders.append(1)
    elif command == 2:
        dq.appendleft(arr[1])
        orders.append(0)
    else:
        if orders:
            a = orders.pop()

            if a == 1:
                dq.pop()
            else:
                dq.popleft()

if dq:
    print(&quot;&quot;.join(dq))
else:
    print(0)&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&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;현재 문자열은 덱에, 1, 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;3이 나온다면 기록용 배열에 존재하는 마지막 값을 보고&amp;nbsp; 분기쳐서 앞뒤중 어디서 pop 할건지 결정.&lt;/p&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;/p&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>알고리즘</category>
      <author>인지용</author>
      <guid isPermaLink="true">https://clear-clouds.tistory.com/198</guid>
      <comments>https://clear-clouds.tistory.com/198#entry198comment</comments>
      <pubDate>Wed, 21 Jan 2026 14:49:46 +0900</pubDate>
    </item>
    <item>
      <title>[백준] 11899 괄호 끼워넣기 [python, 실버3, 스택]</title>
      <link>https://clear-clouds.tistory.com/197</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/11899&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.acmicpc.net/problem/11899&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1768788139300&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import sys

def input():
    return sys.stdin.readline().strip()

text = input()

stack = []

for i in text:
    if i == '(':
        stack.append(i)
    else:
        if stack and stack[-1] == '(':
            stack.pop()
        else:
            stack.append(i)

print(len(stack))&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;style6&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;&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;</description>
      <category>알고리즘</category>
      <author>인지용</author>
      <guid isPermaLink="true">https://clear-clouds.tistory.com/197</guid>
      <comments>https://clear-clouds.tistory.com/197#entry197comment</comments>
      <pubDate>Mon, 19 Jan 2026 11:05:28 +0900</pubDate>
    </item>
    <item>
      <title>[백준] 4889 안정적인 문자열 [python, 실버1, 스택]</title>
      <link>https://clear-clouds.tistory.com/196</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/4889&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.acmicpc.net/problem/4889&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1768786132421&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import sys

def input():
    return sys.stdin.readline().strip()

idx = 1

while True:
    text = input()

    if text.startswith(&quot;-&quot;):
        break

    arr = list(text)
    stack = []

    for i in arr:
        if i == '{':
            stack.append(i)
            continue
        else:
            if stack and stack[-1] == '{':
                stack.pop()
            else:
                stack.append(i)

    num = 0

    for i in range(0, len(stack), 2):
        if stack[i] == stack[i+1]:
            num += 1
        else:
            num += 2

    print(f&quot;{idx}. {num}&quot;)
    idx += 1&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;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 원본 배열에서 안정적인 문자열을 다 제거하고 남은 값들을 변환시켜주면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;입력은 무조건 짝수라고 했으니 반복문을 2씩 증가시키고 값이&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;{ { 혹은 } } 와 같이 같은 값이라면 하나만 바꾸면 되니까 + 1을&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;&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>알고리즘</category>
      <author>인지용</author>
      <guid isPermaLink="true">https://clear-clouds.tistory.com/196</guid>
      <comments>https://clear-clouds.tistory.com/196#entry196comment</comments>
      <pubDate>Mon, 19 Jan 2026 10:37:58 +0900</pubDate>
    </item>
    <item>
      <title>[백준] 2841 외계인의 기타 연주 [python, 실버1, 스택]</title>
      <link>https://clear-clouds.tistory.com/195</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/2841&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.acmicpc.net/problem/2841&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1768545201889&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import sys

def input():
    return sys.stdin.readline().strip()

arr = list(map(int, input().split()))
stack = [[] for _ in range(7)]
count = 0

for i in range(arr[0]):

    temp = list(map(int, input().split()))
    K = temp[0]
    P = temp[1]

    if not stack[K] or stack[K][-1] &amp;lt; P:
        stack[K].append(P)
        count += 1
    else:
        while True:
            if not stack[K] or stack[K][-1] &amp;lt; P:
                stack[K].append(P)
                count += 1
                break
            elif stack[K][-1] == P:
                break
            else:
                stack[K].pop()
                count += 1

print(count)&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&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>알고리즘</category>
      <author>인지용</author>
      <guid isPermaLink="true">https://clear-clouds.tistory.com/195</guid>
      <comments>https://clear-clouds.tistory.com/195#entry195comment</comments>
      <pubDate>Fri, 16 Jan 2026 15:35:24 +0900</pubDate>
    </item>
    <item>
      <title>[백준] 1935 후위 표기식2 [python, 실버3, 스택]</title>
      <link>https://clear-clouds.tistory.com/194</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/1935&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.acmicpc.net/problem/1935&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1768442079090&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import sys
import operator

def input():
    return sys.stdin.readline().strip()

n = int(input())
text = list(input())
stack = []
nums = []
ops = {
    '+': operator.add,
    '-': operator.sub,
    '*': operator.mul,
    '/': operator.truediv
}

for i in range(n):
    nums.append(int(input()))

for i in text:
    if i.isalpha():
        index = ord(i) - ord('A')
        stack.append(nums[index])
    else:
        a = stack.pop()
        b = stack.pop()
        stack.append(ops[i](b, a))

print(&quot;{:.2f}&quot;.format(stack.pop()))&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;style6&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;후위표기식이 나오면 스택 마지막 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;문자열이라고해서 신규 입력을 받으면 실패.. (내가 처음에 그랬음 ㅎ)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>알고리즘</category>
      <author>인지용</author>
      <guid isPermaLink="true">https://clear-clouds.tistory.com/194</guid>
      <comments>https://clear-clouds.tistory.com/194#entry194comment</comments>
      <pubDate>Thu, 15 Jan 2026 10:57:08 +0900</pubDate>
    </item>
    <item>
      <title>윈도우에서 와이어샤크로 패킷 덤프해보기</title>
      <link>https://clear-clouds.tistory.com/193</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;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.wireshark.org/download.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.wireshark.org/download.html&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&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. 와이어샤크가 있는 폴더로 이동&lt;/p&gt;
&lt;pre id=&quot;code_1769747334229&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;cd C:\Program Files\Wireshark&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 목록 조회&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(로컬 통신을 보려면&amp;nbsp; Loopback 보면 됨, 9번째에 있네)&lt;/p&gt;
&lt;pre id=&quot;code_1769747357147&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;dumpcap.exe -D&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&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;786&quot; data-origin-height=&quot;78&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bVkshT/dJMcaaYkAWi/575uTijSPJZvVGgz2J0aTK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bVkshT/dJMcaaYkAWi/575uTijSPJZvVGgz2J0aTK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bVkshT/dJMcaaYkAWi/575uTijSPJZvVGgz2J0aTK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbVkshT%2FdJMcaaYkAWi%2F575uTijSPJZvVGgz2J0aTK%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;655&quot; height=&quot;65&quot; data-origin-width=&quot;786&quot; data-origin-height=&quot;78&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 덤프를 떠보자. (기록을 남긴다는 의미)&lt;/p&gt;
&lt;pre id=&quot;code_1769747419108&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;dumpcap.exe -i 번호 -w 덤프파일명.pcap
ex) dumpcap.exe -i 9 -w test.pcap&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1441&quot; data-origin-height=&quot;199&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/o31uZ/dJMcacu4QDW/yYmQb5kkjGKAMCIkWXtvM1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/o31uZ/dJMcacu4QDW/yYmQb5kkjGKAMCIkWXtvM1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/o31uZ/dJMcacu4QDW/yYmQb5kkjGKAMCIkWXtvM1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fo31uZ%2FdJMcacu4QDW%2FyYmQb5kkjGKAMCIkWXtvM1%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;1441&quot; height=&quot;199&quot; data-origin-width=&quot;1441&quot; data-origin-height=&quot;199&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;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 test.pcap을 확인해보자&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;1371&quot; data-origin-height=&quot;800&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/baHbyK/dJMcai24NdM/sNvK7hCcfTdZsu0RtCR4F0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/baHbyK/dJMcai24NdM/sNvK7hCcfTdZsu0RtCR4F0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/baHbyK/dJMcai24NdM/sNvK7hCcfTdZsu0RtCR4F0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbaHbyK%2FdJMcai24NdM%2FsNvK7hCcfTdZsu0RtCR4F0%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;531&quot; height=&quot;310&quot; data-origin-width=&quot;1371&quot; data-origin-height=&quot;800&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;pre id=&quot;code_1769747535989&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;원하는 로그 우클릭 &amp;gt; 따라가기 &amp;gt; TCP 스트림 &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;&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;499&quot; data-origin-height=&quot;439&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/blYSna/dJMcafSSUWg/ylicZGBkV0xPMcOMfqdCE1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/blYSna/dJMcafSSUWg/ylicZGBkV0xPMcOMfqdCE1/img.png&quot; data-alt=&quot;결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/blYSna/dJMcafSSUWg/ylicZGBkV0xPMcOMfqdCE1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FblYSna%2FdJMcafSSUWg%2FylicZGBkV0xPMcOMfqdCE1%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;499&quot; height=&quot;439&quot; data-origin-width=&quot;499&quot; data-origin-height=&quot;439&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <author>인지용</author>
      <guid isPermaLink="true">https://clear-clouds.tistory.com/193</guid>
      <comments>https://clear-clouds.tistory.com/193#entry193comment</comments>
      <pubDate>Wed, 14 Jan 2026 17:30:45 +0900</pubDate>
    </item>
    <item>
      <title>[백준] 12789 도키도키 간식드리미 [python, 실버2, 스택]</title>
      <link>https://clear-clouds.tistory.com/192</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/12789&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.acmicpc.net/problem/12789&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1768371338347&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import sys

def input():
    return sys.stdin.readline().strip()


n = int(input())
arr = list(map(int, input().split()))
stack = []
result = []
target = 1

for i in range(n):
    if arr[i] == target:
        result.append(arr[i])
        target += 1

        while stack and stack[-1] == target:
            result.append(stack.pop())
            target += 1
    else:
        stack.append(arr[i])

if len(result) == n:
    print(&quot;Nice&quot;)
else:
    print(&quot;Sad&quot;)&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;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재&amp;nbsp;번호표와&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;&lt;br /&gt;이걸&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;다음&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;&lt;br /&gt;이걸&amp;nbsp;반복해서&amp;nbsp;간식&amp;nbsp;받은&amp;nbsp;사람의&amp;nbsp;수를&amp;nbsp;비교해보면&amp;nbsp;된다. &lt;br /&gt;&lt;br /&gt;(중간 while문을 엉뚱한데 넣어서 많이 헤맸다..)&lt;/p&gt;</description>
      <category>알고리즘</category>
      <author>인지용</author>
      <guid isPermaLink="true">https://clear-clouds.tistory.com/192</guid>
      <comments>https://clear-clouds.tistory.com/192#entry192comment</comments>
      <pubDate>Wed, 14 Jan 2026 15:16:24 +0900</pubDate>
    </item>
    <item>
      <title>io.debezium.DebeziumException: The db history topic is missing 에러</title>
      <link>https://clear-clouds.tistory.com/183</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;kafka 사용중 에러가 발생했다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;io.debezium.DebeziumException:&amp;nbsp;The&amp;nbsp;db&amp;nbsp;history&amp;nbsp;topic&amp;nbsp;is&amp;nbsp;missing&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전체 에러 메시지&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&quot;name&quot;:&amp;nbsp;&quot;mysql-coin-connector&quot;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&quot;connector&quot;:&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;state&quot;:&amp;nbsp;&quot;RUNNING&quot;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;worker_id&quot;:&amp;nbsp;&quot;127.0.0.1:8083&quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;},&lt;br /&gt;&amp;nbsp;&amp;nbsp;&quot;tasks&quot;:&amp;nbsp;[&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;id&quot;:&amp;nbsp;0,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;state&quot;:&amp;nbsp;&quot;FAILED&quot;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;worker_id&quot;:&amp;nbsp;&quot;127.0.0.1:8083&quot;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;trace&quot;:&amp;nbsp;&quot;io.debezium.DebeziumException:&amp;nbsp;The&amp;nbsp;db&amp;nbsp;history&amp;nbsp;topic&amp;nbsp;is&amp;nbsp;missing.&amp;nbsp;You&amp;nbsp;may&amp;nbsp;attempt&amp;nbsp;to&amp;nbsp;recover&amp;nbsp;it&amp;nbsp;by&amp;nbsp;reconfiguring&amp;nbsp;the&amp;nbsp;connector&amp;nbsp;to&amp;nbsp;recovery.\n\tat&amp;nbsp;io.debeziu&lt;a href=&quot;http://m.connector.common.BaseSourceTask.validateSchemaHistory(BaseSourceTask.java:135)&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;http://m.connector.common.BaseSourceTask.validateSchemaHistory(BaseSourceTask.java:135)&lt;/a&gt;\n\tat&amp;nbsp;io.debeziu&lt;a href=&quot;http://m.connector.mysql.MySqlConnectorTask.start(MySqlConnectorTask.java:138)&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;http://m.connector.mysql.MySqlConnectorTask.start(MySqlConnectorTask.java:138)&lt;/a&gt;\n\tat&amp;nbsp;io.debeziu&lt;a href=&quot;http://m.connector.common.BaseSourceTask.start(BaseSourceTask.java:260)&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;http://m.connector.common.BaseSourceTask.start(BaseSourceTask.java:260)&lt;/a&gt;\n\tat&amp;nbsp;org.apache.kafka.connect.runtime.AbstractWorkerSourceTask.initializeAndStart(AbstractWorkerSourceTask.java:279)\n\tat&amp;nbsp;org.apache.kafka.connect.runtime.WorkerTask.doStart(WorkerTask.java:176)\n\tat&amp;nbsp;org.apache.kafka.connect.runtime.WorkerTask.doRun(WorkerTask.java:225)\n\tat&amp;nbsp;org.apache.kafka.connect.runtime.WorkerTask.run(WorkerTask.java:281)\n\tat&amp;nbsp;org.apache.kafka.connect.runtime.AbstractWorkerSourceTask.run(AbstractWorkerSourceTask.java:79)\n\tat&amp;nbsp;org.apache.kafka.connect.runtime.isolation.Plugins.lambda$withClassLoader$1(Plugins.java:238)\n\tat&amp;nbsp;java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539)\n\tat&amp;nbsp;java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)\n\tat&amp;nbsp;java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)\n\tat&amp;nbsp;java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)\n\tat&amp;nbsp;java.base/java.lang.Thread.run(Thread.java:833)\n&quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;],&lt;br /&gt;&amp;nbsp;&amp;nbsp;&quot;type&quot;:&amp;nbsp;&quot;source&quot;&lt;br /&gt;}&lt;/p&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ddl 변경 후 꼬여서 CDC가 안돼서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;mysql source connector json의 &quot;schema.history.internal.kafka.topic&quot; 옵션에 설정된 토픽을 지웠었다.&lt;/p&gt;
&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;h4 data-ke-size=&quot;size20&quot;&gt;임시 해결방법&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. connector json의 name 변경해주기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. snapshot.mode: initial 옵션 추가&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1760367686006&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{
  &quot;name&quot;: &quot;mysql-coin-connector&quot;,  &amp;lt;- 1. name 변경
  &quot;config&quot;: {
    &quot;connector.class&quot;: &quot;io.debezium.connector.mysql.MySqlConnector&quot;,
    &quot;tasks.max&quot;: &quot;1&quot;,
    &quot;database.hostname&quot;: &quot;localhost&quot;,
    &quot;database.port&quot;: &quot;3306&quot;,
    &quot;database.user&quot;: &quot;test&quot;,
    &quot;database.password&quot;: test
    &quot;database.include.list&quot;: &quot;test1&quot;,
    &quot;database.server.id&quot;: &quot;184055&quot;,
    &quot;snapshot.mode&quot;: &quot;initial&quot; &amp;lt;- 2. 추가
	...
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&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;전체 json&lt;/p&gt;
&lt;pre id=&quot;code_1760424925439&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{
  &quot;name&quot;: &quot;mysql-coin-connector&quot;,
  &quot;config&quot;: {
    &quot;connector.class&quot;: &quot;io.debezium.connector.mysql.MySqlConnector&quot;,
    &quot;tasks.max&quot;: &quot;1&quot;,
    &quot;database.hostname&quot;: &quot;localhost&quot;,
    &quot;database.port&quot;: &quot;3306&quot;,
    &quot;database.user&quot;: &quot;test&quot;,
    &quot;database.password&quot;: &quot;test&quot;,
    &quot;database.include.list&quot;: &quot;test1&quot;,
    &quot;database.server.id&quot;: &quot;184057&quot;,
    &quot;database.connectionTimeZone&quot;: &quot;Asia/Seoul&quot;,
    &quot;table.include.list&quot;: &quot;test1.TB_MARKET_ORDER,test1.TB_COIN_TRADE_HIST&quot;,
    &quot;topic.prefix&quot;: &quot;mysqlserver&quot;,
    
    &quot;schema.history.internal.kafka.bootstrap.servers&quot;: &quot;localhost:9092&quot;,
    &quot;schema.history.internal.kafka.topic&quot;: &quot;schemahistory.v3&quot;,
    &quot;snapshot.mode&quot;: &quot;initial&quot;,
    
    &quot;key.converter&quot;: &quot;org.apache.kafka.connect.storage.StringConverter&quot;,
    &quot;value.converter&quot;: &quot;org.apache.kafka.connect.json.JsonConverter&quot;,
    &quot;value.converter.schemas.enable&quot;: &quot;false&quot;,
    
    &quot;transforms&quot;: &quot;unwrap, extractKey&quot;,
    &quot;transforms.extractKey.type&quot;: &quot;org.apache.kafka.connect.transforms.ExtractField$Key&quot;,
    &quot;transforms.extractKey.field&quot;: &quot;id&quot;,
    &quot;transforms.unwrap.type&quot;: &quot;io.debezium.transforms.ExtractNewRecordState&quot;,
    &quot;transforms.unwrap.drop.tombstones&quot;: &quot;true&quot;,
    &quot;transforms.unwrap.delete.handling.mode&quot;: &quot;rewrite&quot;,
    
    &quot;errors.tolerance&quot;: &quot;all&quot;,
    &quot;errors.log.enable&quot;: &quot;true&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;&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://groups.google.com/g/debezium/c/IO55ZeAEM14&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://groups.google.com/g/debezium/c/IO55ZeAEM14&lt;/a&gt;&lt;/p&gt;</description>
      <author>인지용</author>
      <guid isPermaLink="true">https://clear-clouds.tistory.com/183</guid>
      <comments>https://clear-clouds.tistory.com/183#entry183comment</comments>
      <pubDate>Tue, 14 Oct 2025 00:11:33 +0900</pubDate>
    </item>
    <item>
      <title>SpringBoot Kafka auto-offset-reset 옵션이 적용 안되던 건에 대하여</title>
      <link>https://clear-clouds.tistory.com/180</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;auto-offset-reset 옵션이란&lt;/h4&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&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;(오프셋을 커밋한 적이 없거나, 오프셋의 레코드가 브로커에서 삭제된 경우)&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;ex) 컨슈머 그룹이 처음 만들어졌을 때&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;옵션은 3가지가 있다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;earliest: 파티션의 맨 처음부터 모든 데이터를 읽음&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;latest (기본값): 가장 최신 레코드부터 읽음 (컨슈머 작동하기 시작한 다음부터 쓰여진 레코드부터)&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;none: 유효하지 않은 오프셋부터 읽으려고 하면 예외 발생&lt;/p&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;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;auto-offset-reset 옵션 테스트 해보기&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;적용이 안되는 문제의 코드&lt;/h4&gt;
&lt;div style=&quot;background-color: #1e1f22; color: #bcbec4;&quot;&gt;
&lt;pre class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot;&gt;&lt;code&gt;package com.min.mockcoin.infrastructure.kafka

import org.apache.kafka.clients.consumer.ConsumerConfig
import org.apache.kafka.clients.producer.ProducerConfig
import org.apache.kafka.common.serialization.StringDeserializer
import org.apache.kafka.common.serialization.StringSerializer
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.kafka.annotation.EnableKafka
import org.springframework.kafka.config.ConcurrentKafkaListenerContainerFactory
import org.springframework.kafka.core.*
import org.springframework.kafka.support.serializer.JsonSerializer


@EnableKafka
@Configuration
class KafkaConfig {

    @Bean
    fun consumerFactory(): ConsumerFactory&amp;lt;String, String&amp;gt; {
        val configProps: MutableMap&amp;lt;String, Any&amp;gt; = HashMap()
        configProps.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, &quot;localhost:9092&quot;)
        configProps.put(ConsumerConfig.GROUP_ID_CONFIG, &quot;mockcoin&quot;)
        configProps.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer::class.java)
        configProps.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer::class.java)
        return DefaultKafkaConsumerFactory(configProps)
    }

    @Bean
    fun producerFactory(): ProducerFactory&amp;lt;String, String&amp;gt; {
        val configProps: MutableMap&amp;lt;String, Any&amp;gt; = HashMap()
        configProps.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, &quot;localhost:9092&quot;)
        configProps.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer::class.java)
        configProps.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JsonSerializer::class.java)
        return DefaultKafkaProducerFactory(configProps)
    }

    @Bean
    fun kafkaListenerContainerFactory(): ConcurrentKafkaListenerContainerFactory&amp;lt;String, String&amp;gt; {
        val factory = ConcurrentKafkaListenerContainerFactory&amp;lt;String, String&amp;gt;()
        factory.consumerFactory = consumerFactory()
        return factory
    }

    @Bean
    fun kafkaTemplate(): KafkaTemplate&amp;lt;String, String&amp;gt; {
        return KafkaTemplate(producerFactory())
    }

}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div style=&quot;background-color: #1e1f22; color: #bcbec4;&quot;&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;spring:
  config:
    activate:
      on-profile: local
  data:
    redis:
      host: localhost
      port: 6379
  kafka:
    bootstrap-servers: localhost:9092
    producer:
      key-serializer: org.apache.kafka.common.serialization.StringSerializer
      value-serializer: org.springframework.kafka.support.serializer.JsonSerializer
    consumer:
      key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
      value-deserializer: org.apache.kafka.common.serialization.StringDeserializer&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;div style=&quot;background-color: #1e1f22; color: #bcbec4;&quot;&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;@KafkaListener(topics = arrayOf(&quot;mysqlserver.test1.TB_MARKET_ORDER&quot;), groupId = &quot;test-group3&quot;)
fun consume3(message: String) {
    println(&quot;컨슈머3 데이터 받기 성공!!!! message = ${message}&quot;)
}&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-ke-size=&quot;size16&quot;&gt;mysqlserver.test1.TB_MARKET_ORDER 토픽에는 이미 여러 데이터들이 있는 상황.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;@KafkaListener에 새로운 컨슈머 그룹 (&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;test-group3)을 적어주고 서버를 실행했다.&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;예상대로라면 맨 처음 데이터부터 데이터 개수만큼 println 구문이 실행돼야했다.&lt;/p&gt;
&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;h4 data-ke-size=&quot;size20&quot;&gt;원인&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원인은 설정에 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;yml에 카프카 설정을 적어두면 KafkaTemplate, ConsumerFactory 등이 자동으로 빈으로 등록된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;근데 나는 또 ConsumerFactory를 직접 빈으로 정의했고,&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;auto-offset-reset 옵션을 안 넣었었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉 yml이 만든 빈을 덮어쓴 것이지..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 아무리 yml에 auto-offset-reset 설정을 적용해도 소용이 없었다.&lt;/p&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;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. ConsumerFactory Bean 등록 하지말고 yml만 설정하기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 직접 선언한 ConsumerFactory Bean에 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;auto-offset-reset&lt;span&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;나는 1번 방법을 사용했다.&lt;/p&gt;
&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;예상대로 토픽 맨 처음 데이터부터 끝까지 println이 찍혔다. bbb&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;(나는 컨슈머, 프로듀서 모두 yml 설정으로 쓰기 위해서 클래스 자체를 주석처리함)&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;정상 동작 코드&lt;/h4&gt;
&lt;div style=&quot;background-color: #1e1f22; color: #bcbec4;&quot;&gt;
&lt;pre class=&quot;awk&quot;&gt;&lt;code&gt;//package com.min.mockcoin.infrastructure.kafka
//
//import org.apache.kafka.clients.consumer.ConsumerConfig
//import org.apache.kafka.clients.producer.ProducerConfig
//import org.apache.kafka.common.serialization.StringDeserializer
//import org.apache.kafka.common.serialization.StringSerializer
//import org.springframework.context.annotation.Bean
//import org.springframework.context.annotation.Configuration
//import org.springframework.kafka.annotation.EnableKafka
//import org.springframework.kafka.config.ConcurrentKafkaListenerContainerFactory
//import org.springframework.kafka.core.*
//import org.springframework.kafka.support.serializer.JsonSerializer
//
//
//@EnableKafka
//@Configuration
//class KafkaConfig {
//
//    @Bean
//    fun consumerFactory(): ConsumerFactory&amp;lt;String, String&amp;gt; {
//        val configProps: MutableMap&amp;lt;String, Any&amp;gt; = HashMap()
//        configProps.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, &quot;localhost:9092&quot;)
//        configProps.put(ConsumerConfig.GROUP_ID_CONFIG, &quot;mockcoin&quot;)
//        configProps.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer::class.java)
//        configProps.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer::class.java)
//        return DefaultKafkaConsumerFactory(configProps)
//    }
//
//    @Bean
//    fun producerFactory(): ProducerFactory&amp;lt;String, String&amp;gt; {
//        val configProps: MutableMap&amp;lt;String, Any&amp;gt; = HashMap()
//        configProps.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, &quot;localhost:9092&quot;)
//        configProps.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer::class.java)
//        configProps.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JsonSerializer::class.java)
//        return DefaultKafkaProducerFactory(configProps)
//    }
//
//    @Bean
//    fun kafkaListenerContainerFactory(): ConcurrentKafkaListenerContainerFactory&amp;lt;String, String&amp;gt; {
//        val factory = ConcurrentKafkaListenerContainerFactory&amp;lt;String, String&amp;gt;()
//        factory.consumerFactory = consumerFactory()
//        return factory
//    }
//
//    @Bean
//    fun kafkaTemplate(): KafkaTemplate&amp;lt;String, String&amp;gt; {
//        return KafkaTemplate(producerFactory())
//    }
//
//}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;background-color: #1e1f22; color: #bcbec4;&quot;&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;spring:
  config:
    activate:
      on-profile: local
  data:
    redis:
      host: localhost
      port: 6379
  kafka:
    bootstrap-servers: localhost:9092
    producer:
      key-serializer: org.apache.kafka.common.serialization.StringSerializer
      value-serializer: org.springframework.kafka.support.serializer.JsonSerializer
    consumer:
      group-id: market-group
      auto-offset-reset: earliest
      key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
      value-deserializer: org.apache.kafka.common.serialization.StringDeserializer&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;background-color: #1e1f22; color: #bcbec4;&quot;&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;@KafkaListener(topics = arrayOf(&quot;mysqlserver.test1.TB_MARKET_ORDER&quot;), groupId = &quot;new-test-group4&quot;)
fun consume3(message: String) {
    println(&quot;컨슈머3 데이터 받기 성공!!!! message = ${message}&quot;)
}&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-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;결론&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 간단하게 쓰려면 yml에만 카프카 설정 정보 적어주기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. yml에 카프카 설정을 썼다면 같은 빈을 직접 등록하지 말기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 직접 빈을 등록할 거면 필요한 옵션 다 넣어주기&lt;/p&gt;</description>
      <category>정보들</category>
      <category>auto-offset-reset</category>
      <category>Kafka</category>
      <category>springboot</category>
      <author>인지용</author>
      <guid isPermaLink="true">https://clear-clouds.tistory.com/180</guid>
      <comments>https://clear-clouds.tistory.com/180#entry180comment</comments>
      <pubDate>Fri, 3 Oct 2025 16:05:15 +0900</pubDate>
    </item>
  </channel>
</rss>