<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>RegularKim</title>
        <link>https://velog.io/</link>
        <description>What doesn't kill you, makes you stronger</description>
        <lastBuildDate>Sun, 08 Mar 2026 12:43:48 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>RegularKim</title>
            <url>https://velog.velcdn.com/images/regular_jk_kim/profile/832447fc-ff25-4733-b894-af65cbbd7048/image.jpeg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. RegularKim. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/regular_jk_kim" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[로그]]></title>
            <link>https://velog.io/@regular_jk_kim/%EB%A1%9C%EA%B7%B8</link>
            <guid>https://velog.io/@regular_jk_kim/%EB%A1%9C%EA%B7%B8</guid>
            <pubDate>Sun, 08 Mar 2026 12:43:48 GMT</pubDate>
            <description><![CDATA[<p>#logger</p>
<h1 id="로그">로그</h1>
<h2 id="주로-저장되는-로그-내용">주로 저장되는 로그 내용</h2>
<ol>
<li>요청/응답 <ul>
<li>목적 : 사용자가 어떤 요청을 보냈고, 시스템이 어떻게 응답했는지 기록</li>
<li>디버깅, 성능 분석</li>
</ul>
</li>
<li>오류 및 예외<ul>
<li>목적 : 시스템에서 발생한 오류와 예외 상황을 기록하여 디버깅에 활용</li>
<li>장애 대응</li>
</ul>
</li>
<li>사용자 활동<ul>
<li>목적 : 사용자 행동 기록을 통한 서비스 이용 흐름 및 보안 감사 추적</li>
<li>법적으로 남겨야 하는 로그들이 이에 해당</li>
<li>감사, 사용 분석</li>
</ul>
</li>
<li>시스템 상태 : 모니터링</li>
<li>데이터베이스 쿼리 : 성능 최적화</li>
<li>보안 : 침해 대응</li>
<li>배치 작업 : 모니터링</li>
<li>디버깅 : 추적</li>
</ol>
<h2 id="로그-레벨">로그 레벨</h2>
<ol>
<li>TRACE<ul>
<li>추적</li>
<li>가장 상세한 정보를 남김</li>
<li>코드가 한 줄 한 줄 어떻게 실행 되는지 경로를 추적함</li>
<li>평소에는 상시로 켜두지 않음 (용량 문제)</li>
<li>일시적으로 켜서 확인하고 다시 끄는 용도</li>
<li>3일치 로그만 보관 (예시)</li>
</ul>
</li>
<li>DEBUG<ul>
<li>디버그</li>
<li>시스템의 작동 상태를 상세하게 기록함</li>
<li>서비스 개발 과정에서 주요하게 확인해야 하는 값들이나 버그들을 기록함</li>
<li>주로 개발 환경에서 코드를 테스트하고, 버그를 찾을 때 사용하고 운영환경에서는 보통 꺼두는 것이 일반적</li>
</ul>
</li>
<li>INFO<ul>
<li>정보</li>
<li>시스템이 예상대로 정상적으로 작동하고 있음을 알려줌</li>
<li>운영 환경에서 가장 기본적으로 켜두는 레벨</li>
<li>서버 시작, 사용자 로그인 완료, 배치 작업 완료와 같이 의미있는 주요 흐름을 기록함</li>
<li>어떤 레벨로 로그를 찍어야할지 모르겠다면 INFO 레벨로 찍어도 무방</li>
</ul>
</li>
<li>WARN<ul>
<li>경고</li>
<li>당장 시스템이 멈추거나 에러가 난 것은 아니지만, 잠재적인 문제가 될 수 있는 상황</li>
<li>데이터가 쌓일수록 외부 API 응답이 점점 지연되는 경우처럼 추후에 문제가 일어날 것 같은 부분을 미리 표시</li>
<li>1분간 10회 이상 발생시 알람 + 일단위 리포트 (예시)</li>
</ul>
</li>
<li>ERROR<ul>
<li>에러</li>
<li>시스템의 특정 기능에 오류가 발생하여, 요청 작업을 정상적으로 처리하지 못하는 상황</li>
<li>DB 저장 중 예외 발생, 결제 API 호출 실패 등의 장애 상황</li>
<li>1회라도 발생시 알람 (예시)</li>
</ul>
</li>
<li>FATAL<ul>
<li>치명적 오류</li>
<li>애플리케이션이나 시스템 전체가 다운되어 더 이상 서비스를 제공할 수 없는 상태</li>
<li>DB 서버 중단/장애, 메모리 부족으로 서버 강제 종료 등 심각한 오류 발생</li>
<li>1회라도 발생시 알람 (예시)</li>
</ul>
</li>
</ol>
<h2 id="slf4j">Slf4j</h2>
<blockquote>
<p>Simple Logging Facade for Java</p>
</blockquote>
<ul>
<li>Facade : 껍데기, 인터페이스</li>
<li>간단하게 로그를 찍어볼 수 있는 인터페이스이다.</li>
</ul>
<h3 id="예전에-로그-설정하던-방법">예전에 로그 설정하던 방법</h3>
<pre><code class="language-java">import org.slf4j.Logger
import org.slf4j.LoggerFactory

public class TestClass {

    private static final Logger log = LoggerFactory.getLogger(TestClass.class)
}</code></pre>
<h3 id="롬복을-활용한-요즘-설정-방법">롬복을 활용한 요즘 설정 방법</h3>
<pre><code class="language-java">
@Slf4j
public class TestClass {
}</code></pre>
<h2 id="코드로-로그-레벨-이해하기">코드로 로그 레벨 이해하기</h2>
<p>웨이팅 등록 서비스 예시를 통해서 로그 레벨을 이해해보자.</p>
<pre><code class="language-java">@Slf4j
@Service
public class TestClass {

    private int currentWaitingCount = 0; // 현재 대기 번호
    private final Set&lt;String&gt; registeredPhones = new HashMap&lt;&gt;(); // 중복 등록 방지

    public String registerWaiting(String name, String phone) {
        String maskedPhone = maskPhoneNumber(phone);

        // 1. [INFO] : 일반적인 비즈니스 흐름 기록
        log.info(&quot;[웨이팅 요청] 이름 : {}, 연락처 : {}&quot;, name, maskedPhone);

        // 2. [ERROR] : 비즈니스 오류 (중복 등록 시도)
        if (registeredPhones.contains(phone)) {
            log.error(&quot;[웨이팅 실패] 중복 등록 시도 발생! 연락처 : {}&quot;, maskedPhone);
            throw new IllegalArgumentException(&quot;이미 대기 등록된 연락처입니다.&quot;);
        }

        // 3. [WARN] 시스템 경고 (대기열 마감 임박)
        if (currentWaitingCount &gt;= 45) {
            log.warn(&quot;[웨이팅 경고] 대기열 마감 임박! 현재 대기 인원 : {}명&quot;, currentWaitingCount);
        }

        registeredPhones.add(phone);
        currentWaitingCount++;

        // 4. [INFO] 비즈니스 정상 처리 완료
        log.info(&quot;[웨이팅 완료] 대기번호 {}번 발급 완료 (고객명 : {})&quot;, currentWaitingCount, name);

        return name + &quot;님, 대기번호 &quot; + currentWaitingCount + &quot;번이 발급되었습니다.&quot;;
    }

    private String maskPhoneNumver(String phone) {
        if (phone == null || phone.length() &lt; 13) return &quot;****&quot;;
        return phone.substring(0, 4) + &quot;****&quot; + phone.substring(8);
    }
}</code></pre>
<h2 id="로그-구성-요소">로그 구성 요소</h2>
<p>로그는 8개의 조각으로 나뉜다. 아래 로그 예시를 통해 살펴보자.</p>
<pre><code class="language-text">2026-03-08 17:12:03.421+09:00  INFO 18324 --- [test-server] [nio-8080-exec-1] c.k.api.user.UserController              : Get user request. userId=42
2026-03-08 17:12:03.438+09:00  INFO 18324 --- [test-server] [nio-8080-exec-1] c.k.service.user.UserService             : Fetching user from database. userId=42
2026-03-08 17:12:03.462+09:00  INFO 18324 --- [test-server] [nio-8080-exec-1] c.k.repository.user.UserRepository       : User entity loaded. id=42
2026-03-08 17:12:03.471+09:00  INFO 18324 --- [test-server] [nio-8080-exec-1] c.k.api.user.UserController              : Response success. userId=42</code></pre>
<h3 id="1-시간-timestamp">1. 시간 (Timestamp)</h3>
<pre><code class="language-text">2026-03-08 17:12:03.421+09:00
2026-03-08 17:12:03.438+09:00
2026-03-08 17:12:03.462+09:00
2026-03-08 17:12:03.471+09:00</code></pre>
<ul>
<li>로그가 발생한 시간 (제일 중요한 정보 중 하나)</li>
<li>+는 시간대(Timezone)를 의미한다. 여기서는 세계 표준시보다 9시간 빠르다는 뜻이다.</li>
</ul>
<h3 id="2-로그-레벨-log-level">2. 로그 레벨 (Log Level)</h3>
<pre><code class="language-text">INFO
INFO
INFO
INFO</code></pre>
<ul>
<li>로그 레벨을 확인하여, 얼마나 중요도 있는 로그인지 파악</li>
</ul>
<h3 id="3-프로세스-아이디-pid">3. 프로세스 아이디 (PID)</h3>
<pre><code class="language-text">18324
18324
18324
18324</code></pre>
<ul>
<li>서버 하나에 여러 개의 프로그램이 띄워져 있을 때, PID로 구분할 수 있다.</li>
</ul>
<h3 id="4-구분선-separator">4. 구분선 (Separator)</h3>
<pre><code class="language-text">---
---
---
---</code></pre>
<ul>
<li>시각적인 구분선</li>
<li>구분선 앞은 메타데이터</li>
<li>구분선 뒤는 애플리케이션 내부 정보</li>
</ul>
<h3 id="5-애플리케이션-이름">5. 애플리케이션 이름</h3>
<pre><code class="language-text">[test-server]
[test-server]
[test-server]
[test-server]</code></pre>
<ul>
<li>대괄호 안에 있는 이름이 애플리케이션의 이름</li>
<li>여러 서버의 로그가 한 곳에 모였을 때 이름을 보고 출처를 확인할 수 있음</li>
</ul>
<h3 id="6-스레드-이름">6. 스레드 이름</h3>
<pre><code class="language-text">[nio-8080-exec-1]
[nio-8080-exec-1]
[nio-8080-exec-1]
[nio-8080-exec-1]</code></pre>
<ul>
<li>서버는 동시에 여러명의 요청을 처리하기 위해 스레드를 두고 작동</li>
<li>8080포트에서 들어온 요청을 처리하는 1번 스레드라는 뜻</li>
<li>어떤 요처을 처리하다가 에러가 났다면, 해당 스레드만 확인하면 됨</li>
</ul>
<h3 id="7-클래스명">7. 클래스명</h3>
<pre><code class="language-text">c.k.api.user.UserController
c.k.service.user.UserService
c.k.repository.user.UserRepository
c.k.api.user.UserController</code></pre>
<ul>
<li>로그를 남긴 구체적인 위치</li>
</ul>
<h3 id="8-로그-메시지">8. 로그 메시지</h3>
<pre><code class="language-text">: Get user request. userId=42
: Fetching user from database. userId=42
: User entity loaded. id=42
: Response success. userId=42</code></pre>
<ul>
<li>콜론 뒤에 이어지는 부분이 실제 메시지 본문</li>
</ul>
<h2 id="로그-관리-방법">로그 관리 방법</h2>
<blockquote>
<p>단순히 로그를 쌓기만 하는 것이 아니라, 모니터링 도구를 연동하여 관리한다.</p>
</blockquote>
<ol>
<li>Elasticsearch : 방대한 양의 텍스트 로그 데이터 속에서 원하는 에러 메시지나 특정 기록을 빠르게 검색할 수 있도록 저장하는 분산 검색 엔진</li>
<li>Kibana : 엘라스틱서치에 저장된 복잡한 로그 데이터를 편리하게 검색하고, 차트나 통계 화면으로 시각화하여 분석할 수 있게 돕는 웹 인터페이스</li>
<li>Prometheus : 시스템의 리소스 사용량, 에러 발생 횟수 등 상태를 파악할 수 있는 메트릭 및 로그 수집</li>
<li>Grafana : Prometheus가 수집한 데이터를 한눈에 파악할 수 있도록 다양한 그래프와 대시보드 형태로 시각화</li>
</ol>
<h2 id="mdcloggingfilter">MdcLoggingFilter</h2>
<h3 id="mdc-필터를-만드는-이유">MDC 필터를 만드는 이유</h3>
<ul>
<li>웨이팅 API에서 100명의 손님이 동시에 웨이팅을 요청하면 어떨까?</li>
<li>여러 로그들이 섞이며 로그가 복잡해지고, 에러 발생시 찾기 어려워진다.</li>
<li>서버에 들어오는 모든 요청에 대해 대기번호 (Trace ID)를 붙여줄 수 있게 필터를 만들자!</li>
<li>이때 발급받은 대기번호를 담아두는 주머니가 바로 MDC(Mapped Diagnostic Context)이다.</li>
<li>각각의 요청(스레드)이 끝날 때까지 고유한 상태를 기억해 놓은 것이 특징이다.</li>
</ul>
<h3 id="필터-생성">필터 생성</h3>
<pre><code class="language-java">import jakarta.servlet.Filter;

@Component 
public class MdcLoggingFilter implements Filter { 

    @Override 
    public void init(FilterConfig filterConfig) throws ServletException { 
        Filter.super.init(filterConfig); 
    } 

    @Override 
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { 
        // 1. 요청이 들어오면 고유한 8글자 Trace ID를 생성 
        String traceId = UUID.randomUUID().toString().substring(0, 8); 
        // 2. MDC라는 곳에 해당 아이디를 보관 
        MDC.put(&quot;traceId&quot;, traceId); 

        try { 
            // 3.Controller로 요청을 넘김. 
            chain.doFilter(request, response); 
        } finally { 
            // 요청 처리가 끝나면 반드시 비워줘야 함 
            // 톰캣은 재사용되기 때문에, 안 비우면 다음 사람 로그에 이전 사람 ID가 섞일 수 있음 
            MDC.clear(); 
        } 
    } 

    @Override 
    public void destroy() { 
        Filter.super.destroy(); 
    } 
}</code></pre>
<h3 id="logback-설정">Logback 설정</h3>
<p>MDC 필터 생성 후 로그백 설정을 추가로 진행해야한다.</p>
<pre><code class="language-xml">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;configuration&gt;
    &lt;appender name=&quot;CONSOLE&quot; class=&quot;ch.qos.logback.core.ConsoleAppender&quot;&gt;
        &lt;encoder&gt;
            &lt;pattern&gt;%d{yyyy-MM-dd HH:mm:ss.SSS} %highlight(%-5level) %magenta([%X{traceId}]) %yellow([%thread]) %cyan(%logger{36}) : %msg%n&lt;/pattern&gt;
        &lt;/encoder&gt;
    &lt;/appender&gt;

    &lt;root level=&quot;INFO&quot;&gt;
        &lt;appender-ref ref=&quot;CONSOLE&quot; /&gt;
    &lt;/root&gt;
&lt;/configuration&gt;</code></pre>
<h1 id="로그를-파일로-보관하는-방법---logback">로그를 파일로 보관하는 방법 -&gt; LOGBACK</h1>
<h2 id="appender">APPENDER</h2>
<p>Logback에서는 로그를 배송하는 목적지(출력 위치)를 APPENDER가 결정한다.</p>
<ol>
<li>ConsoleAppender<ul>
<li>개발자의 모니터에 로그를 출력함</li>
<li>휘발성</li>
</ul>
</li>
<li>FileAppender<ul>
<li>로그를 텍스트 파일(.log) 안에 기록</li>
<li>삭제하지 않는 한 영구 보관</li>
</ul>
</li>
<li>RollingFileAppender<ul>
<li>FileAppender만 사용하면 1년 치 로그가 하나의 파일에 다 쌓여서 용량이 커짐</li>
<li>매일 자정이 되면 어제 쓴 로그를 저장하고, 오늘 날짜가 적힌 새로운 로그를 만들어냄</li>
<li>현업, 실무에서는 대부분 해당 Appender 사용</li>
</ul>
</li>
</ol>
<h2 id="logback-설정-파일-구성">Logback 설정 파일 구성</h2>
<pre><code class="language-xml">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;configuration&gt;

    &lt;!-- property : 자바의 변수 같은 것 --&gt;
    &lt;!-- 로그를 저장할 경로 --&gt;
    &lt;property name=&quot;LOG_DIR&quot; value=&quot;./logs&quot; /&gt;
    &lt;property name=&quot;LOG_FILE_NAME&quot; value=&quot;waiting-api-log&quot; /&gt;

    &lt;!-- 로그를 출력할 곳을 정하는것이 appender --&gt;
    &lt;appender name=&quot;CONSOLE&quot; class=&quot;ch.qos.logback.core.ConsoleAppender&quot;&gt;
        &lt;encoder&gt;
            &lt;pattern&gt;%d{yyyy-MM-dd HH:mm:ss} %highlight(%-5level) [%X{traceId}] %cyan(%logger{36}) : %msg%n&lt;/pattern&gt;
        &lt;/encoder&gt;
    &lt;/appender&gt;

    &lt;appender name=&quot;FILE&quot; class=&quot;ch.qos.logback.core.rolling.RollingFileAppender&quot;&gt;
        &lt;file&gt;${LOG_DIR}/${LOG_FILE_NAME}.log&lt;/file&gt;

        &lt;encoder&gt;
            &lt;pattern&gt;%d{yyyy-MM-dd HH:mm:ss} %-5level [%X{traceId}] %logger{36} : %msg%n&lt;/pattern&gt;
        &lt;/encoder&gt;

        &lt;rollingPolicy class=&quot;ch.qos.logback.core.rolling.TimeBasedRollingPolicy&quot;&gt;
&lt;!--            &lt;fileNamePattern&gt;${LOG_DIR}/${LOG_FILE_NAME}-%d{yyyy-MM-dd}.log.gz&lt;/fileNamePattern&gt;--&gt;
&lt;!--            이름이 MM-dd 기준으로 생성된다 즉, 날마다 로그파일을 새로 만든다! --&gt;
&lt;!--            gz는 압축 하겠다라는 의미이다 --&gt;
&lt;!--            &lt;maxHistory&gt;30&lt;/maxHistory&gt;--&gt;
&lt;!--            로그를 최대 30일치만 남기고 31일째 로그부터는 알아서 지워줘!--&gt;
            &lt;fileNamePattern&gt;${LOG_DIR}/${LOG_FILE_NAME}-%d{yyyy-MM-dd_HH-mm}.log.gz&lt;/fileNamePattern&gt;
&lt;!--            이름이 HH-mm 기준으로 생성된다 즉, 분마다 로그파일을 새로 만든다! ---&gt;            
            &lt;maxHistory&gt;3&lt;/maxHistory&gt;
&lt;!--            로그를 최대 3분치만 남기고 4분째 로그부터는 알아서 지워줘! ---&gt;
        &lt;/rollingPolicy&gt;
    &lt;/appender&gt;

    &lt;root level=&quot;INFO&quot;&gt;
        &lt;appender-ref ref=&quot;CONSOLE&quot; /&gt; 
        &lt;appender-ref ref=&quot;FILE&quot; /&gt;    
    &lt;/root&gt;

&lt;/configuration&gt;</code></pre>
<h1 id="elk">ELK</h1>
<h2 id="서버가-여러-대일-때는-로그를-어떻게-찾을까">서버가 여러 대일 때는 로그를 어떻게 찾을까?</h2>
<p><img src="https://velog.velcdn.com/images/regular_jk_kim/post/c70222f1-1f1c-43de-98b0-ff7582959cb0/image.png" alt=""></p>
<ul>
<li>서버가 3대라고 가정</li>
<li>고객 문의가 들어와 로그를 찾아야 한다고 하면 몇 번 서버를 탐색해야 할까?</li>
<li>에러를 찾기 위해 서버 1번부터 서버 3번까지 압축된 로그 파일을 하나하나 열어봐야한다.</li>
<li>귀찮으니 여러 서버에 흩어진 로그를 하나의 거대한 중앙 저장소로 모아두자!</li>
<li>이 기술을 ELK라고 부른다.</li>
</ul>
<h2 id="elk-스택이란">ELK 스택이란</h2>
<blockquote>
<p>방대한 로그 데이터를 실시간으로 수집, 검색, 분석 및 시각화하는 오픈소스 플랫폼</p>
</blockquote>
<ul>
<li>E(Elasticsearch) : 수많은 로그를 저장하고, 빠른 속도로 검색할 수 있게 지원</li>
<li>L(Logstash) : 각 서버에서 로그를 수집, 변환하여 Elasticsearch로 전달하는 도구</li>
<li>K(Kibana) : Elasticsearch에 쌓인 데이터를 시각화하여 그래프와 대시보드로 보여주는 분석 도구</li>
</ul>
<h2 id="logstash">Logstash</h2>
<blockquote>
<p>Logstash는 세 가지 단계(input, filter, output)를 통해 움직인다.</p>
</blockquote>
<h3 id="핵심-특징-및-기능">핵심 특징 및 기능</h3>
<ul>
<li>input<ul>
<li><code>.log</code> 파일을 한 줄씩 실시간으로 읽어온다.</li>
</ul>
</li>
<li>filter<ul>
<li>로그를 그냥 통째로 텍스트로 넣지 않고 가공한다.</li>
<li>시간, 로그레벨, Trace ID 등 정보에 라벨링을 해서 구분한다.</li>
</ul>
</li>
<li>output<ul>
<li>Logstash의 최종 목적지인 Elasticsearch로 데이터를 보낸다.</li>
</ul>
</li>
</ul>
<h3 id="설정-예시">설정 예시</h3>
<p><code>logstash.conf</code> 파일 예시를 살펴보자.</p>
<pre><code class="language-conf"># 1. Input
input {
  file {
    # 도커 컨테이너 안에서 바라보는 로그 파일의 위치
    path =&gt; &quot;/usr/share/logstash/logs/waiting-api-log.log&quot;

    # 처음 켤 때 파일의 맨 처음부터 끝까지 싹 다 읽어오라는 뜻
    start_position =&gt; &quot;beginning&quot;

    # 파일이 끝났는지 확인하는 주기 (기본 1초에 한 번씩 감시)
    stat_interval =&gt; 1
  }
}

# 2. Filter
filter {
  # logstash grok 검색후 적용해보기
}

# 3. Output
output {
  # 목적지인 엘라스틱서치로 보냄
  elasticsearch {
    hosts =&gt; [&quot;http://elasticsearch:9200&quot;]
    # 엘라스틱서치에 저장될 인덱스 이름! 날짜별로 분류함
    index =&gt; &quot;waiting-api-logs-%{+YYYY.MM.dd}&quot;
  }

  # 잘 전송되고 있는지 도커 콘솔 화면에서도 확인하기 위해 추가
  stdout { codec =&gt; rubydebug }
}</code></pre>
<h2 id="elasticsearch를-로그-수집에-사용하는-이유">Elasticsearch를 로그 수집에 사용하는 이유</h2>
<h3 id="로그-파일-저장에-db를-사용하면-안-되는-이유">로그 파일 저장에 DB를 사용하면 안 되는 이유</h3>
<ul>
<li>로그는 하루에 수천만 건씩 쌓이는 텍스트 데이터이다.</li>
<li>MySQL과 같은 관계형 DB는 이런 방대한 텍스트에서 특정 단어를 검색하는 게 매우 오래 걸린다.</li>
<li>따라서 Elasticsearch와 같은 검색 엔진을 사용하는 것이 더 적절한다.</li>
</ul>
<h3 id="elasticsearch가-적절한-이유">Elasticsearch가 적절한 이유</h3>
<ul>
<li>Elasticsearch는 태생이 검색 엔진이다.</li>
<li>관계형 DB의 경우 특정단어를 찾기 위해 첫 번째 페이지부터 끝까지 넘기면서 해당 단어를 찾는다 -&gt; 느림</li>
<li>Elasticsearch의 경우 Index를 활용하여 데이터를 아주 빠르게 찾을 수 있다.<ul>
<li>데이터가 1억 건이어도 0.1초 만에 Index를 보고 찾아낸다.</li>
<li>이 개념을 Inverted Index(역인덱스)라고 부른다.</li>
</ul>
</li>
</ul>
<h2 id="kibana의-역할">Kibana의 역할</h2>
<blockquote>
<p>Elasticsearch에 쌓인 데이터를 시각화하여 그래프와 대시보드로 보여주는 분석 도구</p>
</blockquote>
<p>Elasticsearch에 쿼리를 실행하고, 결과를 다양한 형태로 보여준다.</p>
<h2 id="elk-docker-compose">ELK Docker Compose</h2>
<pre><code class="language-yml">services:
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:9.1.0
    container_name: elasticsearch
    environment:
      - discovery.type=single-node
      - xpack.security.enabled=false
      - xpack.security.http.ssl.enabled=false
      - &quot;ES_JAVA_OPTS=-Xms512m -Xmx512m&quot;
    ports:
      - &quot;9200:9200&quot;
  logstash:
    image: docker.elastic.co/logstash/logstash:9.1.0
    container_name: logstash
    volumes:
      - ./logs:/usr/share/logstash/logs
      - ./logstash.conf:/usr/share/logstash/pipeline/logstash.conf
    ports:
      - &quot;5044:5044&quot;
    depends_on:
      - elasticsearch

  kibana:
    image: docker.elastic.co/kibana/kibana:9.1.0 # 무조건 ES, Logstash와 버전을 맞춰야 한다! (9.1.0)
    container_name: kibana
    ports:
      - &quot;5601:5601&quot; # 키바나 포트 번호
    environment:
      # 키바나가 데이터를 가져올 주소
      - ELASTICSEARCH_HOSTS=http://elasticsearch:9200
    depends_on:
      - elasticsearch</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[251130]]></title>
            <link>https://velog.io/@regular_jk_kim/251130</link>
            <guid>https://velog.io/@regular_jk_kim/251130</guid>
            <pubDate>Sun, 30 Nov 2025 10:01:20 GMT</pubDate>
            <description><![CDATA[<p>#회고 </p>
<h2 id="251130-회고-💬">251130 회고 💬</h2>
<p> 미세먼지가 심해졌다. 또 시작이구나,,, 하늘이 회색빛이다. 나가기 싫다... 💀 퇴근하는 길에 전직장 동료분을 만났다. 처음에 먼저 알아보시고 먼저 말을 걸어주셨다. 이런 우연이라니! 신기하다. 이래서 있을 때 잘 하라는 말이 있는건가... 이런 저런 이야기하면서 신기한 경험을 했다.</p>
<p>싸피 2학기가 끝났다고한다. 오랜만에 싸피 친구들과 만나서 즐거운 시간을 보냈다. 다들 좋은곳에 취업하길 응원한다!</p>
<h2 id="keep-👍">Keep 👍</h2>
<h3 id="출퇴근-자투리-공부">출퇴근 자투리 공부</h3>
<p>장고 공부를 하고있다. </p>
<h3 id="개인-공부">개인 공부</h3>
<p>우분투 공부를 하고 있다. 지금까지 윈도우, 맥 두 종류의 os 만 사용해봤다. 다행히 맥을 오래 사용했었기 때문에 이런저런 명령어를 몇가지는 알고 있다. 그럼에도 어려운 점이 있다면 터미널로 모든 일을 처리한다는 부분이다. 물론 브라우저도 있고 이런저런 인터페이스가 있기는 하다. 그럼에도 원하는 작업을 하려면 명령어로 처리를 해야하다보니 어색한 부분이 많다.</p>
<p>수동이긴 하지만 우분투에 서버 실행 후 외부에서 접속하는 과정까지 성공했다. 접속이 된다는 테스트를 완료한 것이다. 이제 cicd 구축만 남았다. 사실 cicd 구축이 안 되면 헛수고가 되버리는건 사실이다. 그럼에도 aws 사용하지 않고 로컬에서 구동하는 경험을 했다.</p>
<h3 id="운동">운동</h3>
<p>월화수목금 운동나가기를 도전 중이다. 이번 주에는 1일 성공했다!</p>
<ul>
<li>월요일 어깨</li>
<li>화요일 가슴</li>
<li>수요일 하체</li>
<li>목요일 등</li>
<li>금요일 이두삼수 (잘 안 함)</li>
</ul>
<h3 id="독서">독서</h3>
<h2 id="try-🧚">Try 🧚</h2>
<ul>
<li>장고 공부하기</li>
<li>도커 공부하기</li>
<li>쿠버네티스 공부하기</li>
<li>혼자 공부하는 네트워크 읽기</li>
</ul>
<h2 id="독서-목록">독서 목록</h2>
<h3 id="서평-완료-목록">서평 완료 목록</h3>
<ul>
<li><a href="https://velog.io/@regular_jk_kim/%ED%98%BC%EC%9E%90-%EA%B3%B5%EB%B6%80%ED%95%98%EB%8A%94-%EC%BB%B4%ED%93%A8%ED%84%B0-%EA%B5%AC%EC%A1%B0-%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%EB%A5%BC-%EC%9D%BD%EA%B3%A0">혼자 공부하는 컴퓨터 구조 + 운영체제</a></li>
<li><a href="https://velog.io/@regular_jk_kim/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%9D%98-%EA%B8%B8-%EB%A9%98%ED%86%A0%EC%97%90%EA%B2%8C-%EB%AC%BB%EB%8B%A4-%EB%A5%BC-%EC%9D%BD%EA%B3%A0-24jpq345">프로그래머의 길, 멘토에게 묻다</a></li>
<li><a href="https://velog.io/@regular_jk_kim/%ED%95%A8%EA%BB%98-%EC%9E%90%EB%9D%BC%EA%B8%B0-%EB%A5%BC-%EC%9D%BD%EA%B3%A0">함께 자라기 애자일로 가는 길</a></li>
<li><a href="https://velog.io/@regular_jk_kim/%EA%B0%9D%EC%B2%B4%EC%A7%80%ED%96%A5%EC%9D%98-%EC%82%AC%EC%8B%A4%EA%B3%BC-%EC%98%A4%ED%95%B4-%EB%A5%BC-%EC%9D%BD%EA%B3%A0">객체지향의 사실과 오해</a></li>
</ul>
<h3 id="서평-예정-목록-읽는-중">서평 예정 목록 (읽는 중)</h3>
<ul>
<li>혼자 공부하는 네트워크 (19%)</li>
</ul>
<h3 id="으악-재미없어-🤪">으악 재미없어,,, 🤪</h3>
<ul>
<li><del>면접을 위한 CS 전공지식 노트</del></li>
<li><del>한 권으로 읽는 컴퓨터 구조와 프로그래밍</del></li>
</ul>
<h3 id="독서-예정-목록">독서 예정 목록</h3>
<ul>
<li>혼자 공부하는 네트워크</li>
<li>오브젝트</li>
<li>HTTP 완벽 가이드</li>
<li>자바/스프링 개발자를 위한 실용주의 프로그래밍</li>
<li>모던 자바 인 액션</li>
<li>자바 성능 튜닝 이야기 </li>
<li>헤드 퍼스트 서블릿</li>
<li>파이브 라인스 오브 코드</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[251123]]></title>
            <link>https://velog.io/@regular_jk_kim/251123</link>
            <guid>https://velog.io/@regular_jk_kim/251123</guid>
            <pubDate>Sun, 23 Nov 2025 10:53:25 GMT</pubDate>
            <description><![CDATA[<p>#회고 </p>
<h2 id="251123-회고-💬">251123 회고 💬</h2>
<p>갑자기 엄청 추워졌다! 진짜 겨울날씨가 돼버렸다. 사무실이 좀 더웠는데 오히려 좋을지도? 회사 분들과 회식도 했다! 고기 먹었다. 단백질 냠냠냠 🍖 회사에서 인프라 역할을 같이 맡아 작업을 하게 됐다. 우효! 언젠가는 그리고 한번쯤은 해보고 싶다고 늘 생각만 하고 있었다. 인프라 작업을 내가 도맡아서 하게 되다니! 설레는 순간이다. 리눅스부터 설치하고, 이것저것 내가 하고 싶은대로 맘대로 할 수 있을듯 싶다! 신난다!</p>
<h2 id="keep-👍">Keep 👍</h2>
<h3 id="출퇴근-자투리-공부">출퇴근 자투리 공부</h3>
<p>장고 공부를 하고있다. </p>
<ul>
<li>페이지네이션</li>
<li>자기 참조 모델</li>
<li>애플리케이션 제작 실습</li>
</ul>
<h3 id="개인-공부">개인 공부</h3>
<p>요즘 도커와 씨름하는 중이다. 환경 변수 주입하기가 잘 안 된다. 대충 개념만 숙지하고 실전으로 부딪히는 중이다. 잘 안된다. GPT 답변이 자꾸 변하니까 뭐가 맞는지도 잘 모르겠다. 후 어렵다...</p>
<h3 id="운동">운동</h3>
<p>월화수목금 운동나가기를 도전 중이다. 이번 주에는 3일 성공했다!</p>
<ul>
<li>월요일 어깨</li>
<li>화요일 가슴</li>
<li>수요일 하체</li>
<li>목요일 등</li>
<li>금요일 이두삼수 (잘 안 함)</li>
</ul>
<h3 id="독서">독서</h3>
<p>다시 출퇴근 시간에 판타지 소설을 읽기 시작했다. 너무 재밌다. 드래곤 라자를 읽고 있다. 학생일 때 읽을까 말까 고민했던 기억이 있다. 왜냐하면 눈물을 마시는 새를 그때 너무 재밌게 읽어서 김영도 작가에 관심이 많았었다. 근데 안 읽었다. 왜냐하면 돈이 없었거든,,, 그렇지만 이제는 읽을 수 있다! 출퇴근이 순식간에 끝나는 마법같은 경험을 하는 중이다. 너무 재밌어!</p>
<h2 id="try-🧚">Try 🧚</h2>
<ul>
<li>장고 공부하기</li>
<li>도커 공부하기</li>
<li>쿠버네티스 공부하기</li>
<li>혼자 공부하는 네트워크 읽기</li>
</ul>
<h2 id="독서-목록">독서 목록</h2>
<h3 id="서평-완료-목록">서평 완료 목록</h3>
<ul>
<li><a href="https://velog.io/@regular_jk_kim/%ED%98%BC%EC%9E%90-%EA%B3%B5%EB%B6%80%ED%95%98%EB%8A%94-%EC%BB%B4%ED%93%A8%ED%84%B0-%EA%B5%AC%EC%A1%B0-%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%EB%A5%BC-%EC%9D%BD%EA%B3%A0">혼자 공부하는 컴퓨터 구조 + 운영체제</a></li>
<li><a href="https://velog.io/@regular_jk_kim/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%9D%98-%EA%B8%B8-%EB%A9%98%ED%86%A0%EC%97%90%EA%B2%8C-%EB%AC%BB%EB%8B%A4-%EB%A5%BC-%EC%9D%BD%EA%B3%A0-24jpq345">프로그래머의 길, 멘토에게 묻다</a></li>
<li><a href="https://velog.io/@regular_jk_kim/%ED%95%A8%EA%BB%98-%EC%9E%90%EB%9D%BC%EA%B8%B0-%EB%A5%BC-%EC%9D%BD%EA%B3%A0">함께 자라기 애자일로 가는 길</a></li>
<li><a href="https://velog.io/@regular_jk_kim/%EA%B0%9D%EC%B2%B4%EC%A7%80%ED%96%A5%EC%9D%98-%EC%82%AC%EC%8B%A4%EA%B3%BC-%EC%98%A4%ED%95%B4-%EB%A5%BC-%EC%9D%BD%EA%B3%A0">객체지향의 사실과 오해</a></li>
</ul>
<h3 id="서평-예정-목록-읽는-중">서평 예정 목록 (읽는 중)</h3>
<ul>
<li>혼자 공부하는 네트워크 (19%)</li>
</ul>
<h3 id="으악-재미없어-🤪">으악 재미없어,,, 🤪</h3>
<ul>
<li><del>면접을 위한 CS 전공지식 노트</del></li>
<li><del>한 권으로 읽는 컴퓨터 구조와 프로그래밍</del></li>
</ul>
<h3 id="독서-예정-목록">독서 예정 목록</h3>
<ul>
<li>혼자 공부하는 네트워크</li>
<li>오브젝트</li>
<li>HTTP 완벽 가이드</li>
<li>자바/스프링 개발자를 위한 실용주의 프로그래밍</li>
<li>모던 자바 인 액션</li>
<li>자바 성능 튜닝 이야기 </li>
<li>헤드 퍼스트 서블릿</li>
<li>파이브 라인스 오브 코드</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[251116]]></title>
            <link>https://velog.io/@regular_jk_kim/251116</link>
            <guid>https://velog.io/@regular_jk_kim/251116</guid>
            <pubDate>Sun, 16 Nov 2025 08:40:40 GMT</pubDate>
            <description><![CDATA[<p>#회고 </p>
<h2 id="251116-회고-💬">251116 회고 💬</h2>
<p>주말에 창립기념일 행사가 있었다. 회사 사람들과 친해지는 시간이 되었다. 오래오래 다녀보자! 이번에는 제발!</p>
<h2 id="keep-👍">Keep 👍</h2>
<h3 id="출퇴근-자투리-공부">출퇴근 자투리 공부</h3>
<p>장고 공부를 하고있다. </p>
<ul>
<li>DRF</li>
<li>Serializer</li>
<li>Mixin</li>
<li>GenericAPIView</li>
<li>GenericViewSet</li>
</ul>
<h3 id="개인-공부">개인 공부</h3>
<ul>
<li>도커 사용할 일이 생겨서 평일에 도커 공부를 했다. 마법같이 동작하는 신기한 기술,,, 여전히 뭔지 잘 모르겠다. 내용은 <a href="https://velog.io/@regular_jk_kim/Docker-Compose">여기서</a> 확인 가능하다.</li>
</ul>
<h3 id="운동">운동</h3>
<p>매일 헬스장에 나가 운동하려고 노력 중이다. 이번 평일에는 <strong>3</strong>일 성공했다. 평소에 데드리프트를 안 한다. 이유는 귀찮아서. 근데 등 운동 하는 날에 사람이 너무 많아서 데드리프트를 도전해봤다. 몇년 전에 40kg이 무거워서 상당히 힘들게 들었던 기억이 있다. 그런데 놀랍게도 50kg이 상당히 쉬웠다. 자세가 불안해서 몇번 안 들었는데 주말동안 자세 공부하면 다음주 쯤에 60kg 정도까지도 가능할거 같다! 우효!</p>
<p>금요일에 처음으로 팔운동을 했다. 어깨, 가슴 운동하는 날에 팔에 힘이 많이 들어가서 평소에는 팔운동을 안 했다. 그런데 이번 주에는 운동 못한 날이 많아서 금요일까지 운동을 해버렸다. 후후 이거 운동이 루틴이 된듯 싶다.</p>
<p>평일에 하체 운동을 못했다. 약속이 생겨서 친구들을 만났다. 안 하고 넘어가기에는 아쉬운 운동이라 계속 신경쓰였다. 신경쓰면서 찝찝하게 있기보다는 운동을 해버리기로 결정! 토요일에 헬스장에 출근했다. 그리고 하체 운동을 했다. 후 앉았다 일어나기가 너무 힘들다... 🦵</p>
<ul>
<li>월요일 어깨</li>
<li>화요일 가슴</li>
<li>수요일 하체</li>
<li>목요일 등</li>
<li>금요일 이두삼수 (잘 안 함)</li>
</ul>
<h3 id="독서">독서</h3>
<p>혼자 공부하는 네트워크를 읽고있다. 회사에서 힘을 못 내는 순간이다. 이러려고 이렇게 긴 시간을 공부했나 의문이 든다. 후 열심히 해야지 화이팅이다 제발...</p>
<h2 id="try-🧚">Try 🧚</h2>
<ul>
<li>장고 공부하기</li>
<li>도커 공부하기</li>
<li>쿠버네티스 공부하기</li>
<li>혼자 공부하는 네트워크 읽기</li>
</ul>
<h2 id="problem-🤢">Problem 🤢</h2>
<p>요즘 독서를 못(안)하고 있다. 책읽기가 왜이렇게 싫지,,, 주말 만이라도 읽으려고 노력 중인데 참 쉽지가 않다.</p>
<h2 id="독서-목록">독서 목록</h2>
<h3 id="서평-완료-목록">서평 완료 목록</h3>
<ul>
<li><a href="https://velog.io/@regular_jk_kim/%ED%98%BC%EC%9E%90-%EA%B3%B5%EB%B6%80%ED%95%98%EB%8A%94-%EC%BB%B4%ED%93%A8%ED%84%B0-%EA%B5%AC%EC%A1%B0-%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%EB%A5%BC-%EC%9D%BD%EA%B3%A0">혼자 공부하는 컴퓨터 구조 + 운영체제</a></li>
<li><a href="https://velog.io/@regular_jk_kim/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%9D%98-%EA%B8%B8-%EB%A9%98%ED%86%A0%EC%97%90%EA%B2%8C-%EB%AC%BB%EB%8B%A4-%EB%A5%BC-%EC%9D%BD%EA%B3%A0-24jpq345">프로그래머의 길, 멘토에게 묻다</a></li>
<li><a href="https://velog.io/@regular_jk_kim/%ED%95%A8%EA%BB%98-%EC%9E%90%EB%9D%BC%EA%B8%B0-%EB%A5%BC-%EC%9D%BD%EA%B3%A0">함께 자라기 애자일로 가는 길</a></li>
<li><a href="https://velog.io/@regular_jk_kim/%EA%B0%9D%EC%B2%B4%EC%A7%80%ED%96%A5%EC%9D%98-%EC%82%AC%EC%8B%A4%EA%B3%BC-%EC%98%A4%ED%95%B4-%EB%A5%BC-%EC%9D%BD%EA%B3%A0">객체지향의 사실과 오해</a></li>
</ul>
<h3 id="서평-예정-목록-읽는-중">서평 예정 목록 (읽는 중)</h3>
<ul>
<li>혼자 공부하는 네트워크 (19%)</li>
</ul>
<h3 id="으악-재미없어-🤪">으악 재미없어,,, 🤪</h3>
<ul>
<li><del>면접을 위한 CS 전공지식 노트</del></li>
<li><del>한 권으로 읽는 컴퓨터 구조와 프로그래밍</del></li>
</ul>
<h3 id="독서-예정-목록">독서 예정 목록</h3>
<ul>
<li>혼자 공부하는 네트워크</li>
<li>오브젝트</li>
<li>HTTP 완벽 가이드</li>
<li>자바/스프링 개발자를 위한 실용주의 프로그래밍</li>
<li>모던 자바 인 액션</li>
<li>자바 성능 튜닝 이야기 </li>
<li>헤드 퍼스트 서블릿</li>
<li>파이브 라인스 오브 코드</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Docker Compose]]></title>
            <link>https://velog.io/@regular_jk_kim/Docker-Compose</link>
            <guid>https://velog.io/@regular_jk_kim/Docker-Compose</guid>
            <pubDate>Fri, 14 Nov 2025 14:40:15 GMT</pubDate>
            <description><![CDATA[<p>#docker </p>
<p>도커 컴포즈 개념과 사용 방법을 간단하게 살펴보자!</p>
<h2 id="docker-compose란">Docker Compose란?</h2>
<blockquote>
<p>여러 개의 Docker 컨테이너들을 하나의 서비스로 정의하고 구성해 하나의 묶음으로 관리할 수 있게 도와주는 툴</p>
</blockquote>
<h2 id="왜-사용하는거에요">왜 사용하는거에요?</h2>
<ol>
<li><p>여러 개의 컨테이너를 관리하는 데 용이
여러 개의 컨테이너로 이루어진 복잡한 애플리케이션을 한 번에 관리할 수 있게 해준다. 여러 컨테이너를 하나의 환경에서 실행하고 관리하는 데 도움이 된다.</p>
</li>
<li><p>복잡한 명령어로 실행시킨 과정을 간소화 할 수 있다.
Docker Compose를 사용하면 컨테이너를 실행시킬 때마다 복잡한 명령어를 입력하지 않아도 된다. 단순히 <code>docker compose up</code> 명령어만 실행시키면 된다.</p>
</li>
</ol>
<h2 id="자주-사용하는-docker-compose-cli-명령어">자주 사용하는 Docker Compose CLI 명령어</h2>
<h3 id="composeyml-파일-작성">compose.yml 파일 작성</h3>
<pre><code class="language-yml">services:
    webserver:
        container_name: webserver
        image: nginx
        ports:
            - 80:80</code></pre>
<ul>
<li>Docker Compose에서는 하나의 컨테이너를 <code>service</code>라고 부른다. </li>
<li><code>services</code> : service를 나열하기 전 입력하는 명령어</li>
<li><code>webserver</code> : services 바로 밑에 위치한 이름은 service의 이름을 나타낸다. 임의로 작성하면 된다.</li>
<li><code>container_name</code> : 서비스가 컨테이너가 될 때 가지게될 이름을 의미한다.</li>
<li><code>image</code> : 서비스의 기반이될 이미지를 의미한다.</li>
<li><code>ports</code> : 서비스가 컨테이너가 됐을 때 사용할 <code>호스트:컨테이너</code> 포트를 의미한다.</li>
</ul>
<h3 id="composeyml에서-정의한-컨테이너-실행">compose.yml에서 정의한 컨테이너 실행</h3>
<pre><code class="language-sh">docker compose up    # 포그라운드에서 실행
docker compose up -d # 백그라운드에서 실행</code></pre>
<h3 id="docker-compose로-실행시킨-컨테이너-확인하기">Docker Compose로 실행시킨 컨테이너 확인하기</h3>
<pre><code class="language-sh"># compose.yml에 정의된 컨테이너 중 실행 중인 컨테이너만 보여준다.
docker compose ps
# compose.yml에 정의된 모든 컨테이너를 보여준다.
docker compose ps -a</code></pre>
<h3 id="docker-compose-로그-확인하기">Docker Compose 로그 확인하기</h3>
<pre><code class="language-sh"># compose.yml에 정의된 모든 컨테이너의 로그를 모아서 출력한다.
docker compose logs</code></pre>
<h3 id="컨테이너-실행-전에-이미지-재빌드하기">컨테이너 실행 전에 이미지 재빌드하기</h3>
<pre><code class="language-sh">docker compose up --build    # 포그라운드에서 실행
docker compose up -d --build # 백그라운드에서 실행</code></pre>
<ul>
<li><code>compose.yml</code>에서 정의한 이미지 파일에서 코드가 변경 됐을 경우, 이미지를 다시 빌드해서 컨테이너를 실행시켜야 변경된 부분이 적용된다. 그러므로 <code>--build</code> 옵션을 추가해서 사용해야 한다.</li>
<li><code>docker compose up</code> : 이미지가 없을 때만 빌드해서 컨테이너를 실행시킨다. 이미지가 존재하는 경우 컨테이너만 실행시킨다.</li>
<li><code>docker compose up --build</code> : 이미지가 있더라도 빌드를 다시해서 컨테이너를 실행시킨다.</li>
</ul>
<h3 id="이미지-다운받기-업데이트하기">이미지 다운받기, 업데이트하기</h3>
<pre><code class="language-sh">docker compose pull</code></pre>
<ul>
<li><code>compose.yml</code>에서 정의된 이미지를 다운 받거나 업데이트 한다.<ul>
<li>로컬 환경에 이미지가 없다면 이미지를 다운 받는다.</li>
<li>로컬 환경에 이미 이미지가 있는데, Dockerhub의 이미지와 다른 이미지일 경우 이미지를 업데이트 한다.</li>
</ul>
</li>
</ul>
<h3 id="docker-compose에서-이용한-컨테이너-종료하기">Docker Compose에서 이용한 컨테이너 종료하기</h3>
<pre><code class="language-sh">docker compose down</code></pre>
<h2 id="docker-compose-사용해서-redis-띄워보기">Docker Compose 사용해서 Redis 띄워보기</h2>
<pre><code class="language-yml">services:
    my-cache-server:
        image: redis
        ports:
            - 6379:6379</code></pre>
<ul>
<li>도커 컴포즈 파일 생성</li>
</ul>
<pre><code class="language-sh">docker compose up -d</code></pre>
<ul>
<li>도커 컴포즈 실행</li>
</ul>
<pre><code class="language-sh">docker compose ps
docker ps
docker compose down</code></pre>
<ul>
<li>도커 컨테이너 확인</li>
</ul>
<h2 id="docker-compose-사용해서-mysql-띄워보기">Docker Compose 사용해서 MySQL 띄워보기</h2>
<pre><code class="language-yml">services:
    my-db:
        image: mysql
        environment:
            MYSQL_ROOT_PASSWORD: password123
        volumes:
            - ./mysql_data:/var/lib/mysql # docker compose는 상대경로 허용
        ports:
            - 3306:3306</code></pre>
<h2 id="docker-compose-사용해서-springboot-띄워보기">Docker Compose 사용해서 SpringBoot 띄워보기</h2>
<pre><code class="language-yml">services:
    my-server:
        build: . # Dockerfile 과 같은 경로에 있다고 가정 (상대경로)
        ports:
            - 8080:8080</code></pre>
<ul>
<li>docker-compose.yml 파일과 Dockerfile 파일이 같은 경로에 있다고 가정한다. build 명령어는 Dockerfile을 찾아 내용에 맞게 빌드를 시작한다.</li>
</ul>
<pre><code class="language-sh">docker compose up -d --build</code></pre>
<ul>
<li>이후 Docker Compose 명령어를 실행할 때 <code>--build</code> 옵션을 추가한다. </li>
<li>스프링 부트 프로젝트에 패치가 있다면 <code>--build</code> 명령어로 해당 내역을 반영한다.</li>
</ul>
<h2 id="redis와-mysql-동시에-실행시키기">Redis와 MySQL 동시에 실행시키기</h2>
<pre><code class="language-yml">services:
    my-db:
        image: mysql
        environment:
            MYSQL_ROOT_PASSWORD: password123
        volumes:
            - ./mysql_data:/var/lib/mysql
        ports:
            - 3306:3306
    my-cache-server:
        image: redis
        ports:
            - 6379:6379</code></pre>
<h2 id="springboot와-mysql-동시에-실행시키기">SpringBoot와 MySQL 동시에 실행시키기</h2>
<p><code>compose.yml</code> (스프링 프로젝트에 포함)</p>
<pre><code class="language-yml">services:
    my-server:
        build: .
        ports:
            - 8080:8080
        depends_on:
            my-db:
                condition: service_healthy

    my-db:
        image: mysql
        environment:
            MYSQL_ROOT_PASSWORD: password123
            MYSQL_DATABASE: mydb              # db 이름
        volumes:
            - ./mysql_data:/var/lib/mysql
        ports:
            - 3306:3306
        healthckeck:
            test: [ &quot;CMD&quot;, &quot;mysqladmin&quot;, &quot;ping&quot; ]
            interval: 5s
            retries: 10</code></pre>
<ul>
<li><code>depends_on</code> : 스프링 애플리케이션은 MySQL에 의존한다. MySQL 컨테이너가 아직 실행 전이라면 스프링 서버도 실행될 수 없다. 따라서 컨테이너 실행 순서를 지정해야한다. 이때 사용하는 명령어이다.</li>
</ul>
<h2 id="springboot와-mysql-redis-동시에-실행시키기">SpringBoot와 MySQL, Redis 동시에 실행시키기</h2>
<pre><code class="language-yml">services:
    my-server:
        build: .
        ports:
            - 8080:8080
        depends_on:
            my-db:
                condition: service_healthy
            my-cache-server:
                condition: service_health

    my-db:
        image: mysql
        environment:
            MYSQL_ROOT_PASSWORD: password123
            MYSQL_DATABASE: mydb              # db 이름
        volumes:
            - ./mysql_data:/var/lib/mysql
        ports:
            - 3306:3306
        healthckeck:
            test: [ &quot;CMD&quot;, &quot;mysqladmin&quot;, &quot;ping&quot; ]
            interval: 5s
            retries: 10

    my-cache-server:
        image: redis
        ports:
            - 6379:6379
        healthcheck:
            test: [ &quot;CMD&quot;, &quot;redist-cli&quot;, &quot;ping&quot; ]
            interval: 5s
            retries: 10</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[Dockerfile]]></title>
            <link>https://velog.io/@regular_jk_kim/Dockerfile</link>
            <guid>https://velog.io/@regular_jk_kim/Dockerfile</guid>
            <pubDate>Wed, 12 Nov 2025 14:42:55 GMT</pubDate>
            <description><![CDATA[<p>#docker </p>
<p>도커 파일 개념과 사용 방법을 간단하게 살펴보자!</p>
<h2 id="dockerfile이란">Dockerfile이란?</h2>
<p>Docker 이미지는 Dockerhub를 통해 다운받아 사용할 수 있다. 이때 사용되는 이미지를 만드는 기술이다.</p>
<blockquote>
<p>Dockerfile을 활용해 Docker 이미지를 만들 수 있다.</p>
</blockquote>
<p>Dockerhub에 올려놓은 Docker 이미지가 아닌, 나만의 Docker 이미지를 만들고 싶을 수 있다. 예를 들어 내가 만든 Django 프로젝트가 있다. 내가 만든 프로젝트 자체를 Dockerfile을 활용하여 Docker 이미지로 만들 수 있다.</p>
<h2 id="from-베이스-이미지-생성"><code>FROM</code> 베이스 이미지 생성</h2>
<p><code>FROM</code>은 베이스 이미지를 생성하는 역할을 한다. Docker 컨테이너를 특정 초기 이미지를 기반으로 추가적인 세팅을 할 수 있다. 특정 초기 이미지가 곧 베이스 이미지이다.</p>
<p>윈도우 컴퓨터를 새로 사서 실행시키면 기본 프로그램들이 이미 설치돼있다. 베이스 이미지도 이와 똑같다. 컨테이너를 새로 띄워서 미니 컴퓨터 환경을 구축할 때 기본 프로그램이 어떤게 깔려있을지 선택하는 옵션이라고 생각하자.</p>
<p>누군가는 JDK가 깔려있는 컴퓨터 환경이 세팅되기를 바랄 수도 있고, 누군가는 Python이 깔려있는 컴퓨터 환경이 세팅되기를 바랄 수도 있다. 필요에 따라 베이스 이미지를 고르면 된다.</p>
<pre><code class="language-docker">FROM [이미지 이름]
FROM [이미지 이름]:[태그 이름]</code></pre>
<ul>
<li><code>태그 이름</code>을 명시하지 않으면 해당 이미지의 최신 버전을 사용한다.</li>
</ul>
<h2 id="베이스-이미지를-생성해보자">베이스 이미지를 생성해보자.</h2>
<h3 id="1-dockerfile-만들기">1. <code>Dockerfile</code> 만들기</h3>
<pre><code class="language-docker">FROM openjdk:17-jdk</code></pre>
<h3 id="2-dockerfile을-기반으로-이미지-만들기">2. Dockerfile을 기반으로 이미지 만들기</h3>
<pre><code class="language-sh">docker build -t [이미지 이름]:[태그 이름] [Dockerfile 디렉터리 경로]
# docker build -t my-jdk-server .
# docker build -t my-jdk-server:beta .</code></pre>
<h3 id="3-생성한-이미지로-컨테이너-띄우기">3. 생성한 이미지로 컨테이너 띄우기</h3>
<pre><code class="language-sh">docker run -d my-jdk-server</code></pre>
<h3 id="4-컨테이너-조회하기">4. 컨테이너 조회하기</h3>
<pre><code class="language-sh">docker ps # 실행되고 있는 컨테이너가 없다
docker ps -a # 컨테이너가 종료돼 있음</code></pre>
<p>왜 종료돼있지? -&gt; Docker 컨테이너는 내부적으로 필요한 명령을 다 수행했을 경우 자동으로 종료된다. 내부에 명령이 없기 때문에 자동으로 종료되었다.</p>
<h2 id="copy-파일-복사이동"><code>COPY</code> 파일 복사(이동)</h2>
<p><code>COPY</code> 명령어는 호스트 컴퓨터에 있는 파일을 복사해서 컨테이너로 전달한다.</p>
<pre><code class="language-docker">COPY [호스트 컴퓨터에 있는 복사할 파일의 경로] [컨테이너에서 파일이 위치할 경로]
# COPY app.txt /app.txt</code></pre>
<h3 id="폴더-안에-있는-모든-파일들-복사하기">폴더 안에 있는 모든 파일들 복사하기</h3>
<pre><code class="language-docker">COPY my-folder /my-folder/</code></pre>
<ul>
<li><code>/my-folder</code> 형식으로 적으면 안 되고 <code>/my-folder/</code> 형식으로 입력해야 <code>my-folder</code> 경로에 파일들이 정상적으로 복사된다.</li>
</ul>
<h2 id="와일드-카드-사용하기">와일드 카드 사용하기</h2>
<p>디렉터리에 여러 txt 파일을 만들어보자.
<code>current working directory</code></p>
<pre><code class="language-md">- tmp.txt
- my_text.txt
- readme.txt</code></pre>
<p>위와 같이 3개의 txt 파일이 있다고 가정하자. 이 모든 파일을 모두 COPY 하고자 한다면 와일드 카드 문법을 사용해 한번에 이동시킬 수 있다.</p>
<pre><code class="language-docker">COPY *.txt /my_text_files/</code></pre>
<p>txt 확장자를 가진 모든 파일들은 <code>my_text_files</code> 폴더로 이동된다.</p>
<h2 id="dockerignore-사용하기"><code>.dockerignore</code> 사용하기</h2>
<p>특정 파일 또는 폴더만 <code>COPY</code> 하고 싶지 않을 수도 있다. 그럴 때 <code>.dockerignore</code>를 사용한다.</p>
<h3 id="1-dockerignore-파일-만들기">1. <code>.dockerignore</code> 파일 만들기</h3>
<p><code>.dockerignore</code></p>
<pre><code class="language-txt">readme.txt</code></pre>
<h3 id="2-이동-명령어-작성">2. 이동 명령어 작성</h3>
<pre><code class="language-docker">COPY *.txt /my_text_files/</code></pre>
<p>txt 확장자 파일 전부를 이동하는 명령어를 입력하고 실행한다.</p>
<h3 id="3-이동된-파일-확인">3. 이동된 파일 확인</h3>
<p>이동된 파일을 살펴보면 readme.md 파일은 <code>.dockerignore</code>에 의해서 이동되지 않았음을 확인할 수 있다.</p>
<h2 id="entrypoint-컨테이너가-시잘될-때-실행되는-명령어"><code>ENTRYPOINT</code> 컨테이너가 시잘될 때 실행되는 명령어</h2>
<p><code>ENTRYPOINT</code>는 컨테이너가 실행되고 최초로 실행되는 명령어를 의미한다.</p>
<pre><code class="language-docker">ENTRYPOINT [명령문...]</code></pre>
<ul>
<li>띄어쓰기를 기준으로 쉼표로 구분하여 문자열을 입력하면 된다.</li>
</ul>
<h3 id="예시">예시</h3>
<pre><code class="language-docker">FROM ubuntu
ENTRYPOINT [&quot;/bin/bash&quot;, &quot;-c&quot;, &quot;echo hello&quot;]</code></pre>
<p>위와 같은 Dockerfile을 만들고 이미지 생성, 컨테이너를 실행시킨다.</p>
<pre><code class="language-sh">docker build -t my-server . 
docker run -d my-server 
docker ps -a 
docker logs [Container ID]</code></pre>
<p>컨테이너는 종료되었지만 로그를 확인하면 <code>hello</code> 문자열을 확인할 수 있다.</p>
<h2 id="run-이미지를-생성하는-과정에서-사용할-명령문-실행"><code>RUN</code> 이미지를 생성하는 과정에서 사용할 명령문 실행</h2>
<p><code>RUN</code>은 이미지 생성 과정에서 명령어를 실행시켜야 할 때 사용한다.</p>
<pre><code class="language-docker">RUN [명령문]
# RUN npm install</code></pre>
<h3 id="run-과-entrypoint"><code>RUN</code> 과 <code>ENTRYPOINT</code>?</h3>
<p><code>RUN</code> 명령어와 <code>ENTRYPOINT</code> 명령어는 비슷한 동작을 수행하기 때문에 헷갈릴 때가 있다. </p>
<ul>
<li><code>RUN</code> : 이미지 생성 과정에서 필요한 명령어를 실행한다.</li>
<li><code>ENTRYPOINT</code> : 생성된 이미지를 기반으로 컨테이너를 생성한 직후에 명령어를 실행시킬 때 사용한다.</li>
</ul>
<h3 id="예시-1">예시</h3>
<p>미니 컴퓨터 환경이 ubuntu로 되어있고, git이 설치되어있으면 좋겠다고 가정해보자. 이런 환경을 구성하기 위해 <code>Dockerfile</code>을 활용해 ubuntu, git이 설치된 이미지를 만들면 된다.</p>
<ol>
<li><p>Dockerfile 작성하기</p>
<pre><code class="language-docker">FROM ubuntu
RUN apt update &amp;&amp; apt install -y git
ENTRYPOINT [&quot;/bin/bash&quot;, &quot;-c&quot;, &quot;sleep 500&quot;]</code></pre>
</li>
<li><p>이미지 빌드 및 컨테이너 실행</p>
<pre><code class="language-sh">docker build -t my-server .
docker run -d my-server
docker exec -it [컨테이너 id] bash
git -v # 컨테이너 내부에 git이 설치되었는지 확인</code></pre>
</li>
</ol>
<h2 id="workdir-작업-디렉토리-지정"><code>WORKDIR</code> 작업 디렉토리 지정</h2>
<p><code>WORKDIR</code>명령어로 작업 디렉터리를 전환하면 그 이후에 등장하는 모든 <code>RUN</code>, <code>CMD</code>, <code>ENTRYPOINT</code>, <code>COPY</code>, <code>ADD</code> 명령문은 해당 디렉터리를 기준으로 실행된다. 작업 디렉터리를 굳이 지정해주는 이유는 컨테이너 내부의 폴더를 깔끔하게 관리하기 위해서이다. 컨테이너도 작은 컴퓨터와 같기 때문에 <code>Dockerfile</code>을 통해 생성되는 파일들을 특정 폴더에 정리해두는 것이 추후에 관리가 쉽다. </p>
<pre><code class="language-docker">WORKDIR [작업 디렉터리로 사용할 절대 경로]
# WORKDIR /usr/src/app</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[도커 볼륨]]></title>
            <link>https://velog.io/@regular_jk_kim/%EB%8F%84%EC%BB%A4-%EB%B3%BC%EB%A5%A8</link>
            <guid>https://velog.io/@regular_jk_kim/%EB%8F%84%EC%BB%A4-%EB%B3%BC%EB%A5%A8</guid>
            <pubDate>Mon, 10 Nov 2025 14:30:50 GMT</pubDate>
            <description><![CDATA[<p>#docker</p>
<p><strong>컨테이너 재배포에도 안전한 데이터 관리를 위한 Docker 볼륨 활용 가이드</strong></p>
<h2 id="컨테이너가-가진-문제점">컨테이너가 가진 문제점</h2>
<p>Docker를 활용하면 특정 프로그램을 컨테이너로 띄울 수 있다. 이 프로그램에 기능이 추가되면 새로운 이미지를 만들어서 컨테이너를 실행시켜야 한다. 이 때, Docker는 기존 컨테이너에서 변경된 부분을 수정하지 않고, 새로운 컨테이너를 만들어서 통째로 갈아끼우는 방식으로 교체를 한다.</p>
<p>이런 특징으로 기존 컨테이너를 새로운 컨테이너로 교체하면, 기존 컨테이너 내부에 있던 데이터도 같이 삭제된다. 만약 이 컨테이너가 DB를 실행시키는 컨테이너였다면 DB에 저장된 데이터도 같이 삭제 된다.</p>
<h2 id="도커-볼륨">도커 볼륨</h2>
<blockquote>
<p>도커 컨테이너에서 데이터를 영속적으로 저장하기 위한 방법</p>
</blockquote>
<p>볼륨은 컨테이너 자체의 저장 공간을 사용하지 않고, 호스트 자체의 저장 공간을 공유해서 사용하는 형태이다.</p>
<h2 id="명령어">명령어</h2>
<pre><code class="language-sh">docker run -v [호스트의 디렉토리 절대경로]:[컨테이너의 디렉토리 절대경로] [이미지명]:[태그명]</code></pre>
<ol>
<li>[호스트의 디렉토리 절대경로]에 디렉토리가 이미 존재할 경우 : 호스트의 디렉터리가 컨테이너의 디렉터리를 덮어씌운다.</li>
<li>[호스트의 디렉토리 절대경로]에 디렉토리가 존재하지 않을 경우 : 호스트의 디렉터리 절대 경로에 디렉터리를 새로 만들고 컨테이너의 디렉터리에 있는 파일들을 호스트의 디렉터리로 복사해온다.</li>
</ol>
<h2 id="docker로-mysql-실행시키기">Docker로 MySQL 실행시키기</h2>
<h3 id="mysql-이미지로-컨테이너-실행시키기">MySQL 이미지로 컨테이너 실행시키기</h3>
<pre><code class="language-sh">docker run -e MYSQL_ROOT_PASSWORD=password123 -p 3306:3306 -d mysql</code></pre>
<ul>
<li><code>docker run</code> : 컨테이너를 생성하고 실행 (이미지가 없다면 자동으로 풀링)</li>
<li><code>-e MYSQL_ROOT_PASSWORD=password123</code> : 컨테이너 내부 MySQL 환경 변수 설정</li>
<li><code>-p 3306:3306</code> : 포트 매핑 설정, <code>[호스트 포트]:[컨테이너 포트]</code> 순서로 매핑하여 로컬에서 컨테이너 접속</li>
<li><code>-d</code> : detached 모드 실행, 컨테이너 로그를 터미널에 출력하지 않고 백그라운드에서 실행</li>
<li><code>mysql</code> : 실행할 docker 이미지 이름</li>
</ul>
<h3 id="mysql-컨테이너-접속">MySQL 컨테이너 접속</h3>
<pre><code class="language-sh">docker exec -it [MySQL 컨테이너 id] bash</code></pre>
<ul>
<li><code>docker exec</code> : 실행 중이면서 선택된 컨테이너 내부에서 명령 실행</li>
<li><code>-it</code> : <code>-i</code> (interactive), <code>-t</code> (TTY), 터미널 입력을 활성화, 쉘 형태로 상호작용</li>
<li><code>bash</code> : 컨테이너 내부에서 실행할 명령, bash 셸을 실행해 컨테이너 내부로 접속</li>
</ul>
<h3 id="컨테이너에서-mysql-접근">컨테이너에서 MySQL 접근</h3>
<pre><code class="language-sh">mysql -u root -p</code></pre>
<h3 id="mysql-데이터베이스-만들기">MySQL 데이터베이스 만들기</h3>
<pre><code class="language-sql">create database mydb;
show databases;</code></pre>
<h3 id="컨테이너-종료">컨테이너 종료</h3>
<pre><code class="language-sh">docker stop [MySQL 컨테이너 id]
docker rm [MySQL 컨테이너 id]</code></pre>
<h3 id="다시-컨테이너를-생성하여-데이터베이스를-조회해보자">다시 컨테이너를 생성하여 데이터베이스를 조회해보자</h3>
<pre><code class="language-sh">docker run -e MYSQL_ROOT_PASSWORD=password123 -p 3306:3306 -d mysql 
docker exec -it [MySQL 컨테이너 ID] bash 

mysql -u root -p 
show databases;</code></pre>
<p>명령어 결과로 이전에 생성한 mydb 데이터베이스가 출력되지 않음을 확인할 수 있다.</p>
<h2 id="볼륨을-활용해-mysql-컨테이너-띄우기">볼륨을 활용해 MySQL 컨테이너 띄우기</h2>
<pre><code class="language-sh">mkdir [MySQL 데이터를 저장하고 싶은 폴더를 원하는 경로에 만들기] # mysql_data 라고 가정</code></pre>
<pre><code class="language-sh"># docker run -v [호스트의 디렉토리 절대경로]:[컨테이너의 디렉토리 절대경로] [이미지명]:[태그명]
docker run -e MYSQL_ROOT_PASSWORD=password123 -p 3306:3306 -v [호스트의 절대 경로]/mysql_data:/var/lib/mysql -d mysql</code></pre>
<p>이제 호스트에 컨테이너의 데이터가 저장된다!</p>
<h3 id="varlibmysql--이-경로는-어디서-알아낸거임"><code>/var/lib/mysql</code>  이 경로는 어디서 알아낸거임?</h3>
<p>해당 위치 설정은 도커 허브의 MySQL 공식 문서 <a href="https://hub.docker.com/_/mysql#user-content-where-to-store-data">Where to Store Data</a> 부분에서 확인할 수 있다.</p>
<p>postgresql 혹은 mongoDB 를 사용할 때도 공식 문서에서 해당 값을 확인할 수 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[251109]]></title>
            <link>https://velog.io/@regular_jk_kim/251109</link>
            <guid>https://velog.io/@regular_jk_kim/251109</guid>
            <pubDate>Sun, 09 Nov 2025 07:23:54 GMT</pubDate>
            <description><![CDATA[<p>#회고 </p>
<h2 id="251109-회고-💬">251109 회고 💬</h2>
<p>11월 두 번째 주차를 회고한다.</p>
<h2 id="keep-👍">Keep 👍</h2>
<h3 id="출퇴근-자투리-공부">출퇴근 자투리 공부</h3>
<p>장고 공부를 시작했다. 장고는 정말 처음이다. 그런데 회사에서는 장고를 사용한다. 모르는데 해야한다? 공부해야지 뭐,,, 그래서 출퇴근 길에 장고 수업을 듣고 있다. 기본적으로 풀스택 프레임워크이기 때문에 화면 관련된 내용이 많다. 하지만 다행히도 api 서버 제작만 하면 되기 때문에 프론트 내용은 모두 스킵하고, 필요한 내용만 취사선택해서 학습 중이다.</p>
<ul>
<li>가상환경 (venv, poetry, uv)</li>
<li>앱 등록 (python manage.py startapp)</li>
<li>view 작성</li>
<li>마이그레이션</li>
<li>쿼리셋</li>
<li>Class-based View</li>
<li>로그인 세션</li>
<li>M2M<ul>
<li>ManyToManyField</li>
<li>through</li>
</ul>
</li>
<li>Lazy Loading</li>
<li>N + 1</li>
</ul>
<h3 id="개인-공부">개인 공부</h3>
<p>회사 온보딩 과정 겸, 실제 업무 겸 해서 장고 프로젝트를 진행 중이다. 이번에야말로 TDD를 해보겠다! 라는 큰 다짐과 함께 실제로 작업 중이다. 하지만 현실의 벽을 느끼고서 TDD는 못했다. 일단 요구사항이 디테일하지 않아서 모든 작업 사항들을 내가 먼저 추측하여 진행해야 한다. 그러면 더 TDD하기에 좋은 상황 아니냐고? 아니다. 기획 디테일을 내가 작업하다 보니 정작 코딩할 시간이 부족하다. 그래서 TDD까지는 아니더라도 API 제작 후 API에 필요한 시나리오를 작성하여 해당 시나리오에 부합하도록 테스트 코드를 작성 중이다. 대략 40개 정도 API를 구현했고 약 240개 정도의 테스트를 작업했다. 그러니까 대충 API 1개당 6개 정도의 테스트 코드 작업을 해냈다. 이것만 해도 어떤가! 🙆</p>
<h3 id="운동">운동</h3>
<p>매일 헬스장에 나가 운동하려고 노력 중이다. 이번 평일에는 <strong>2</strong>일 성공했다. </p>
<ul>
<li>월요일 어깨</li>
<li>화요일 가슴</li>
<li>수요일 하체</li>
<li>목요일 등</li>
<li>금요일 이두삼수 (잘 안 함)</li>
</ul>
<h3 id="독서">독서</h3>
<p>혼자 공부하는 네트워크를 읽고있다.</p>
<h2 id="try-🧚">Try 🧚</h2>
<ul>
<li>장고 공부하기</li>
<li>도커 공부하기</li>
<li>쿠버네티스 공부하기</li>
<li>혼자 공부하는 네트워크 읽기</li>
</ul>
<h2 id="problem-🤢">Problem 🤢</h2>
<p>요즘 독서를 못(안)하고 있다. 책읽기가 왜이렇게 싫지,,, 주말 만이라도 읽으려고 노력 중인데 참 쉽지가 않다.</p>
<h2 id="독서-목록">독서 목록</h2>
<h3 id="서평-완료-목록">서평 완료 목록</h3>
<ul>
<li><a href="https://velog.io/@regular_jk_kim/%ED%98%BC%EC%9E%90-%EA%B3%B5%EB%B6%80%ED%95%98%EB%8A%94-%EC%BB%B4%ED%93%A8%ED%84%B0-%EA%B5%AC%EC%A1%B0-%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%EB%A5%BC-%EC%9D%BD%EA%B3%A0">혼자 공부하는 컴퓨터 구조 + 운영체제</a></li>
<li><a href="https://velog.io/@regular_jk_kim/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%9D%98-%EA%B8%B8-%EB%A9%98%ED%86%A0%EC%97%90%EA%B2%8C-%EB%AC%BB%EB%8B%A4-%EB%A5%BC-%EC%9D%BD%EA%B3%A0-24jpq345">프로그래머의 길, 멘토에게 묻다</a></li>
<li><a href="https://velog.io/@regular_jk_kim/%ED%95%A8%EA%BB%98-%EC%9E%90%EB%9D%BC%EA%B8%B0-%EB%A5%BC-%EC%9D%BD%EA%B3%A0">함께 자라기 애자일로 가는 길</a></li>
<li><a href="https://velog.io/@regular_jk_kim/%EA%B0%9D%EC%B2%B4%EC%A7%80%ED%96%A5%EC%9D%98-%EC%82%AC%EC%8B%A4%EA%B3%BC-%EC%98%A4%ED%95%B4-%EB%A5%BC-%EC%9D%BD%EA%B3%A0">객체지향의 사실과 오해</a></li>
</ul>
<h3 id="서평-예정-목록-읽는-중">서평 예정 목록 (읽는 중)</h3>
<ul>
<li>혼자 공부하는 네트워크 (19%)</li>
</ul>
<h3 id="으악-재미없어-🤪">으악 재미없어,,, 🤪</h3>
<ul>
<li><del>면접을 위한 CS 전공지식 노트</del></li>
<li><del>한 권으로 읽는 컴퓨터 구조와 프로그래밍</del></li>
</ul>
<h3 id="독서-예정-목록">독서 예정 목록</h3>
<ul>
<li>혼자 공부하는 네트워크</li>
<li>오브젝트</li>
<li>HTTP 완벽 가이드</li>
<li>자바/스프링 개발자를 위한 실용주의 프로그래밍</li>
<li>모던 자바 인 액션</li>
<li>자바 성능 튜닝 이야기 </li>
<li>헤드 퍼스트 서블릿</li>
<li>파이브 라인스 오브 코드</li>
</ul>
<h2 id="extras">Extras</h2>
]]></description>
        </item>
        <item>
            <title><![CDATA[251102]]></title>
            <link>https://velog.io/@regular_jk_kim/251102</link>
            <guid>https://velog.io/@regular_jk_kim/251102</guid>
            <pubDate>Sun, 02 Nov 2025 10:43:29 GMT</pubDate>
            <description><![CDATA[<p>#회고 </p>
<h2 id="251102-회고-💬">251102 회고 💬</h2>
<p>아침에는 춥고, 저녁에는 덥고! 또 어느 장단에 맞춰야할지 모르겠는 날씨가 찾아왔다. 후 출퇴근마다 열받는다. </p>
<h2 id="keep-👍">Keep 👍</h2>
<h3 id="출퇴근-자투리-공부">출퇴근 자투리 공부</h3>
<p>DataBase 공부를 하고있다. 그간 애플리케이션만 공부하느라 DB 공부할 시간이 없었는데 이번 기회로 오랜만에 DB 복습을 하고 있다.</p>
<p>인덱스 부분을 공부했다. 이런말 하기 부끄럽지만 인덱스를 처음 공부했다. 매번 시작할 때 처음 부분만 공부하고 포기해버려서 인덱스까지 공부해본적이 없다. 그래서 이번에 처음으로 알게되었다. 쿼리 최적화를 신경써야할 일이 아직까지는 없었어서(<del>캐싱으로 다 해결!</del>) 인덱스 공부에 큰 흥미가 없기도 했다.</p>
<ul>
<li>인덱스</li>
<li>check 제약 조건</li>
<li>트랜잭션</li>
</ul>
<h3 id="개인-공부">개인 공부</h3>
<ul>
<li>장고 공부를 하고있다. 진도가 생각보다 안 나간다. 술만 줄이면 열공할거 같은데.... 🤪</li>
<li>장고 프로젝트를 제작하고 있다. 처음에는 장고 스타일로 제작을 하려고 했다. 그래서 스타일에 맞춰서 개발을 좀 해봤다. 그런데 하면 할수록 스타일이 맘에 안 들었다. 계층적으로 분리된 스타일을 선호한다. 그런데 장고에서는 내가 원하는 기능을 어느 레이어에서건 선언해서 사용할 수 있다. 이런 자유로움이라니! 자유로움에 불편함을 아이러니한 상황이다. 이런 상황이다보니 시간이 지날수록 점점 내 원래 스타일에 맞춰서 개발이 되고 있다. 처음에는 장고 스타일, 좀 지나고 보니 layered 스타일, 지금은 유스 케이스 스타일로 개발이 되고 있다... 이거 동료들한테 미안해지는데... 날잡고 빨리 리팩토링을 해야겠다.</li>
</ul>
<h3 id="운동">운동</h3>
<p>매일 헬스장에 나가 운동하려고 노력 중이다. 이번 평일에는 <strong>4</strong>일 성공했다. 운동 기록 어플로 무게와 횟수를 기록하기 시작했다. </p>
<h3 id="독서">독서</h3>
<p>혼자 공부하는 네트워크를 읽고있다.</p>
<h2 id="try-🧚">Try 🧚</h2>
<ul>
<li>장고 공부하기</li>
<li>도커 공부하기</li>
<li>쿠버네티스 공부하기</li>
<li>혼자 공부하는 네트워크 읽기</li>
</ul>
<h2 id="problem-🤢">Problem 🤢</h2>
<p>요즘 독서를 못(안)하고 있다. 책읽기가 왜이렇게 싫지,,, 주말 만이라도 읽으려고 노력 중인데 참 쉽지가 않다.</p>
<h2 id="독서-목록">독서 목록</h2>
<h3 id="서평-완료-목록">서평 완료 목록</h3>
<ul>
<li><a href="https://velog.io/@regular_jk_kim/%ED%98%BC%EC%9E%90-%EA%B3%B5%EB%B6%80%ED%95%98%EB%8A%94-%EC%BB%B4%ED%93%A8%ED%84%B0-%EA%B5%AC%EC%A1%B0-%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%EB%A5%BC-%EC%9D%BD%EA%B3%A0">혼자 공부하는 컴퓨터 구조 + 운영체제</a></li>
<li><a href="https://velog.io/@regular_jk_kim/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%9D%98-%EA%B8%B8-%EB%A9%98%ED%86%A0%EC%97%90%EA%B2%8C-%EB%AC%BB%EB%8B%A4-%EB%A5%BC-%EC%9D%BD%EA%B3%A0-24jpq345">프로그래머의 길, 멘토에게 묻다</a></li>
<li><a href="https://velog.io/@regular_jk_kim/%ED%95%A8%EA%BB%98-%EC%9E%90%EB%9D%BC%EA%B8%B0-%EB%A5%BC-%EC%9D%BD%EA%B3%A0">함께 자라기 애자일로 가는 길</a></li>
<li><a href="https://velog.io/@regular_jk_kim/%EA%B0%9D%EC%B2%B4%EC%A7%80%ED%96%A5%EC%9D%98-%EC%82%AC%EC%8B%A4%EA%B3%BC-%EC%98%A4%ED%95%B4-%EB%A5%BC-%EC%9D%BD%EA%B3%A0">객체지향의 사실과 오해</a></li>
</ul>
<h3 id="서평-예정-목록-읽는-중">서평 예정 목록 (읽는 중)</h3>
<ul>
<li>혼자 공부하는 네트워크 (19%)</li>
</ul>
<h3 id="으악-재미없어-🤪">으악 재미없어,,, 🤪</h3>
<ul>
<li><del>면접을 위한 CS 전공지식 노트</del></li>
<li><del>한 권으로 읽는 컴퓨터 구조와 프로그래밍</del></li>
</ul>
<h3 id="독서-예정-목록">독서 예정 목록</h3>
<ul>
<li>혼자 공부하는 네트워크</li>
<li>오브젝트</li>
<li>HTTP 완벽 가이드</li>
<li>자바/스프링 개발자를 위한 실용주의 프로그래밍</li>
<li>모던 자바 인 액션</li>
<li>자바 성능 튜닝 이야기 </li>
<li>헤드 퍼스트 서블릿</li>
<li>파이브 라인스 오브 코드</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[251026]]></title>
            <link>https://velog.io/@regular_jk_kim/251026</link>
            <guid>https://velog.io/@regular_jk_kim/251026</guid>
            <pubDate>Sun, 26 Oct 2025 09:05:14 GMT</pubDate>
            <description><![CDATA[<p>#회고 </p>
<h2 id="251026-회고-💬">251026 회고 💬</h2>
<p>엄청 춥다! 저번 주 까지만 해도 에어컨 켜야하나 고민할 정도로 더웠는데, 하루만에 엄청나게 추워졌다. 겨울옷을 급하게 꺼내야겠다.</p>
<h2 id="keep-👍">Keep 👍</h2>
<h3 id="출퇴근-자투리-공부">출퇴근 자투리 공부</h3>
<p>DataBase 공부를 하고있다. 그간 애플리케이션만 공부하느라 DB 공부할 시간이 없었는데 이번 기회로 오랜만에 DB 복습을 하고 있다.</p>
<ul>
<li>UNION</li>
<li>CASE</li>
<li>VIEW</li>
</ul>
<h3 id="개인-공부">개인 공부</h3>
<ul>
<li>장고 공부를 하고있다. 진도가 생각보다 안 나간다. 술만 줄이면 열공할거 같은데.... 🤪</li>
</ul>
<h3 id="운동">운동</h3>
<p>매일 헬스장에 나가 운동하려고 노력 중이다. 이번 평일에는 <strong>4</strong>일 성공했다. 일찍 일어나면 아침에 운동, 늦으면 저녁에 운동하는 식으로 진행했다. 온 몸이 아프다...</p>
<h3 id="독서">독서</h3>
<p>혼자 공부하는 네트워크를 읽고있다.</p>
<h2 id="try-🧚">Try 🧚</h2>
<ul>
<li>장고 공부하기</li>
<li>도커 공부하기</li>
<li>쿠버네티스 공부하기</li>
<li>혼자 공부하는 네트워크 읽기</li>
</ul>
<h2 id="problem-🤢">Problem 🤢</h2>
<p>요즘 독서를 못(안)하고 있다. 책읽기가 왜이렇게 싫지,,, 주말 만이라도 읽으려고 노력 중인데 참 쉽지가 않다.</p>
<h2 id="독서-목록">독서 목록</h2>
<h3 id="서평-완료-목록">서평 완료 목록</h3>
<ul>
<li><a href="https://velog.io/@regular_jk_kim/%ED%98%BC%EC%9E%90-%EA%B3%B5%EB%B6%80%ED%95%98%EB%8A%94-%EC%BB%B4%ED%93%A8%ED%84%B0-%EA%B5%AC%EC%A1%B0-%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%EB%A5%BC-%EC%9D%BD%EA%B3%A0">혼자 공부하는 컴퓨터 구조 + 운영체제</a></li>
<li><a href="https://velog.io/@regular_jk_kim/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%9D%98-%EA%B8%B8-%EB%A9%98%ED%86%A0%EC%97%90%EA%B2%8C-%EB%AC%BB%EB%8B%A4-%EB%A5%BC-%EC%9D%BD%EA%B3%A0-24jpq345">프로그래머의 길, 멘토에게 묻다</a></li>
<li><a href="https://velog.io/@regular_jk_kim/%ED%95%A8%EA%BB%98-%EC%9E%90%EB%9D%BC%EA%B8%B0-%EB%A5%BC-%EC%9D%BD%EA%B3%A0">함께 자라기 애자일로 가는 길</a></li>
<li><a href="https://velog.io/@regular_jk_kim/%EA%B0%9D%EC%B2%B4%EC%A7%80%ED%96%A5%EC%9D%98-%EC%82%AC%EC%8B%A4%EA%B3%BC-%EC%98%A4%ED%95%B4-%EB%A5%BC-%EC%9D%BD%EA%B3%A0">객체지향의 사실과 오해</a></li>
</ul>
<h3 id="서평-예정-목록-읽는-중">서평 예정 목록 (읽는 중)</h3>
<ul>
<li>혼자 공부하는 네트워크 (19%)</li>
</ul>
<h3 id="으악-재미없어-🤪">으악 재미없어,,, 🤪</h3>
<ul>
<li><del>면접을 위한 CS 전공지식 노트</del></li>
<li><del>한 권으로 읽는 컴퓨터 구조와 프로그래밍</del></li>
</ul>
<h3 id="독서-예정-목록">독서 예정 목록</h3>
<ul>
<li>혼자 공부하는 네트워크</li>
<li>오브젝트</li>
<li>HTTP 완벽 가이드</li>
<li>자바/스프링 개발자를 위한 실용주의 프로그래밍</li>
<li>모던 자바 인 액션</li>
<li>자바 성능 튜닝 이야기 </li>
<li>헤드 퍼스트 서블릿</li>
<li>파이브 라인스 오브 코드</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[251019]]></title>
            <link>https://velog.io/@regular_jk_kim/251019</link>
            <guid>https://velog.io/@regular_jk_kim/251019</guid>
            <pubDate>Sun, 19 Oct 2025 08:40:38 GMT</pubDate>
            <description><![CDATA[<p>#회고 </p>
<h2 id="251019-회고-💬">251019 회고 💬</h2>
<p>친구가 결혼을 한단다... 와! 청첩장 모임에 다녀왔다. 대학교 동기가 결혼을 한다니 뭔가 신기하다. 오랜만에 다들 모여서 즐거운 시간을 보냈다. </p>
<h2 id="keep-👍">Keep 👍</h2>
<h3 id="출퇴근-자투리-공부">출퇴근 자투리 공부</h3>
<p>DataBase 공부를 하고있다. 그간 애플리케이션만 공부하느라 DB 공부할 시간이 없었는데 이번 기회로 오랜만에 DB 복습을 하고 있다.</p>
<ul>
<li>GROUP BY</li>
<li>HAVING</li>
<li>INNER JOIN</li>
<li>LEFT JOIN</li>
<li>SELF JOIN</li>
</ul>
<h3 id="개인-공부">개인 공부</h3>
<ul>
<li>기존에 하던 프로젝트는 취소하고, 새로운 프로젝트에 투입될듯 하다. 파이썬 장고 사용할거라고 하는데,,, 한번도 안 해봐서 걱정 반, 기대 반, 내 감정을 모르겠다. 열심히 해보자.</li>
</ul>
<h3 id="운동">운동</h3>
<p>매일 헬스장에 나가 운동하려고 노력 중이다. 이번 평일에는 <strong>2</strong>일 성공했다. 집앞, 옆동네 헬스장 일일권으로 어디가 괜찮나 비교해보고 괜찮은 곳으로 정했다. 연말까지 열심히 다녀보자. 제발~ 🏋️‍</p>
<h3 id="독서">독서</h3>
<p>혼자 공부하는 네트워크를 읽고있다.</p>
<h2 id="try-🧚">Try 🧚</h2>
<ul>
<li>장고 공부하기</li>
<li>도커 공부하기</li>
<li>쿠버네티스 공부하기</li>
<li>혼자 공부하는 네트워크 읽기</li>
</ul>
<h2 id="독서-목록">독서 목록</h2>
<h3 id="서평-완료-목록">서평 완료 목록</h3>
<ul>
<li><a href="https://velog.io/@regular_jk_kim/%ED%98%BC%EC%9E%90-%EA%B3%B5%EB%B6%80%ED%95%98%EB%8A%94-%EC%BB%B4%ED%93%A8%ED%84%B0-%EA%B5%AC%EC%A1%B0-%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%EB%A5%BC-%EC%9D%BD%EA%B3%A0">혼자 공부하는 컴퓨터 구조 + 운영체제</a></li>
<li><a href="https://velog.io/@regular_jk_kim/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%9D%98-%EA%B8%B8-%EB%A9%98%ED%86%A0%EC%97%90%EA%B2%8C-%EB%AC%BB%EB%8B%A4-%EB%A5%BC-%EC%9D%BD%EA%B3%A0-24jpq345">프로그래머의 길, 멘토에게 묻다</a></li>
<li><a href="https://velog.io/@regular_jk_kim/%ED%95%A8%EA%BB%98-%EC%9E%90%EB%9D%BC%EA%B8%B0-%EB%A5%BC-%EC%9D%BD%EA%B3%A0">함께 자라기 애자일로 가는 길</a></li>
<li><a href="https://velog.io/@regular_jk_kim/%EA%B0%9D%EC%B2%B4%EC%A7%80%ED%96%A5%EC%9D%98-%EC%82%AC%EC%8B%A4%EA%B3%BC-%EC%98%A4%ED%95%B4-%EB%A5%BC-%EC%9D%BD%EA%B3%A0">객체지향의 사실과 오해</a></li>
</ul>
<h3 id="서평-예정-목록-읽는-중">서평 예정 목록 (읽는 중)</h3>
<ul>
<li>혼자 공부하는 네트워크 (19%)</li>
</ul>
<h3 id="으악-재미없어-🤪">으악 재미없어,,, 🤪</h3>
<ul>
<li><del>면접을 위한 CS 전공지식 노트</del></li>
<li><del>한 권으로 읽는 컴퓨터 구조와 프로그래밍</del></li>
</ul>
<h3 id="독서-예정-목록">독서 예정 목록</h3>
<ul>
<li>혼자 공부하는 네트워크</li>
<li>오브젝트</li>
<li>HTTP 완벽 가이드</li>
<li>자바/스프링 개발자를 위한 실용주의 프로그래밍</li>
<li>모던 자바 인 액션</li>
<li>자바 성능 튜닝 이야기 </li>
<li>헤드 퍼스트 서블릿</li>
<li>파이브 라인스 오브 코드</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[251012]]></title>
            <link>https://velog.io/@regular_jk_kim/251012</link>
            <guid>https://velog.io/@regular_jk_kim/251012</guid>
            <pubDate>Sun, 12 Oct 2025 10:53:08 GMT</pubDate>
            <description><![CDATA[<p>#회고 </p>
<h2 id="251012-회고-💬">251012 회고 💬</h2>
<p>민족 대명절 추석이었다. 그리고 엄청 긴 연휴였다. 그리고 나에게도 큰 의미를 가지는 시기다. 첫 출근(생에 첫 출근은 아니지만)을 했다. 스타트업에 입사해서 이런저런 안내받고 작업할 내용 설계하고 등등 작업을 했다. 추석이라 1주 쉬고서 다시 회고를 시작해본다.</p>
<h2 id="keep-👍">Keep 👍</h2>
<h3 id="출퇴근-자투리-공부">출퇴근 자투리 공부</h3>
<p>DataBase 공부를 하고있다. 집계함수 공부를 했다. 사실 다 아는 내용이다. 그럼에도 왜 듣냐 하냐면, 출근길에 심심하니까,,,</p>
<h3 id="개인-공부">개인 공부</h3>
<ul>
<li>개인 공부 겸, 인턴 과제를 하고 있다. 일단은 초반이라 단순한 crud api 작업 중이다. 좀 신경쓰는 부분이 하나 있다면 테스트 코드 작성이다. TDD 수준은 아니고, api 명세 설계 후에 필요한 기능들 정의하고, 그 기능들에 맞춰 작동하는지 확인하는 테스트 코드를 작성 중이다. 현재 API 개수가 10개 정도 되는데 테스트는 60개 정도,,, 하핳 즐겁다.</li>
</ul>
<h3 id="독서">독서</h3>
<p>혼자 공부하는 네트워크를 읽고있다.</p>
<h2 id="try-🧚">Try 🧚</h2>
<ul>
<li>카프카 공부하기</li>
<li>혼자 공부하는 네트워크 읽기</li>
</ul>
<h2 id="problem-🤢">Problem 🤢</h2>
<ul>
<li>해야지 해야지 다짐만 하면서 운동 안 하고 있다. 헬스장 빨리 알아봐야겠다.</li>
</ul>
<h2 id="독서-목록">독서 목록</h2>
<h3 id="서평-완료-목록">서평 완료 목록</h3>
<ul>
<li><a href="https://velog.io/@regular_jk_kim/%ED%98%BC%EC%9E%90-%EA%B3%B5%EB%B6%80%ED%95%98%EB%8A%94-%EC%BB%B4%ED%93%A8%ED%84%B0-%EA%B5%AC%EC%A1%B0-%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%EB%A5%BC-%EC%9D%BD%EA%B3%A0">혼자 공부하는 컴퓨터 구조 + 운영체제</a></li>
<li><a href="https://velog.io/@regular_jk_kim/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%9D%98-%EA%B8%B8-%EB%A9%98%ED%86%A0%EC%97%90%EA%B2%8C-%EB%AC%BB%EB%8B%A4-%EB%A5%BC-%EC%9D%BD%EA%B3%A0-24jpq345">프로그래머의 길, 멘토에게 묻다</a></li>
<li><a href="https://velog.io/@regular_jk_kim/%ED%95%A8%EA%BB%98-%EC%9E%90%EB%9D%BC%EA%B8%B0-%EB%A5%BC-%EC%9D%BD%EA%B3%A0">함께 자라기 애자일로 가는 길</a></li>
<li><a href="https://velog.io/@regular_jk_kim/%EA%B0%9D%EC%B2%B4%EC%A7%80%ED%96%A5%EC%9D%98-%EC%82%AC%EC%8B%A4%EA%B3%BC-%EC%98%A4%ED%95%B4-%EB%A5%BC-%EC%9D%BD%EA%B3%A0">객체지향의 사실과 오해</a></li>
</ul>
<h3 id="서평-예정-목록-읽는-중">서평 예정 목록 (읽는 중)</h3>
<ul>
<li>혼자 공부하는 네트워크 (19%)</li>
</ul>
<h3 id="으악-재미없어-🤪">으악 재미없어,,, 🤪</h3>
<ul>
<li><del>면접을 위한 CS 전공지식 노트</del></li>
<li><del>한 권으로 읽는 컴퓨터 구조와 프로그래밍</del></li>
</ul>
<h3 id="독서-예정-목록">독서 예정 목록</h3>
<ul>
<li>혼자 공부하는 네트워크</li>
<li>오브젝트</li>
<li>HTTP 완벽 가이드</li>
<li>자바/스프링 개발자를 위한 실용주의 프로그래밍</li>
<li>모던 자바 인 액션</li>
<li>자바 성능 튜닝 이야기 </li>
<li>헤드 퍼스트 서블릿</li>
<li>파이브 라인스 오브 코드</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[250928]]></title>
            <link>https://velog.io/@regular_jk_kim/250928</link>
            <guid>https://velog.io/@regular_jk_kim/250928</guid>
            <pubDate>Sun, 28 Sep 2025 10:50:11 GMT</pubDate>
            <description><![CDATA[<p>#회고 </p>
<h2 id="250928-회고-💬">250928 회고 💬</h2>
<p>날이 많이 시원해졌다. 그러면서 가을 냄새도 나기 시작함... 저번 주에는 면접이 몰려서 1주 쉬고 다시 회고를 작성한다. 그리고 좋은 일이 하나 있다. 바로바로 취업 성공했다. 원하던 스타트업에 입사하게 됐다. 예스! 🤩 열심히 일해보자!</p>
<h2 id="keep-👍">Keep 👍</h2>
<h3 id="알고리즘">알고리즘</h3>
<p>알고리즘 문제풀이를 계속하고 있다. 이제 알고리즘 문제를 놓아줄 때가 됐다. 이전에 다짐했던대로 알고리즘은 잠시 쉬고, 프로젝트나, 필요 기술 위주로 커밋을 채워보려고한다. 약 2년간 수고했다!</p>
<h3 id="출퇴근-자투리-공부">출퇴근 자투리 공부</h3>
<p>DataBase 공부를 하고있다.</p>
<h3 id="ssafy-프로젝트-학기">SSAFY 프로젝트 학기</h3>
<p>취업하게 되면서 SSAFY 프로젝트에 신경을 꺼버렸다. 팀원들에게 미안하다! </p>
<h3 id="독서">독서</h3>
<p>혼자 공부하는 네트워크를 읽고있다.</p>
<h2 id="try-🧚">Try 🧚</h2>
<ul>
<li>카프카 공부하기</li>
<li>혼자 공부하는 네트워크 읽기</li>
</ul>
<h2 id="독서-목록">독서 목록</h2>
<h3 id="서평-완료-목록">서평 완료 목록</h3>
<ul>
<li><a href="https://velog.io/@regular_jk_kim/%ED%98%BC%EC%9E%90-%EA%B3%B5%EB%B6%80%ED%95%98%EB%8A%94-%EC%BB%B4%ED%93%A8%ED%84%B0-%EA%B5%AC%EC%A1%B0-%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%EB%A5%BC-%EC%9D%BD%EA%B3%A0">혼자 공부하는 컴퓨터 구조 + 운영체제</a></li>
<li><a href="https://velog.io/@regular_jk_kim/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%9D%98-%EA%B8%B8-%EB%A9%98%ED%86%A0%EC%97%90%EA%B2%8C-%EB%AC%BB%EB%8B%A4-%EB%A5%BC-%EC%9D%BD%EA%B3%A0-24jpq345">프로그래머의 길, 멘토에게 묻다</a></li>
<li><a href="https://velog.io/@regular_jk_kim/%ED%95%A8%EA%BB%98-%EC%9E%90%EB%9D%BC%EA%B8%B0-%EB%A5%BC-%EC%9D%BD%EA%B3%A0">함께 자라기 애자일로 가는 길</a></li>
<li><a href="https://velog.io/@regular_jk_kim/%EA%B0%9D%EC%B2%B4%EC%A7%80%ED%96%A5%EC%9D%98-%EC%82%AC%EC%8B%A4%EA%B3%BC-%EC%98%A4%ED%95%B4-%EB%A5%BC-%EC%9D%BD%EA%B3%A0">객체지향의 사실과 오해</a></li>
</ul>
<h3 id="서평-예정-목록-읽는-중">서평 예정 목록 (읽는 중)</h3>
<ul>
<li>혼자 공부하는 네트워크 (16%)</li>
</ul>
<h3 id="으악-재미없어-🤪">으악 재미없어,,, 🤪</h3>
<ul>
<li><del>면접을 위한 CS 전공지식 노트</del></li>
<li><del>한 권으로 읽는 컴퓨터 구조와 프로그래밍</del></li>
</ul>
<h3 id="독서-예정-목록">독서 예정 목록</h3>
<ul>
<li>혼자 공부하는 네트워크</li>
<li>오브젝트</li>
<li>HTTP 완벽 가이드</li>
<li>자바/스프링 개발자를 위한 실용주의 프로그래밍</li>
<li>모던 자바 인 액션</li>
<li>자바 성능 튜닝 이야기 </li>
<li>헤드 퍼스트 서블릿</li>
<li>파이브 라인스 오브 코드</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[250914]]></title>
            <link>https://velog.io/@regular_jk_kim/250914</link>
            <guid>https://velog.io/@regular_jk_kim/250914</guid>
            <pubDate>Sun, 14 Sep 2025 09:43:44 GMT</pubDate>
            <description><![CDATA[<p>#회고 </p>
<h2 id="250914-회고-💬">250914 회고 💬</h2>
<h2 id="keep-👍">Keep 👍</h2>
<h3 id="알고리즘">알고리즘</h3>
<p>알고리즘 문제풀이를 계속하고 있다.</p>
<h3 id="출퇴근-자투리-공부">출퇴근 자투리 공부</h3>
<p>DataBase 공부를 하고있다.</p>
<h3 id="ssafy-프로젝트-학기">SSAFY 프로젝트 학기</h3>
<p>팀원들과 프로젝트 시작 전에 약속을 하나 했다. 매인 애플리케이션을 TDD로 진행하자는 약속이다. 그래서 관련 공부를 꽤나 열심히 했다. 아직까지는 TDD 도입이 잘 되고 있다. 지금은 대략 78% 정도 테스트 커버리지를 유지 중이다. 꼼꼼한 테스트보다는 컨트롤러 테스트만 진행하기로 했다.</p>
<p>이제껏 인프라 경험이 없다. 그래서 먼저 나서서 인프라 관리 역할을 맡기로 했다. GitLab 으로 배포 파이프라인을 만들어야한다. 그런데 너무 어렵다. 깃랩 ci 설정을 어떻게 하는지 내용 정리를 해봤다. 해당 내용은 <a href="https://velog.io/@regular_jk_kim/.gitlab-ci.yml-%EC%A0%84%EC%97%AD-%ED%82%A4%EC%9B%8C%EB%93%9C-default-variables">여기</a>와 <a href="https://velog.io/@regular_jk_kim/.gitlab-ci.yml-%ED%8C%8C%EC%9D%BC-stages-%ED%82%A4%EC%9B%8C%EB%93%9C">여기서</a> 볼 수 있다.</p>
<p>프로젝트 완료 작업 리스트</p>
<ul>
<li>백엔드 아키텍처 기획</li>
<li>프로젝트 생성</li>
<li>vitals(프로젝트 이름) 생성</li>
<li>client 서버 생성</li>
<li>traffic 생성기 생성</li>
<li>도커 파일로 이미지 생성하기</li>
<li>fluent bit 사용하여 컨테이너에서 로그 추출하기
프로젝트 TODO</li>
<li>CICD (GitLab)</li>
<li>Hadoop/Spark</li>
<li>Kafka</li>
<li>Infra Docker-Compose 정리</li>
<li>동료 코드 리뷰</li>
</ul>
<h3 id="운동">운동</h3>
<p>매일 헬스장에 나가 운동하려고 노력 중이다. 이번 평일에는 <strong>1</strong>일 성공했다.</p>
<h3 id="독서">독서</h3>
<p>혼자 공부하는 네트워크를 읽고있다.</p>
<h2 id="try-🧚">Try 🧚</h2>
<ul>
<li>카프카 공부하기</li>
<li>혼자 공부하는 네트워크 읽기</li>
</ul>
<h2 id="독서-목록">독서 목록</h2>
<h3 id="서평-완료-목록">서평 완료 목록</h3>
<ul>
<li><a href="https://velog.io/@regular_jk_kim/%ED%98%BC%EC%9E%90-%EA%B3%B5%EB%B6%80%ED%95%98%EB%8A%94-%EC%BB%B4%ED%93%A8%ED%84%B0-%EA%B5%AC%EC%A1%B0-%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%EB%A5%BC-%EC%9D%BD%EA%B3%A0">혼자 공부하는 컴퓨터 구조 + 운영체제</a></li>
<li><a href="https://velog.io/@regular_jk_kim/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%9D%98-%EA%B8%B8-%EB%A9%98%ED%86%A0%EC%97%90%EA%B2%8C-%EB%AC%BB%EB%8B%A4-%EB%A5%BC-%EC%9D%BD%EA%B3%A0-24jpq345">프로그래머의 길, 멘토에게 묻다</a></li>
<li><a href="https://velog.io/@regular_jk_kim/%ED%95%A8%EA%BB%98-%EC%9E%90%EB%9D%BC%EA%B8%B0-%EB%A5%BC-%EC%9D%BD%EA%B3%A0">함께 자라기 애자일로 가는 길</a></li>
<li><a href="https://velog.io/@regular_jk_kim/%EA%B0%9D%EC%B2%B4%EC%A7%80%ED%96%A5%EC%9D%98-%EC%82%AC%EC%8B%A4%EA%B3%BC-%EC%98%A4%ED%95%B4-%EB%A5%BC-%EC%9D%BD%EA%B3%A0">객체지향의 사실과 오해</a></li>
</ul>
<h3 id="서평-예정-목록-읽는-중">서평 예정 목록 (읽는 중)</h3>
<ul>
<li>혼자 공부하는 네트워크 (16%)</li>
</ul>
<h3 id="으악-재미없어-🤪">으악 재미없어,,, 🤪</h3>
<ul>
<li><del>면접을 위한 CS 전공지식 노트</del></li>
<li><del>한 권으로 읽는 컴퓨터 구조와 프로그래밍</del></li>
</ul>
<h3 id="독서-예정-목록">독서 예정 목록</h3>
<ul>
<li>혼자 공부하는 네트워크</li>
<li>오브젝트</li>
<li>HTTP 완벽 가이드</li>
<li>자바/스프링 개발자를 위한 실용주의 프로그래밍</li>
<li>모던 자바 인 액션</li>
<li>자바 성능 튜닝 이야기 </li>
<li>헤드 퍼스트 서블릿</li>
<li>파이브 라인스 오브 코드</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[.gitlab-ci.yml 파일 stages 키워드]]></title>
            <link>https://velog.io/@regular_jk_kim/.gitlab-ci.yml-%ED%8C%8C%EC%9D%BC-stages-%ED%82%A4%EC%9B%8C%EB%93%9C</link>
            <guid>https://velog.io/@regular_jk_kim/.gitlab-ci.yml-%ED%8C%8C%EC%9D%BC-stages-%ED%82%A4%EC%9B%8C%EB%93%9C</guid>
            <pubDate>Tue, 09 Sep 2025 18:14:02 GMT</pubDate>
            <description><![CDATA[<p>#infra </p>
<p>기본적으로 gitlab의 job 은 병렬로 실행된다. 별다른 설정이 없다면 병렬 작업이 기본이다. 그런데 아래의 경우를 생각해보자.</p>
<ul>
<li>특정 작업 전 다른 작업을 해야하는 경우</li>
<li>특정 종류의 작업들을 그룹으로 지정해야 하는 경우</li>
<li>특정 작업 실패시 후속 동작을 지정해야 하는 경우</li>
</ul>
<p>이 외에도 다른 여러 경우가 있을 수 있다. 그리고 이 경우들 모두 작업의 순서가 있어야한다는 의미를 내포한다. 이와 같은 경우에 사용할 수 있는 키워드가 <code>stages</code> 이다.</p>
<h2 id="stages">stages</h2>
<p>여러 job들의 순서를 지정하고, 그룹을 만들어 줄 수 있다. 그리고 이렇게 모여진 job들은 당연히 병렬로 실행된다.</p>
<ul>
<li>stages -&gt; 순서대로 실행됨</li>
<li>stage 내부의 jobs -&gt; 병렬로 실행됨</li>
</ul>
<h2 id="기본-stages-키워드">기본 stages 키워드</h2>
<p>5개의 기본 stages가 존재한다. </p>
<ol>
<li><code>.pre</code> (항상 맨 처음 실행)</li>
<li><code>build</code></li>
<li><code>test</code></li>
<li><code>deploy</code></li>
<li><code>.post</code> (항상 맨 마지막 실행)</li>
</ol>
<p>stages를 명시하면 기본 stages는 무시된다.</p>
<h2 id="stages-사용하기">stages 사용하기</h2>
<pre><code class="language-yaml">stages:
    - build
    - test
    - deploy

job1:
    stage: test
    script:
        - echo script1

job2:
    stage: test
    script:
        - echo script2

job3:
    stage: deploy
    script:
        - echo script3</code></pre>
<p>stages에 build, test, deploy 3개가 작성돼있다. 기본 stages 는 비활성화되고, 명시된 stages만 설정된다. 즉, 이 파이프라인에서는 3개의 stage를 진행한다고 이해할 수 있다. stages의 진행은 작성된 순서대로, 위에서 아래로 진행된다(build -&gt; test -&gt; deploy).</p>
<p><code>job1</code>과 <code>job2</code>는 test 라는 stage에 속해있음을 알 수 있다. 그러면 테스트 스테이지에서 job1과 job2가 병렬로 실행된다는 부분도 파악할 수 있다.</p>
<p>job3은 job1과 job2가 모두 끝나야지 진행될 것이란 점을 확인할 수 있다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[.gitlab-ci.yml 전역 키워드 (default, variables)]]></title>
            <link>https://velog.io/@regular_jk_kim/.gitlab-ci.yml-%EC%A0%84%EC%97%AD-%ED%82%A4%EC%9B%8C%EB%93%9C-default-variables</link>
            <guid>https://velog.io/@regular_jk_kim/.gitlab-ci.yml-%EC%A0%84%EC%97%AD-%ED%82%A4%EC%9B%8C%EB%93%9C-default-variables</guid>
            <pubDate>Tue, 09 Sep 2025 18:13:23 GMT</pubDate>
            <description><![CDATA[<p>#infra</p>
<h2 id="전역-키워드-global-keywords">전역 키워드 (Global Keywords)</h2>
<p>말 그대로 전역적으로 사용할 수 있는 키워드를 의미한다. 5개가 있다.</p>
<ol>
<li><strong><code>default</code></strong></li>
<li><code>include</code></li>
<li><code>stages</code></li>
<li><strong><code>variables</code></strong></li>
<li><code>workflow</code></li>
</ol>
<p>5개 중에 default, variables 만 알아보자.</p>
<h2 id="default">default</h2>
<ul>
<li>모든 job이 공통적으로 따라야 할 기본 설정을 정의한다.</li>
<li>개별 job에서 override 하면 그 job에는 default가 적용되지 않는다.</li>
</ul>
<pre><code class="language-yml">default:
    image: python:3.0

job name 1:
    script: my script texts

job name 2:
    image: python:2.0
    script: my script texts
</code></pre>
<p>default 로 파이썬의 버전을 3버전을 지정했다.<br><code>job name 1</code>에서는 별다른 image 설정이 없으므로 파이썬 3버전이 사용된다.<br><code>job name 2</code>에서는 image 설정을 따로 지정했으므로 default가 무시된다.</p>
<h2 id="variables">variables</h2>
<ul>
<li>모든 job에서 참조 가능한 전역 변수를 선언한다.</li>
<li>각 job 내부에서 같은 이름으로 변수를 재정의하면 로컬 변수가 우선한다.</li>
<li>선언된 변수는 스크립트에서 ${VAR_NAME} 형태로 사용할 수 있다.</li>
<li>민감한 값은 GitLab UI의 <strong>CI/CD Settings → Variables</strong>에서 관리하는 것이 권장된다.</li>
</ul>
<pre><code class="language-yaml">variables:
    VAR: my-global-var-value

job name 1:
    script:
        echo ${VAR}

job name 2:
    variables:
        VAR: local-var-value
    script:
        echo ${VAR}</code></pre>
<p>전역 변수로 <code>VAR</code>를 선언했다.<br><code>job name 1</code>에서는 전역 변수의 <code>VAR</code>를 사용한다.<br><code>job name 2</code>에서는 로컬 변수를 선언했으므로 전역 변수의 값은 사용되지 않는다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[250907]]></title>
            <link>https://velog.io/@regular_jk_kim/250907</link>
            <guid>https://velog.io/@regular_jk_kim/250907</guid>
            <pubDate>Sun, 07 Sep 2025 07:35:23 GMT</pubDate>
            <description><![CDATA[<p>#회고 </p>
<h2 id="250907-회고-💬">250907 회고 💬</h2>
<p>9월이다! 그리고 덥다. 9월에도 30도라니,,, 미친 날씨다. 출퇴근이 여전히 힘들다. 날이 좀 시원해졌으면 좋겠다. 
원래 락, 메탈 쪽 음악을 좋아한다. 요즘은 Bring Me The Horizon의 노래를 자주 듣는다. 특히 sTraNgeRs 를 많이 듣는다. 왜이리 좋은지 모르겠다. 🤘</p>
<h2 id="keep-👍">Keep 👍</h2>
<h3 id="알고리즘">알고리즘</h3>
<p>알고리즘 문제풀이를 계속하고 있다. SQL 문제만 풀이하다가 오랜만에 DP 문제를 풀어봤다. LCS문제를 풀었다. 풀이하면서 LCS 개념 정리도 했는데, 내용이 궁금하다면 <a href="https://velog.io/@regular_jk_kim/LCS">여기서</a> 확인할 수 있다.</p>
<h3 id="출퇴근-자투리-공부">출퇴근 자투리 공부</h3>
<p>DataBase 공부를 하고있다. 학부 때 분명 들었던 내용의 수업인데,,, 왜 새로운건지,,, 늦었으니 이제라도 공부를 해야한다.</p>
<h3 id="ssafy-프로젝트-학기">SSAFY 프로젝트 학기</h3>
<p>본격적인 특화 프로젝트가 시작됐다. 특화 프로젝트란 싸피에서 진행하는 프로젝트 이름 중 하나다. 2학기에는 3개의 프로젝트를 진행하는데 각 공통, 특화, 자율 프로젝트라고 부른다. 이 중 특화 프로젝트를 본격적으로 시작했다. 깃 레포지토리도 생성하고, 브랜치 전략도 논의하면서 하루가 1초처럼 흘렀다.</p>
<p>프로젝트 완료 작업 리스트</p>
<ul>
<li>백엔드 아키텍처 기획</li>
<li>프로젝트 생성</li>
<li>vitals(프로젝트 이름) 생성</li>
<li>client 서버 생성</li>
<li>traffic 생성기 생성</li>
<li>도커 파일로 이미지 생성하기</li>
<li>fluent bit 사용하여 컨테이너에서 로그 추출하기</li>
</ul>
<h3 id="운동">운동</h3>
<p>매일 헬스장에 나가 운동하려고 노력 중이다. 이번 평일에는 <strong>3</strong>일 성공했다.</p>
<h3 id="독서">독서</h3>
<p>혼자 공부하는 네트워크를 읽고있다.</p>
<h2 id="try-🧚">Try 🧚</h2>
<ul>
<li>카프카 공부하기</li>
<li>혼자 공부하는 네트워크 읽기</li>
</ul>
<h2 id="독서-목록">독서 목록</h2>
<h3 id="서평-완료-목록">서평 완료 목록</h3>
<ul>
<li><a href="https://velog.io/@regular_jk_kim/%ED%98%BC%EC%9E%90-%EA%B3%B5%EB%B6%80%ED%95%98%EB%8A%94-%EC%BB%B4%ED%93%A8%ED%84%B0-%EA%B5%AC%EC%A1%B0-%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%EB%A5%BC-%EC%9D%BD%EA%B3%A0">혼자 공부하는 컴퓨터 구조 + 운영체제</a></li>
<li><a href="https://velog.io/@regular_jk_kim/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%9D%98-%EA%B8%B8-%EB%A9%98%ED%86%A0%EC%97%90%EA%B2%8C-%EB%AC%BB%EB%8B%A4-%EB%A5%BC-%EC%9D%BD%EA%B3%A0-24jpq345">프로그래머의 길, 멘토에게 묻다</a></li>
<li><a href="https://velog.io/@regular_jk_kim/%ED%95%A8%EA%BB%98-%EC%9E%90%EB%9D%BC%EA%B8%B0-%EB%A5%BC-%EC%9D%BD%EA%B3%A0">함께 자라기 애자일로 가는 길</a></li>
<li><a href="https://velog.io/@regular_jk_kim/%EA%B0%9D%EC%B2%B4%EC%A7%80%ED%96%A5%EC%9D%98-%EC%82%AC%EC%8B%A4%EA%B3%BC-%EC%98%A4%ED%95%B4-%EB%A5%BC-%EC%9D%BD%EA%B3%A0">객체지향의 사실과 오해</a></li>
</ul>
<h3 id="서평-예정-목록-읽는-중">서평 예정 목록 (읽는 중)</h3>
<ul>
<li>혼자 공부하는 네트워크 (16%)</li>
</ul>
<h3 id="으악-재미없어-🤪">으악 재미없어,,, 🤪</h3>
<ul>
<li><del>면접을 위한 CS 전공지식 노트</del></li>
<li><del>한 권으로 읽는 컴퓨터 구조와 프로그래밍</del></li>
</ul>
<h3 id="독서-예정-목록">독서 예정 목록</h3>
<ul>
<li>혼자 공부하는 네트워크</li>
<li>오브젝트</li>
<li>HTTP 완벽 가이드</li>
<li>자바/스프링 개발자를 위한 실용주의 프로그래밍</li>
<li>모던 자바 인 액션</li>
<li>자바 성능 튜닝 이야기 </li>
<li>헤드 퍼스트 서블릿</li>
<li>파이브 라인스 오브 코드</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[LCS]]></title>
            <link>https://velog.io/@regular_jk_kim/LCS</link>
            <guid>https://velog.io/@regular_jk_kim/LCS</guid>
            <pubDate>Sun, 07 Sep 2025 07:25:37 GMT</pubDate>
            <description><![CDATA[<p>#알고리즘</p>
<h1 id="lcs">LCS</h1>
<p>LCS(Longest Common Subsequence, 최장 공통 부분 수열)문제는 두 수열이 주어졌을 때, 모두의 부분 수열이 되는 수열 중 가장 긴 것을 찾는 문제이다.</p>
<h2 id="1-기본-개념">1. 기본 개념</h2>
<ul>
<li><p><strong>부분 수열 (Subsequence)</strong><br>원래 순서를 유지하지만, 중간의 몇 문자를 건너뛰어도 된다.<br>예: <code>ABCDEF</code>에서 <code>ACE</code>는 부분 수열이다.</p>
</li>
<li><p><strong>부분 문자열 (Substring)</strong><br>반드시 연속된 구간이어야 한다.<br>예: <code>ABCDEF</code>에서 <code>CDE</code>는 부분 문자열이다.</p>
</li>
</ul>
<p>즉, <strong>부분 문자열은 부분 수열의 특수한 경우</strong>라고 볼 수 있다.</p>
<hr>
<h2 id="2-lcs-longest-common-subsequence">2. LCS (Longest Common Subsequence)</h2>
<p><strong>LCS란?</strong><br>두 문자열이 있을 때, <strong>공통된 부분 수열 중 가장 긴 것</strong>을 찾는 문제다.</p>
<p>예제:</p>
<ul>
<li>문자열 1: <code>ABCBDAB</code>  </li>
<li>문자열 2: <code>BDCABA</code>  </li>
</ul>
<p>가능한 LCS의 예시는 다음과 같다:</p>
<ul>
<li><code>BCBA</code> (길이 4)  </li>
<li><code>BDAB</code> (길이 4)  </li>
</ul>
<blockquote>
<p>LCS는 <strong>유일하지 않을 수 있다.</strong><br>그래서 보통은 길이만 구하는 것이 기본 문제이고, 실제 수열을 복원하는 것은 추가 과정이다.</p>
</blockquote>
<hr>
<h2 id="3-왜-단순-비교로는-어려운가">3. 왜 단순 비교로는 어려운가?</h2>
<p>문자열 길이가 <code>n</code>일 때, 각 문자를 <strong>고른다 / 안 고른다</strong> 두 가지 선택지가 있다.<br>→ 부분 수열의 개수는 $2^{n}$.</p>
<p>두 문자열 길이가 <code>n</code>, <code>m</code>이라면 가능한 모든 부분 수열 조합은 대략<br>$$
2^n \times 2^m = 2^{n+m}
$$<br>가지가 된다.</p>
<p>즉, <strong>단순 비교로는 지수 시간이 걸리므로</strong> 비효율적이다.<br>따라서 <strong>동적 계획법(DP)</strong>으로 시간 복잡도를 $O(nm)$까지 줄인다.</p>
<hr>
<h2 id="4-lcs-dp-아이디어">4. LCS DP 아이디어</h2>
<p>핵심은 <strong>작은 문제(접두사)로 분해하기</strong>이다.</p>
<p>보통은 문자열 <code>X</code>, <code>Y</code>에 대해 다음과 같이 정의한다:</p>
<blockquote>
<p><strong>LCS(i, j)</strong> = 문자열 <code>X</code>의 앞에서 <code>i</code>개, 문자열 <code>Y</code>의 앞에서 <code>j</code>개를 고려했을 때 최장 공통 부분 수열의 길이</p>
</blockquote>
<hr>
<h2 id="5-점화식-세우기">5. 점화식 세우기</h2>
<ol>
<li><p><strong>마지막 문자가 같을 때</strong>  </p>
<ul>
<li>공통 부분 수열에 포함될 수 있음<br>$$
LCS(i, j) = LCS(i-1, j-1) + 1
$$</li>
</ul>
</li>
<li><p><strong>마지막 문자가 다를 때</strong>  </p>
<ul>
<li>두 경우 중 더 긴 것을 선택<br>$$
LCS(i, j) = \max(LCS(i-1, j), ; LCS(i, j-1))
$$</li>
</ul>
</li>
</ol>
<hr>
<h2 id="6-기저-조건">6. 기저 조건</h2>
<ul>
<li>한쪽 문자열이 공집합일 때 LCS 길이는 0이다.<br>$$
LCS(0, j) = 0 \quad,\quad LCS(i, 0) = 0
$$</li>
</ul>
<hr>
<h2 id="7-최종-정리-점화식">7. 최종 정리 (점화식)</h2>
<p>$$
LCS(i, j) =
\begin{cases} 
0 &amp; \text{if } i=0 \text{ or } j=0 \
LCS(i-1, j-1) + 1 &amp; \text{if } X[i] = Y[j] \
\max(LCS(i-1, j), LCS(i, j-1)) &amp; \text{if } X[i] \neq Y[j]
\end{cases}
$$</p>
<hr>
<h2 id="8-요약">8. 요약</h2>
<ul>
<li><strong>부분 수열</strong>: 순서만 유지, 연속성 불필요  </li>
<li><strong>부분 문자열</strong>: 반드시 연속  </li>
<li><strong>LCS 문제</strong>: 두 문자열의 공통된 부분 수열 중 최장 길이  </li>
<li><strong>해결 방법</strong>: DP로 (O(nm)) 시간에 해결 가능  </li>
<li><strong>실제 수열 복원</strong>: DP 테이블을 역추적(backtracking)해서 구한다</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[250831]]></title>
            <link>https://velog.io/@regular_jk_kim/250831</link>
            <guid>https://velog.io/@regular_jk_kim/250831</guid>
            <pubDate>Sun, 31 Aug 2025 08:35:27 GMT</pubDate>
            <description><![CDATA[<p>#회고 </p>
<h2 id="250831-회고-💬">250831 회고 💬</h2>
<p>헬스장을 등록했다. 오랜만에 운동 시작이다. 이번에 등록한 헬스장은 체인점이다. 그래서 등록하지 않은 지점이라도 이용할 수 있다고 한다. 엄청나다! 여름 다 지났지만(정말?) 운동 시작이다. 이번에도 열심히 해보자. 🏋️‍♀️</p>
<p>0829일, 그러니까 이번 주 금요일에 팀원들과 field trip이 있었다. 싸피에 출근하지 않고 팀원들과 다른 곳에서 모여서 점심 먹고, 아이디어 회의하고 등등 생산적인 시간을 보냈다.</p>
<h2 id="keep-👍">Keep 👍</h2>
<h3 id="알고리즘">알고리즘</h3>
<p>알고리즘 문제풀이를 계속하고 있다.</p>
<h3 id="출퇴근-자투리-공부">출퇴근 자투리 공부</h3>
<p>TDD 인강을 듣고있다.</p>
<h3 id="ssafy-프로젝트-학기">SSAFY 프로젝트 학기</h3>
<p>SSAFY 2학기에는 3개의 프로젝트를 진행한다. 공통, 특화, 자유 프로젝트 3가지이다. 그 중 공통 프로젝트를 완료했다. 공통 프로젝트 내용이 궁금하다면 <a href="https://velog.io/@regular_jk_kim/250822">여기서</a> 확인할 수 있다.</p>
<p>그리고 이제 특화 프로젝트를 시작했다. 0825일 그러니까 이번 주 월요일에 팀원들과 공식적으로 만나게 되었다. 아직 기획도, 기술 스택도, 계획도 아무 것도 정해진게 없지만 모두들 화이팅이다!</p>
<p>사실 프로젝트 시작 첫 주에는 프로젝트를 시작하지 않는다. 뭔 소리냐고? 말 그대로 프로젝트를 진행할 시간이 아니다. 다른 수업을 들어야 한다. 그래서 팀원들과 친해질겸 이런저런 담소를 나누면서 개인 정비하는 한 주를 보냈다.</p>
<p>싸피 공부하러 와서 놀기만 할 수는 없다. 다들 할일도 많고 들을 수업도 많았지만 그 짧은 시간이라도 서로 모아서 프로젝트 기획 회의를 진행했다. &lt;빅데이터 분산&gt;을 주제로 진행해야 한다. 실시간 요청 정보를 로그로 남기고, 이 로그들을 빅데이터라고 가정하여 진행할 계획이다. </p>
<ul>
<li>트래픽 생성 서버</li>
<li>로그 생성 서버</li>
<li>이벤트 발행</li>
<li>데이터 분석(스파크)</li>
<li>db 저장</li>
<li>소켓 통신 </li>
</ul>
<p>정도의 기술 스택으로 프로젝트가 진행되지 않을까 예상이 된다.</p>
<h3 id="개인-공부">개인 공부</h3>
<p>헥사고날 아키텍쳐 공부를 계속 하고있다. 흥미롭게도 CQRS 패턴도 같이 공부했다. 이제껏 그냥 서비스 레이어에서만 분리하면 된다고 생각했는데(물론 이렇게 해도 된다!) 그런 단순한 내용이 아니였다. 고수들의 비법은 역시 나같은 범부와는 태가 다르다. 잘 메모해두고 내 코드인양 잘 기억해둬야겠다.</p>
<h3 id="운동">운동</h3>
<p>오랜만에 운동을 다시 시작했다. 매일 아침 일찍 일어나 세안만 하고 헬스장으로 출근했다. 오랜만에 운동을 하니 온 몸에서 비명이 들린다. 몸도 잘 안 움직인다. 며칠만 지나면 괜찮아지겠지,,, 😢</p>
<h3 id="독서">독서</h3>
<p>혼자 공부하는 네트워크를 읽고있다.</p>
<h2 id="try-🧚">Try 🧚</h2>
<ul>
<li>카프카 공부하기</li>
<li>혼자 공부하는 네트워크 읽기</li>
</ul>
<h2 id="독서-목록">독서 목록</h2>
<h3 id="서평-완료-목록">서평 완료 목록</h3>
<ul>
<li><a href="https://velog.io/@regular_jk_kim/%ED%98%BC%EC%9E%90-%EA%B3%B5%EB%B6%80%ED%95%98%EB%8A%94-%EC%BB%B4%ED%93%A8%ED%84%B0-%EA%B5%AC%EC%A1%B0-%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%EB%A5%BC-%EC%9D%BD%EA%B3%A0">혼자 공부하는 컴퓨터 구조 + 운영체제</a></li>
<li><a href="https://velog.io/@regular_jk_kim/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%9D%98-%EA%B8%B8-%EB%A9%98%ED%86%A0%EC%97%90%EA%B2%8C-%EB%AC%BB%EB%8B%A4-%EB%A5%BC-%EC%9D%BD%EA%B3%A0-24jpq345">프로그래머의 길, 멘토에게 묻다</a></li>
<li><a href="https://velog.io/@regular_jk_kim/%ED%95%A8%EA%BB%98-%EC%9E%90%EB%9D%BC%EA%B8%B0-%EB%A5%BC-%EC%9D%BD%EA%B3%A0">함께 자라기 애자일로 가는 길</a></li>
<li><a href="https://velog.io/@regular_jk_kim/%EA%B0%9D%EC%B2%B4%EC%A7%80%ED%96%A5%EC%9D%98-%EC%82%AC%EC%8B%A4%EA%B3%BC-%EC%98%A4%ED%95%B4-%EB%A5%BC-%EC%9D%BD%EA%B3%A0">객체지향의 사실과 오해</a></li>
</ul>
<h3 id="서평-예정-목록-읽는-중">서평 예정 목록 (읽는 중)</h3>
<ul>
<li>혼자 공부하는 네트워크 (16%)</li>
</ul>
<h3 id="으악-재미없어-🤪">으악 재미없어,,, 🤪</h3>
<ul>
<li><del>면접을 위한 CS 전공지식 노트</del></li>
<li><del>한 권으로 읽는 컴퓨터 구조와 프로그래밍</del></li>
</ul>
<h3 id="독서-예정-목록">독서 예정 목록</h3>
<ul>
<li>혼자 공부하는 네트워크</li>
<li>오브젝트</li>
<li>HTTP 완벽 가이드</li>
<li>자바/스프링 개발자를 위한 실용주의 프로그래밍</li>
<li>모던 자바 인 액션</li>
<li>자바 성능 튜닝 이야기 </li>
<li>헤드 퍼스트 서블릿</li>
<li>파이브 라인스 오브 코드</li>
</ul>
<h2 id="extras">Extras</h2>
<p>카프카 공부를 짧게 했다. 해당 내용은 <a href="https://velog.io/@regular_jk_kim/%EC%B9%B4%ED%94%84%EC%B9%B4-%EA%B8%B0%EB%B3%B8-%EB%AA%85%EB%A0%B9%EC%96%B4">여기서</a> 확인할 수 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[카프카 기본 명령어]]></title>
            <link>https://velog.io/@regular_jk_kim/%EC%B9%B4%ED%94%84%EC%B9%B4-%EA%B8%B0%EB%B3%B8-%EB%AA%85%EB%A0%B9%EC%96%B4</link>
            <guid>https://velog.io/@regular_jk_kim/%EC%B9%B4%ED%94%84%EC%B9%B4-%EA%B8%B0%EB%B3%B8-%EB%AA%85%EB%A0%B9%EC%96%B4</guid>
            <pubDate>Wed, 27 Aug 2025 13:08:49 GMT</pubDate>
            <description><![CDATA[<p>#카프카 </p>
<h1 id="토픽-생성-조회-삭제">토픽 생성, 조회, 삭제</h1>
<h2 id="토픽-생성하기">토픽 생성하기</h2>
<pre><code class="language-sh"># 카프카 디렉터리 안에서 명령어를 실행한다
cd kafka_xxx

# 토픽 생성
# bin/kafka-topics.sh --bootstrap-server &lt;kakfa 주소&gt; --create --topic &lt;토픽명&gt;
bin/kafka-topics.sh --bootstrap-server localhost:9092 --create --topic email.send</code></pre>
<h2 id="토픽-조회하기">토픽 조회하기</h2>
<pre><code class="language-sh"># 토픽 전체 조회
# bin/kafka-topics.sh --bootstrap-server &lt;kakfa 주소&gt; --list 
bin/kafka-topics.sh --bootstrap-server localhost:9092 --list

# 특정 토픽 세부 정보 조회 
# bin/kafka-topics.sh --bootstrap-server &lt;kakfa 주소&gt; --describe --topic &lt;토픽명&gt; 
bin/kafka-topics.sh --bootstrap-server localhost:9092 --describe --topic email.send</code></pre>
<h2 id="토픽-삭제하기">토픽 삭제하기</h2>
<pre><code class="language-sh"># 토픽 삭제 
# bin/kafka-topics.sh --bootstrap-server &lt;kafka 주소&gt; --delete --topic &lt;토픽명&gt; 
bin/kafka-topics.sh --bootstrap-server localhost:9092 --delete --topic email.send 
# 잘 삭제됐는 지 확인하기 
bin/kafka-topics.sh --bootstrap-server localhost:9092 --list</code></pre>
<hr>
<h1 id="메시지-삽입-조회">메시지 삽입, 조회</h1>
<h2 id="특정-토픽에-메시지-넣기">특정 토픽에 메시지 넣기</h2>
<p>메시지는 key-value 형식으로, 혹은 value만 넣을 수 있다. key를 생략하고 value만 넣어보자!</p>
<pre><code class="language-sh"># email.send 라는 토픽에 메시지 넣기
bin/kafka-console-producer.sh --bootstrap-server localhost:9092 --topic email.send

# 위 명령어 입력 후 넣을 메시지 내용 입력하고 enter 누르기
hello1
hello2
hello3

# 입력을 완료했으면 ctr+c 로 입력 상태 종료</code></pre>
<h2 id="특정-토픽에서-메시지-조회하기">특정 토픽에서 메시지 조회하기</h2>
<p>카프카는 메시지를 읽고 제거하는 방식이 아니다. 저장된 메시지를 읽기만 하고 제거하지 않는 방식으로 작동한다. 따라서 같은 메시지를 여러 번 읽을 수 있다.</p>
<pre><code class="language-sh"># email.send 토픽에 있는 메시지 꺼내기
bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic email.send --from-beginning</code></pre>
<p><code>--from-beginning</code> : 토픽에 저장된 가장 처음 메시지부터 출력</p>
<p>만약 다른 mq 프로그램이었다면 위 명령어를 실행했을 때 메시지를 소비하여 큐가 비워졌을 것이다. 하지만 카프카는 메시지를 소비하더라도 제거하지 않는다. 따라서 한 번 더 명령어를 입력해도 저장된 메시지가 다시 출력된다.</p>
<hr>
<h1 id="consumer-group-offset">Consumer Group, Offset</h1>
<p>시작전에</p>
<ul>
<li>컨슈머 : 카프카의 메시지를 처리하는 주체</li>
<li>컨슈머 그룹 : 1개 이상의 컨슈머를 하나의 그룹으로 묶은 단위</li>
<li>오프셋 : 메시지의 순서를 나타내는 고유 번호 (0 부터 시작)</li>
</ul>
<p><img src="https://velog.velcdn.com/images/regular_jk_kim/post/36dcf631-a47f-47a3-aab1-15f120be0379/image.png" alt=""></p>
<ul>
<li>토픽에 저장된 메시지는 순서를 나타내는 고유 번호인 오프셋을 가진다.</li>
<li>오프셋 번호는 인덱스처럼 0부터 시작한다.</li>
<li>컨슈머 그룹은 1개 이상의 컨슈머를 가질 수 있다.</li>
<li>컨슈머 그룹은 어디까지 메시지를 읽었는지에 대한 정보(<code>current-offset</code>)를 알고 있다.</li>
<li>current-offset : 다음에 읽을 메시지의 오프셋 번호를 의미한다.</li>
</ul>
<h2 id="컨슈머-그룹을-지정해서-메시지-읽기">컨슈머 그룹을 지정해서 메시지 읽기</h2>
<pre><code class="language-sh"># 컨슈머 그룹을 이용해 메시지 조회하기
bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic email.send --from-beginning --group email-send-group</code></pre>
<ul>
<li><code>--group email-send-group &lt;group-name&gt;</code> : 기존에 <code>&lt;group-name&gt;</code>이라는 컨슈머 그룹이 없었다면 <code>&lt;group-name&gt;</code> 에 해당하는 컨슈머 그룹을 생성한다. 그리고 이 컨슈머 그룹으로 메시지를 읽는다. 이때 몇번째 메시지까지 읽었는지를 오프셋 번호로 저장한다.</li>
<li><code>--from-beginning</code> : (<code>--group</code> 옵션과 함께 사용했을 경우에만) 컨슈머 그룹의 오프셋 기록이 없으면 첫 메시지부터 읽고, 만약 오프셋 기록이 있으면 그 이후 오프셋부터 메시지를 읽는다. </li>
</ul>
<h2 id="컨슈머-그룹-확인하기">컨슈머 그룹 확인하기</h2>
<pre><code class="language-sh"># 컨슈머 그룹 전체 조회
bin/kafka-consumer-groups.sh --bootstrap-server localhost:9092 --list</code></pre>
<h2 id="특정-컨슈머-그룹-세부-조회하기">특정 컨슈머 그룹 세부 조회하기</h2>
<pre><code class="language-sh"># 컨슈머 그룹 세부 정보 조회하기
bin/kafka-consumer-groups.sh --bootstrap-server localhost:9092 --group email-send-group --describe</code></pre>
<p>위 명령어를 입력하면 해당하는 컨슈머 그룹의 세부 정보가 출력된다. 이때 <code>current-offset</code> 항목에서 몇번째 메시지까지 읽었는지 확인이 가능하다.</p>
]]></description>
        </item>
    </channel>
</rss>