<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Fermentation.log</title>
        <link>https://velog.io/</link>
        <description>Do Infinity And Beyond</description>
        <lastBuildDate>Fri, 21 Jan 2022 05:38:06 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>Fermentation.log</title>
            <url>https://images.velog.io/images/cid-yoon/profile/b36ea0c6-4933-47bc-9601-8e1f82364f5f/social.jpeg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. Fermentation.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/cid-yoon" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[분리 인터페이스 패턴]]></title>
            <link>https://velog.io/@cid-yoon/%EB%B6%84%EB%A6%AC-%EC%9D%B8%ED%84%B0%ED%8E%98%EC%9D%B4%EC%8A%A4-%ED%8C%A8%ED%84%B4</link>
            <guid>https://velog.io/@cid-yoon/%EB%B6%84%EB%A6%AC-%EC%9D%B8%ED%84%B0%ED%8E%98%EC%9D%B4%EC%8A%A4-%ED%8C%A8%ED%84%B4</guid>
            <pubDate>Fri, 21 Jan 2022 05:38:06 GMT</pubDate>
            <description><![CDATA[<p>다음 책 내용을 정리한 항목입니다
<a href="http://www.kyobobook.co.kr/product/detailViewKor.laf?mallGb=KOR&amp;ejkGb=KOR&amp;barcode=9791158390174">엔터프라이즈 애플리케이션 아키텍처 패턴</a></p>
<blockquote>
<p>구현과 분리된 별도의 패키지에 인터페이스를 정의한다</p>
</blockquote>
<h3 id="필요-이유">필요 이유</h3>
<p>시스템을 구성하는 부분간의 결합을 줄이면 시스템의 설계를 개선할 수 있다
이를 위해서 좋은 방법은 클래스를 패키지로 그룹화 하고 이들간의 의존성을 제어하는 것이다</p>
<p>주로 사용했던 언어(C#)와 현재 사용중인 언어(java)는 이를 지원해주고 있다
온전히 같지는 않지만 비슷한 행태이다(논리적 분할이냐 물리적 분할이냐 정도?)
<a href="https://pediaa.com/what-is-the-difference-between-namespace-and-package/">what-is-the-difference-between-namespace-and-package</a></p>
<p>그러나 일반적인 의존성 구조를 위반하고 메서드를 호출해야 하는 경우가 종종 존재한다</p>
<pre><code>예시)
프레임워크 패키지에 넣은 범용 추상 코드에서 특정한 애플리케이션 코드를 호출해야 하는 경우
한 계층의 코드에서 볼 수 없어야 하는 다른 계층의 코드를 호출해야 하는 경우
- 예시) 도메인 코드에서 데이터 매퍼를 호출하는
다른 개발 그룹에서 개발한 함수를 호출해야 하지만 해당 API에 대한 의존성을 원하지 않는 경우</code></pre><p>이런 경우 하나의 방법으로 사용될 수 있다. 
인터페이스에 대한 의존성이 필요한 클라이언트는 해당 방식을 통해 <strong>구현을 전혀 의식하지 않고</strong> 작업을 수행할 수 있다. 분리 인터페이스는 게이트웨이를 연결할 수 있는 좋은 위치다
(개인적으로는 인터페이스의 위치를 이동하는 경우에도 종종 사용한다)</p>
<h3 id="경고">경고</h3>
<p>적당히(트레이드 오프)를 고민 하자
분리를 함으로 발생할 수 있는 <strong>직접적인 의존성 관리</strong>는 복잡도를 높일 수 있다
의존성을 제거하려는 경우 또는 여러 독립적 구현을 사용하려는 경우에만 분리 인터페이스를 사용하는 것이 바람직하다.</p>
<h3 id="작동-원리">작동 원리</h3>
<blockquote>
<p>구현은 해당 인터페이스에 의존하지만 그 반대는 해당되지 않는다</p>
</blockquote>
<p>인터페이스와 구현을 <strong>별도의 패키지</strong>에 넣고 구현 패키지가 인터페이스 패키지에 대한 의존성을 갖게 한다
다른 패키지는 구현 패키지에 의존하지 않고 인터페이스 패키지에 의존할 수 있다.</p>
<p>인터페이스의 구현이 아예 없는 경우는 런타임에 문제가 발생하겠지만 해당 문제는 컴파일 시 둘을 연결하는 별도의 패키지를 사용하거나 구성시 플러그인을 통해서 해결할 수 있다</p>
<p>해당 개념은 인터페이스를 정의할 책임이 클라이언트 패키지(사용하는)에 있다고 생각하면 이해하기 쉽다
근본적으로 클라이언트 패키지는 자신이 정의하는 인터페이스를 구현하는 다른 모든 패키지와 함께 작업한다는 것을 나타낸다</p>
<p>만약 클라이언트 패키지가 여러개인 경우에는 다른 인터페이스를 사용하는 것이 좋다
또한 인터페이스를 정의하는 역할이 클라이언트 패키지 개발자의 책임이 아니라는것을 나타내는 경우에도 이 방법이 좋다</p>
<ul>
<li>서드 파티 라이브러리 또는 API의 직접 연관성을 제거하고 싶은 경우</li>
</ul>
<p>분리 인터페이스는 구현을 인스턴스화 하기가 약간 불편할 수 있으며 일반적으로 구현 클래스의 정보(implemet)가 필요하다. 일반적인 방법은 별도의 팩토리 객체와 팩토리에 대한 분리 인터페이스를 사용하는 것이다(또 늘어난다..)</p>
<p>굳이 이런 플러그인을 사용하고 싶지 않다면 인터페이스와 구현을 모두 인식하는 다른 패키지를 사용해 애플리케이션 시작시 해당 객체를 인스턴스화 할 수도 있다</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Log4Shell문제와 Spring Boot]]></title>
            <link>https://velog.io/@cid-yoon/Log4Shell%EB%AC%B8%EC%A0%9C%EC%99%80-Spring-Boot</link>
            <guid>https://velog.io/@cid-yoon/Log4Shell%EB%AC%B8%EC%A0%9C%EC%99%80-Spring-Boot</guid>
            <pubDate>Mon, 13 Dec 2021 02:39:46 GMT</pubDate>
            <description><![CDATA[<p>주말동안 Log4Shell 문제로 여러 커뮤니티에서 이슈가 되었고 이를 기록하는 차원에서 기록합니다</p>
<h1 id="문제-발생">문제 발생</h1>
<p>Log4Shell 이슈는 이미 너무 많은 곳에서 이야기 해 주고 있으니 아래 링크를 참고
<a href="https://blog.alyac.co.kr/4341">Apache Log4j 2 원격코드 실행(RCE) 취약점 주의! (CVE-2021-44228)</a></p>
<p>해당 이슈에 영향받는 log4j 버전</p>
<pre><code>- 2.0 ~ 2.14.1 (2.15.0 미만 버전)
 + org.apache.logging.log4j:log4j-api &lt; 2.15.0
 + org.apache.logging.log4j:log4j-core &lt; 2.15.0</code></pre><h1 id="결론">결론</h1>
<p>결과적으로 스프링 부트를 사용하는 경우 <strong>기본 로그 서비스 사용 + 사용자 입력을 통한 log4j-core를 사용하지 않는 경우라면 별도의 조치는 필요 없음</strong> 이라고 하며 spring.io에 올라온 글을 참조하시면 됩니다
<a href="https://spring.io/blog/2021/12/10/log4j2-vulnerability-and-spring-boot">log4j2-vulnerability-and-spring-boot</a></p>
<p>별다른 조치가 필요 없지만 강제 버전업이 필요하다면 아래와 같이 진행하면 됩니다</p>
<pre><code>gradle
// log4shell 문제 예방용 강제 업데이트
// https://spring.io/blog/2021/12/10/log4j2-vulnerability-and-spring-boot
ext[&#39;log4j2.version&#39;] = &#39;2.15.0&#39;</code></pre><p><img src="https://images.velog.io/images/cid-yoon/post/909a7f67-0f68-487a-b0e7-083402f767af/image.png" alt=""></p>
<h1 id="작업-진행-과정-정리">작업 진행 과정 정리</h1>
<h2 id="현재-상황">현재 상황</h2>
<p>현재 개발중인 프로젝트는 스프링 부트를 사용하고 있으며 기본 로그 시스템(spring-boot-starter-logging)을 사용하고 있습니다(spring boot 2.2.x)</p>
<p>간략하게 스프링 부트는 slf4j어댑터를 통해 로그를 기록하고 해당 인터페이스의 구현체로 logback을 사용
<a href="http://www.slf4j.org/">SLF4J</a>
<img src="https://images.velog.io/images/cid-yoon/post/cb4e3850-6802-4d00-9b42-369a64cedc42/image.png" alt="스프링 부트 종속성"></p>
<h2 id="종속성-그래프-조회">종속성 그래프 조회</h2>
<p>별도의 변경(구현체 교체)이 없었기에 연관 문제 없을것이라 생각했지만 종속성 그래프에서 log4j가 발견되었고 이는 해당 취약점 공격을 받을 수 있는 버전으로 확인
<img src="https://images.velog.io/images/cid-yoon/post/89630ded-e07a-4b78-a225-2ff8a65ef238/image.png" alt=""></p>
<pre><code>영향받는 버전
- 2.0 ~ 2.14.1 (2.15.0 미만 버전)
 + org.apache.logging.log4j:log4j-api &lt; 2.15.0
 + org.apache.logging.log4j:log4j-core &lt; 2.15.0</code></pre><p>버전업을 해야 하나? 고민했지만 검색을 통해 스프링 공홈에서 다음과 같이 어떻게 대응할지 가르쳐 주고 있습니다</p>
<pre><code>Spring Boot users are only affected by this vulnerability if they have switched the default logging system to Log4J2. The log4j-to-slf4j and log4j-api jars that we include in spring-boot-starter-logging cannot be exploited on their own. Only applications using log4j-core and including user input in log messages are vulnerable.
</code></pre><h2 id="정리--조치">정리 &amp; 조치</h2>
<p><strong>기본 로그 서비스 사용 + 사용자 입력을 통해 log4j-core를 사용하지 않는 경우라면 별도의 조치는 필요 없음</strong> </p>
<p><a href="https://spring.io/blog/2021/12/10/log4j2-vulnerability-and-spring-boot">log4j2-vulnerability-and-spring-boot</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[리펙토링]]></title>
            <link>https://velog.io/@cid-yoon/%EB%A6%AC%ED%8E%99%ED%86%A0%EB%A7%81</link>
            <guid>https://velog.io/@cid-yoon/%EB%A6%AC%ED%8E%99%ED%86%A0%EB%A7%81</guid>
            <pubDate>Sun, 21 Nov 2021 14:48:27 GMT</pubDate>
            <description><![CDATA[<h1 id="chapter-01">Chapter 01</h1>
<p>간단한 수정 -&gt; 테스트를 리듬처럼 반복하자</p>
<blockquote>
<p>프로그램에 기능을 추가해야 하는데 코드 구조가 조잡해서 그 기능을 추가하기 힘들다면, 우선 리펙토링을 실시해서 기능을 추가하기 쉽게 만든 후 그 기능을 추가하자.</p>
</blockquote>
<p>적절한 테스트 코드를 작성하는 것은 리펙토링의 기본이다</p>
<blockquote>
<p>명확성을 높이기 위한 이름 수정에 인색하게 굴지 말자. 용도가 확실히 드러나게 코드를 작서하는 것은 아주 중요하다</p>
</blockquote>
<p>좋은 코드는 그것이 무슨 기능을 하는지 분명히 드러나야 하는데, 코드의 기능을 분명히 드러내는 열쇠가 바로 직관적인 변수명이다. </p>
<blockquote>
<p>임시 변수를 메서드 호출로 전환(Replace Temp with Query)</p>
</blockquote>
<p>임시 변수가 많으면 불필요하게 많은 매개변수를 전달하게 도는 문제가 흔히 생긴다
임시변수는 특히 긴 메서드 안에서 알게 모르게 늘어난다. </p>
<p>루프 및 코드가 길어진다고해서 지레 겁먹을 필요는 없다
최적화 단계가 성능 해결의 적기이며 효과적인 최적화를 위한 더 많은 선택의 여지가 있다</p>
<blockquote>
<p>타 객체의 속성을 비교 인자로 사용하는 것은 나쁜 방법이다. 자신의 데이터로 바꾸자</p>
</blockquote>
<p>객체의 비교값을 변경해도 그로인해 미치는 영향을 최소화 하고자 자신의 클래스 안으로 옮겨진 것</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[오브젝트]]></title>
            <link>https://velog.io/@cid-yoon/%EA%B0%9D%EC%B2%B4-%EC%A7%80%ED%96%A5</link>
            <guid>https://velog.io/@cid-yoon/%EA%B0%9D%EC%B2%B4-%EC%A7%80%ED%96%A5</guid>
            <pubDate>Thu, 07 Oct 2021 13:26:25 GMT</pubDate>
            <description><![CDATA[<h3 id="캡슐화">캡슐화</h3>
<blockquote>
<p>Tell, Dont&#39; Ask</p>
</blockquote>
<p>데이터와 행동을 하나의 객체로 엮어 시스템의 기본 동작들을 연결하여 동작하게 만드는 것
정보의 은닉성을 유지하며 객체를 설계하는 것이 견고한 시스템을 구성하는데 도움이 된다</p>
<p><img src="https://images.velog.io/images/cid-yoon/post/fa61e609-25e9-4805-a37a-c0e3e6f5758d/image.png" alt="Tell Don&#39;t Ask">
<a href="https://martinfowler.com/bliki/TellDontAsk.html">출처 : MartinFlwler Tell Don&#39;t Ask</a></p>
<p>즉 Equeal(x) 보단 message로 불리는 형태를 지향
하지만 원칙이 아닌 법칙 끝까지 읽어보면 다음과 같이 이야기 한다</p>
<pre><code>For me, tell-don&#39;t-ask is a stepping stone towards co-locating behavior and data, 
but I don&#39;t find it a point worth highlighting.</code></pre><p><strong>오브젝트 6장 메시지와 인터페이스</strong></p>
<blockquote>
<p>디미터 법칙은 객체의 내부 구조를 묻는 메시지가 아니라 
수신자에게 무언가를 시키는 메시지가 더 좋은 메시지라고 속삭인다.</p>
</blockquote>
<pre><code>객체의 내부 구조를 묻지 말고, 무언가를 시켜라.
이처럼 협력하는 객체의 내부 구조에 대한 결합으로 인해 발생하는 설계 문제를 해결하기 위해 제안된 원칙이 바로 디미터 법칙(Law of Demeter)이다. 

디미터 법칙은 객체가 자기 자신을 책임지는 자율적인 존재여야 한다는 사실을 강조한다. 
정보를 처리하는 데 필요한 책임을 정보를 알고 있는 객체에게 할당하기 때문에 응집도가 높은 객체가 만들어진다.

하지만 무비판적으로 디미터 법칙을 수용하면 퍼블릭 인터페이스 관점에서 객체의 응집도가 낮아질 수도 있다. 
자세한 내용은 이번 장에 포함된 &quot;원칙의 함정&quot; 절을 읽어보기 바란다.

디미터 법칙은 객체의 내부 구조를 묻는 메시지가 아니라 수신자에게 무언가를 시키는 메시지가 더 좋은 메시지라고 속삭인다.
</code></pre><blockquote>
<p>가볍게 속삭여 보자.</p>
</blockquote>
<p>원칙은 아니다. 트레이드 오프가 필요하면 하자
물어보자. 과연 이것이 객체의 책임인가?</p>
<p>잘 만들어진(단단한) 클래스 그 다음은 메시지를 고민해보자</p>
<h3 id="애플리케이션은-클래스로-구성되지만-메세지를-통해-정의된다">애플리케이션은 클래스로 구성되지만 메세지를 통해 정의된다</h3>
<p>협력과 메시지의 관계에 대해 항상 기억하자.
결국 클래스를 표현하는 것은 메세지, 그중에서도 <strong>퍼블릭 인터페이스</strong>를 고민하자
객체가 의사 소통을 위해 외부에 공개하는 메시지 집합을 퍼블릭 인터페이스라고 한다</p>
<ul>
<li>메시지 : 객체들이 협력하기 위한 의사 소통 수단</li>
<li>메세지는 오퍼레이션 명(operation)과 인자(arg)로 구성된다</li>
<li>이를 누군가에게 전송하려 할때 수신자가 필요하다.
<del>* 우린 모두 <strong>능동적인</strong> 생명체</del><blockquote>
<p>condition.isSatisfiedBy(Arg)
수신자(who).연산자(operation).인자(arg)</p>
</blockquote>
</li>
</ul>
<p>그렇다면 이런 객체 지향은 왜 필요한 것일까? 결국 인지과부하를 방지하기 위함이다</p>
<p><strong>오브젝트 7장 객체 분해</strong></p>
<pre><code>단기 기억과 장기기억
문제해결에 필요한 요소의 수가 단기 기억의 용량을 초과하는 순간 문제 해결 능력이 급격히 떨어지는것

인지 과부하(cognitive overload) 발생
-&gt; 단기기억안에 보관할 정보의 양을 조절하기위해

불필요한 정보를 제거, 현재 문제 해결에 필요한 핵심 정보만 남기는 작업(추상화)

큰 문제를 한번에 해결 가능한 작은 단위로 나누는 작업 분해(decomposition)
추상화를 더 큰 규모의 추상화로 압축시킴으로써 단기 기억의 한계를 초월할 수 있음.

복잡성의 문제를 추상화와 분해로 해결 </code></pre><blockquote>
<p>내가 알아야 할 정보의 양을 줄여주는 것 만으로도 머릿속의 저장공간을 좀더 잘 쓸 수 있다</p>
</blockquote>
<p>결국은 머릿속의 복잡도를 줄이기 위한 역할인데 때때로 나자신도 모르는 코드가 나오기도 한다
<del>망치를 쥐어주면 못질을 하려 하지</del></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[K8S 인프라 구성]]></title>
            <link>https://velog.io/@cid-yoon/K8S</link>
            <guid>https://velog.io/@cid-yoon/K8S</guid>
            <pubDate>Tue, 22 Jun 2021 15:15:50 GMT</pubDate>
            <description><![CDATA[<h1 id="목적">목적</h1>
<p>K8S 학습을 위한 인프라 구성</p>
<p>내가 필요한 것은 매니지드 환경에서 동작 가능한 서비스 운용이다.
k3s를 통해 일부 테스 해본 지식은 있음
인프라까지 구성할 필요 있을까? 깊게 알 필요는 없지만 큰 흐름을 학습하기 위해 실습을 진행한다</p>
<p>참고자료 : 컨테이너 인프라 환경 구축을 위한 쿠버네티스/도커</p>
<h2 id="vagrant-설정">vagrant 설정</h2>
<p>리소스 사용을 위한 vagrant 구성</p>
<pre><code class="language-sh">brew tap hashicorp/tap
brew install vagrant</code></pre>
<p>예제로 제공되는 vagrant 파일 다운로드하여 vagrant 동작
<code>https://app.vagrantup.com/sysnet4admin/boxes/CentOS-k8s</code></p>
<p><img src="https://images.velog.io/images/cid-yoon/post/308b8453-fd3e-4a88-acd3-38f1cbf5ce42/image.png" alt=""></p>
<h3 id="vagrant-동작-오류">vagrant 동작 오류</h3>
<p>아주 오래전에 설치해서 잘 기억 나지 않지만 이녀석은 설치할때마다 이런 메시지를 나에게 보여줌
<img src="https://images.velog.io/images/cid-yoon/post/b185ed59-62ff-4f81-bb19-40551abc6691/image.png" alt=""></p>
<p>확장도 깔고 이것 저것 해보지만 항상 결론은 virtualbox 재설치, vagrant 재설치로 마무리됨</p>
<ul>
<li>설치 잘 되었지만 다음과 같은 경고 메시지 보임, 이건 virtual box guest edition 문제로 책에서도 사용하지 않을거니 무시하라고 함( 해결하고 싶으면 게스트 플러그인 설치 : <a href="https://javaworld.co.kr/96">https://javaworld.co.kr/96</a>)
<img src="https://images.velog.io/images/cid-yoon/post/a4aa8da0-fe01-4379-98e8-26ce52bb095e/image.png" alt=""></li>
</ul>
<p>ssh 로 접속 성공
<img src="https://images.velog.io/images/cid-yoon/post/0a6766fd-730f-4105-a147-8312cd133ff7/image.png" alt=""></p>
<p><a href="https://github.com/cid-yoon/do_infiinity_and_beyond/tree/main/devops/k8s/k8s-infra/vagrant/step_01">https://github.com/cid-yoon/do_infiinity_and_beyond/tree/main/devops/k8s/k8s-infra/vagrant/step_01</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[프로세스의 상태]]></title>
            <link>https://velog.io/@cid-yoon/%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4%EC%9D%98-%EC%83%81%ED%83%9C</link>
            <guid>https://velog.io/@cid-yoon/%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4%EC%9D%98-%EC%83%81%ED%83%9C</guid>
            <pubDate>Tue, 20 Apr 2021 15:39:59 GMT</pubDate>
            <description><![CDATA[<h1 id="정의">정의</h1>
<blockquote>
<p>프로세스는 실행되면서 그 상태가 변화한다</p>
</blockquote>
<p>프로세스의 상태는 그 프로세스의 현재의 활동에 따라 부분적으로 정의된다. 
즉 <strong>어느 한 순간에 한 처리기(CPU)상에서는 오직 하나의 프로세스만이 실행</strong> 된다
<img src="https://images.velog.io/images/cid-yoon/post/6738d2fd-bf4f-4a7f-ba84-d9fb9992f0b8/image.png" alt=""></p>
<h2 id="프로세스의-상태-분류">프로세스의 상태 분류</h2>
<p>각 프로세스는 다음 상태들 중 하나에 있을 수 있다
<img src="https://images.velog.io/images/cid-yoon/post/389e0de7-84ed-423c-8cb8-0ffdbb446b3d/image.png" alt=""></p>
<h3 id="생성startnew">생성(Start/New)</h3>
<ul>
<li>프로세스가 생성 중이다</li>
</ul>
<h3 id="실행running">실행(Running)</h3>
<ul>
<li>명령어들이 실행되고 있다</li>
<li>우선순위가 높은 프로세스가 있을 경우, 자신의 상태를 Ready상태로 변경하고 높은 우선순위의 프로세스를 실행</li>
</ul>
<h3 id="대기waiting">대기(Waiting)</h3>
<ul>
<li>프로세스가 어떤 이벤트(입/출력 완료 또는 신호의 수신 같은)이 일어나기를 기다린다</li>
<li><strong>스케줄러에 의해 선택될 수 없는 상태</strong></li>
<li>추가로 프로세스를 종료 시킬 경우 waiting(block) 상태를 거쳐서 exit(termination)상태로 갈 수도 있다</li>
</ul>
<h3 id="준비완료ready">준비완료(Ready)</h3>
<ul>
<li>프로세스가 처리기에 의해 할당되기를 기다린다</li>
<li><strong>스케줄러에 의해 선택</strong>되어 지금 당장이라도 실행 가능한 상태</li>
</ul>
<h3 id="종료termination">종료(Termination)</h3>
<ul>
<li>프로세스의 실행이 종료되었다</li>
</ul>
<h2 id="참조-링크">참조 링크</h2>
<p><a href="https://www.baeldung.com/cs/process-lifecycle">https://www.baeldung.com/cs/process-lifecycle</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Jenkins] 디스크 공간 확보하기]]></title>
            <link>https://velog.io/@cid-yoon/Jenkins-%EB%94%94%EC%8A%A4%ED%81%AC-%EA%B3%B5%EA%B0%84-%ED%99%95%EB%B3%B4%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@cid-yoon/Jenkins-%EB%94%94%EC%8A%A4%ED%81%AC-%EA%B3%B5%EA%B0%84-%ED%99%95%EB%B3%B4%ED%95%98%EA%B8%B0</guid>
            <pubDate>Fri, 16 Apr 2021 15:38:15 GMT</pubDate>
            <description><![CDATA[<h1 id="저장-공간이-부족합니다">저장 공간이 부족합니다</h1>
<p>우리 팀에서는 CI 도구로 젠킨스를 사용하고 있다.</p>
<p>코드 저장소는 회사에서 제공하는 Git을 사용하고 있으며 feature, pr-head에 대한 테스트 &amp; 빌드를 통과해야 배포될 수 있는 구조로 구성되어 있으며 빌드가 끝나면 추출된 아티펙트를 dockerize 하여 레지스트리에 올린다(push)</p>
<blockquote>
<p>디스크 사용량 확인해 주세요</p>
</blockquote>
<p><img src="https://images.velog.io/images/cid-yoon/post/b77dc52c-da47-4391-ac8d-2e05f771375a/image.png" alt=""></p>
<p>빌드 머신에 하드디스크 공간을 95%나 쓰고있다고 연락이 왔다.</p>
<p>역시나 우연의 일치로  동료분에게 메시지도 왔다.</p>
<blockquote>
<p>젠킨스 접속 안되는데요...</p>
</blockquote>
<p>확인해 보자</p>
<pre><code class="language-sh">
# 디스크 사용량 보기
df -h

# 결과
Filesystem      Size  Used Avail Use% Mounted on
devtmpfs        3.8G     0  3.8G   0% /dev
tmpfs           3.9G     0  3.9G   0% /dev/shm
tmpfs           3.9G  394M  3.5G  11% /run
tmpfs           3.9G     0  3.9G   0% /sys/fs/cgroup
/dev/sda3       199G   190G   9G  96% /
/dev/sda2      1014M  178M  837M  18% /boot
/dev/sda1       200M   12M  189M   6% /boot/efi
tmpfs           779M     0  779M   0% /run/user/1000
</code></pre>
<p>하드 디스크 사용량이 아주 빵빵!!!하다. 구글님에게 문의하자</p>
<p>젠킨스 용량 100% 해결하기 글이 보인다
<a href="http://www.kwangsiklee.com/2020/04/%EC%A0%A0%ED%82%A8%EC%8A%A4-%EC%9A%A9%EB%9F%89-100-%EC%B0%AC-%EC%83%81%ED%99%A9-%ED%95%B4%EA%B2%B0%ED%95%98%EA%B8%B0/">젠킨스 용량 100% 찬 상황 해결하기</a></p>
<h2 id="job-디스크-사용량-보기">job 디스크 사용량 보기</h2>
<p>좀더 자세하게 사용 용량을 보여주는 명령이 있으니 한번 확인 해보고</p>
<pre><code class="language-sh"># 디스크 사용량으로 정렬하여 확인
du -hsx * | sort -rh | head -n 10

# 결과
5.7G    workspace
851M    plugins
12.6G   jobs
82M    war
26M    monitoring
18M    org.jenkinsci.plugins.github_branch_source.GitHubSCMProbe.cache
2.4M    updates
1.1M    fingerprints
280K    logs
52K    secrets</code></pre>
<p>음?... </p>
<p>job이 차지하는 공간이 생각보다 적은것 같다. 
그래도 경고를 멈추기 위해 수동으로 job(젠킨스 작업 단위)데이터를 지워보자</p>
<pre><code class="language-sh"># 젠킨스 job 생성 구조가 조금 다르다. 블루 오션이라 그런가?
# 올드 버전 데이터를 지우는 거니 자신의 구조에 맞게 지우면 됨
rm -rf /var/{JENKINS_HOME}/*/jobs/*/branches/*/builds/*
</code></pre>
<p>다시 확인해 보면</p>
<pre><code>du -hsx * | sort -rh | head -n 10

# 결과
5.7G    workspace
851M    plugins
600M   jobs            # 줄기는 줄었는데.. 
82M    war
26M    monitoring
18M    org.jenkinsci.plugins.github_branch_source.GitHubSCMProbe.cache
2.4M    updates
1.1M    fingerprints
280K    logs
52K    secrets</code></pre><p>줄어든 용량이 택도 없다. 이게 아닌가보다</p>
<p>하긴 생각해보니 젠킨스 설정에서 이미 job 관련 보관 개수를 정해 놨기 때문에 그렇게 많은 공간을 사용할 일은 없을 것 같다.
<img src="https://images.velog.io/images/cid-yoon/post/291dcbc1-576d-49f4-9750-ab85772086cc/image.png" alt=""></p>
<p>아.. 젠킨스에서 도커 빌드를 하고 있지? 느낌이 온다</p>
<h2 id="도커-이미지-정리하기">도커 이미지 정리하기</h2>
<p>도커 이미지를 정리해 보자. prune</p>
<pre><code># 사용하지 않는 이미지 제거
# https://docs.docker.com/engine/reference/commandline/image_prune/
docker image prune

# 삭제 경고
WARNING! This will remove all dangling images.
Are you sure you want to continue? [y/N] y
Total reclaimed space: 0B</code></pre><p>0B? 지워진게 없네..</p>
<pre><code># 결과
Filesystem      Size  Used Avail Use% Mounted on
devtmpfs        3.8G     0  3.8G   0% /dev
tmpfs           3.9G     0  3.9G   0% /dev/shm
tmpfs           3.9G  394M  3.5G  11% /run
tmpfs           3.9G     0  3.9G   0% /sys/fs/cgroup
/dev/sda3       199G   178G  21G  89% /
/dev/sda2      1014M  178M  837M  18% /boot
/dev/sda1       200M   12M  189M   6% /boot/efi
tmpfs           779M     0  779M   0% /run/user/1000</code></pre><p>이미지도 아니라면 이젠 도커 빌드 캐시밖에 범인이 없다.</p>
<h2 id="도커-시스템-정리하기">도커 시스템 정리하기</h2>
<p>도커는 레이어 구조로 이미지를 생성하기에 빌드 속도 향상을 위해 캐시를 사용한다
(이 내용은 조만간 정리해야지)</p>
<p>일단 터프한 명령인 system prune + 모두(a) + 강제(f)로 날리자</p>
<pre><code># 터프한 명령어, 빌드 머신에서 실행중인 컨테이너가 없기에 쿨하게 실행
docker system prune -a -f

WARNING! ThDeleted Images:
untagged: 232123048478.dkr.ecr.ap-northeast-2.amazonaws.com/project:latest
.................................................................................
.................................................................................
.................................................................................
deleted: sha256:06b9a94d7befa1634b382f972c8844e865cd01ef6e9980116c23a1e058ebe451

Deleted build cache objects:
gsltrijb4xgdv4nzbr7coqnvk
g8po53jcf9yzm5jc7x2tt8wrk
e1lzobqbm4jf8u0o1h94gyvoa
srbvq001xgiwebnubac3mvwvu
yj4d9nyqok52c2ba3az4ll6w7
sp8fkw9cxvyy8tzy3afqst1r1
tnnoeywgfv2iipsmh4uos7vgp
vedoju5u92m3vsbly547tlpu1
tuij8wztyklet2914txtg1wx6
uxpdfdhtsunnrvcggqpz1vty5
x23qls4pp7nk89qkyxlcwhrcg
jmu8jeto10dniguyez5m2u7x8
il2relqcrwrzq6q56p2hs41gz
4k59zayzfokydkett6yoiffl6
.........................
.........................

Total reclaimed space: 163GB</code></pre><p>엄청나게 많은 빌드 캐시가 쌓여 있었고 제거 되었다고 나왔으니 용량을 확인해 보자</p>
<pre><code>$df -h

# 결과
Filesystem      Size  Used Avail Use% Mounted on
devtmpfs        3.8G     0  3.8G   0% /dev
tmpfs           3.9G     0  3.9G   0% /dev/shm
tmpfs           3.9G  394M  3.5G  11% /run
tmpfs           3.9G     0  3.9G   0% /sys/fs/cgroup
/dev/sda3       199G   15G  185G   8% /
/dev/sda2      1014M  178M  837M  18% /boot
/dev/sda1       200M   12M  189M   6% /boot/efi
tmpfs           779M     0  779M   0% /run/user/1000</code></pre><p>사용량이 줄었다. </p>
<h1 id="정리">정리</h1>
<p>디스크 사용량의 대부부을 차지하고 있던 녀석은 도커 빌드 캐시였고 이를 삭제하여 다시 평온한 상태를 유지할 수 있게 되었다. 앞으로도 이런 경우가 있다면 다음과 같이 정리해 보자</p>
<ol>
<li>빌드 머신의 하드 디스크 사용량이 부족할때는 사용하지 않는 파일을 지우자</li>
<li>젠킨스의 경우, job에서 생성되는 아티펙트 및 히스토리 데이터를 지우면 용량을 확보할 수 있다.</li>
<li>빌드 머신에서 도커 이미지를 빌드하는 경우 사용하지 않는 이미지를 제거하면 저장 공간을 확보할 수 있다.</li>
<li>도커 이미지 빌드 시 속도 향상을 위해 캐시를 사용하는데 이게 생각보다 많은 용량을 차지한다 system prune같은 파괴적 명령을 통해 사용한 캐시를 제거하자. <strong>단 해당 머신이 컨테이너를 운영하는 머신이라면 조심해야 한다</strong></li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Git] 여러 계정으로 사용하기]]></title>
            <link>https://velog.io/@cid-yoon/Git-%EC%97%AC%EB%9F%AC-%EA%B3%84%EC%A0%95%EC%9C%BC%EB%A1%9C-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@cid-yoon/Git-%EC%97%AC%EB%9F%AC-%EA%B3%84%EC%A0%95%EC%9C%BC%EB%A1%9C-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0</guid>
            <pubDate>Thu, 15 Apr 2021 14:03:00 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>Q : 잘못된 push로 낭패를 본적이 있습니까?
A : 네... 회사 소스코드를 공개 저장소에 올린 적이 있습니다</p>
</blockquote>
<p>우연의 일치 + 집중하지 않은 나의 문제 였고 복구 하였지만 당황스러운 경험이였다.</p>
<ol>
<li>fork를 띄어서 프로젝트를 import할 이슈가 생김</li>
<li>개인 학습을 위해 github 저장소를 사용</li>
<li>sourcetree의 계정 정보(git)가 회사 계정에서 개인 계정으로 스위칭</li>
<li>아무 생각 없이 push...</li>
<li>보안 팀에서 연락옴</li>
</ol>
<p>자신의 총명함을 믿습니까? 아니요..</p>
<p>실수를 하지 않기 위해서는? 실수할 상황을 없애거나 줄이면 되기에 개발 환경을 설정하자</p>
<p><strong>내가 사용하고 있는 개발 환경에서 git 저장소가 별도로 동작하게 하자</strong></p>
<h2 id="gitconfig">GitConfig</h2>
<p>git에서 제어할 수 있는 설정값은 다음과 같이 엄청나게 많은 기능일 제공한다</p>
<p><a href="https://gist.github.com/pksunkara/988716">https://gist.github.com/pksunkara</a></p>
<pre><code class="language-sh">[user]
    name = Pavan Kumar Sunkara
    email = pavan.sss1991@gmail.com
    username = pksunkara
[core]
    editor = vim
    whitespace = fix,-indent-with-non-tab,trailing-space,cr-at-eol
    pager = delta
[sendemail]
    smtpencryption = tls
    smtpserver = smtp.gmail.com
    smtpuser = pavan.sss1991@gmail.com
    smtppass = password
    smtpserverport = 587
[web]
    browser = google-chrome
[instaweb]
    httpd = apache2 -f
[rerere]
    enabled = 1
    autoupdate = 1
 ..........more</code></pre>
<p>git을 설치하였다면 다음 명령어를 통해 git 설정 값을 확인 할 수 있다</p>
<pre><code class="language-sh">
# 설정 보기
git config -l

# 설정 파일 보기
vi $HOME/.gitconfig

# 출력
[gpg]
        program = gpg
[commit]
        template = /Users/cid.yoon/.stCommitMsg
        gpgSign = false
[tag]
        forceSignAnnotated = false

[core]
        excludesfile = /Users/cid.yoon/.gitignore_global
        autocrlf = input

[filter &quot;lfs&quot;]
        clean = git-lfs clean -- %f
        smudge = git-lfs smudge -- %f
        process = git-lfs filter-process
        required = true

[difftool &quot;sourcetree&quot;]
        cmd = opendiff \&quot;$LOCAL\&quot; \&quot;$REMOTE\&quot;
        path =
[mergetool &quot;sourcetree&quot;]
        cmd = /Applications/Sourcetree.app/Contents/Resources/opendiff-w.sh \&quot;$LOCAL\&quot; \&quot;$REMOTE\&quot; -ancestor \&quot;$BASE\&quot; -merge \&quot;$MERGED\&quot;
        trustExitCode = true</code></pre>
<p>git 계정을 사용 할 수 있게 ssh를 설정하는 과정은 생략하였는 <a href="https://git-scm.com/book/ko/v2/Git-%EC%84%9C%EB%B2%84-SSH-%EA%B3%B5%EA%B0%9C%ED%82%A4-%EB%A7%8C%EB%93%A4%EA%B8%B0">Git 서버 - SSH 공개키 만들기</a>를 참고하면 된다</p>
<p>간략하게 과정을 정리하면</p>
<ol>
<li>내 컴퓨터에서 사용할 메일 계정으로 ssh 만들기</li>
<li>만들어진 ssh를 github 사이트에 등록하기(사용자 정보 -&gt; settings -&gt; SSH and GPG keys)</li>
<li>해당 계정을 ssh에 등록하기
다음 글을 참고하자 <a href="https://brunch.co.kr/@anonymdevoo/10">Github ssh key 등록하는법</a></li>
</ol>
<p>키 등록을 하였으면 ssh에 내가 사용할 alias를 설정하자</p>
<pre><code class="language-sh"># ssh 설정 파일
vi ~/.ssh/config

# alias 등록
Host github.com                     // 사용할 이름
        HostName github.com                 // host 정보
        User git 
        IdentityFile ~/.ssh/github_id_rsa          // 생성한 ssh의 private key</code></pre>
<p>등록 완료된 ssh 키가 잘 동작하는지 확인하려면 다음과 같은 명령어를 사용하면 된다
여기서 github.com은 내가 등록한 호스트의 alias이다
<img src="https://images.velog.io/images/cid-yoon/post/020b889b-4b6b-4ad3-9332-2f35d2c24b5c/image.png" alt="키 검사"></p>
<p>mac환경 + sourceTree가 설치되어 이런 모양으로 나오는데, <strong>[IncludeIf]</strong> 속성을 사용하여 작업할 폴더와 사용할 계정을 추가해 주면 된다.</p>
<p><a href="https://git-scm.com/docs/git-config#_includes">Includes 속성</a></p>
<blockquote>
<p>Includes
The include and includeIf sections allow you to include config directives from another source. These sections behave identically to each other with the exception that includeIf sections may be ignored if their condition does not evaluate to true; see &quot;Conditional includes&quot; below.</p>
</blockquote>
<p>간략하게 보면 해당 속성을 사용하여 다른 구성 파일(경로 및 설정)을 사용할 수 있는것이다.
원하는 것이 나왔으니 설정하면 된다</p>
<pre><code># ./gitconfig

[includeIf &quot;gitdir:~/cid/&quot;]
        path =.gitconfig-cid // 내가 사용할 설정 정보</code></pre><p>내 설정 정보</p>
<pre><code># ~/.gitconfig-cid
[user]
        email = myemail@mail.com    # git 계정에 사용되는 메일 주소
        name = cid.yoon                # git 사용자 이름</code></pre><p>끝났다. 이제 내가 설정한 폴더로 이동해서 정상적으로 동작 되는지 확인해 보자
<code>git config --show-origin --get user.name</code>
<img src="https://images.velog.io/images/cid-yoon/post/f3e56603-224b-431e-8fc7-0bca3cceaf34/image.png" alt=""></p>
<p>내가 설정했던 이름이 잘 나온다. 다른 폴더로 이동해서 테스트도 해보자
<img src="https://images.velog.io/images/cid-yoon/post/f71a7f5e-a20d-459d-8323-515797688575/image.png" alt=""></p>
<p>별도의 설정 없이도 다른 설정 파일을 사용하는 것을 확인하였다. 이제 그런 일은 없겠지 ;ㅁ;</p>
<h3 id="참고-자료">참고 자료</h3>
<p><a href="https://jintaewoo.tistory.com/44">https://jintaewoo.tistory.com/44</a>
<a href="https://michigusa-nlp.tistory.com/74">https://michigusa-nlp.tistory.com/74</a>
<a href="https://jeunna.tistory.com/109">https://jeunna.tistory.com/109</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[프로세스(Process)란?]]></title>
            <link>https://velog.io/@cid-yoon/%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4Process%EB%9E%80</link>
            <guid>https://velog.io/@cid-yoon/%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4Process%EB%9E%80</guid>
            <pubDate>Wed, 14 Apr 2021 15:29:38 GMT</pubDate>
            <description><![CDATA[<p>해당 내용은 과거에 학습하였던 내용을 복기하기 위한 내용입니다.
대부분 Windows OS를 기반으로 정리되어 있습니다.</p>
<h1 id="정의">정의</h1>
<blockquote>
<p>프로세스(process) : 비공식적으로 실행 중인 프로그램(program)을 지칭</p>
</blockquote>
<p>초기의 컴퓨터 시스템은 한 번에 하나의 프로그램만을 수행하였고 보다 나은 시스템 활용을 위하여 메모리에 다수의 프로그램들이 적재되어 동시에 수행되는 것을 허용하게 되었습니다.</p>
<p>그로 인하여 다양한 프로그램을 보다 견고하게 제어 및 구획화(분리)하여 관리할 것이 필요하게 되었고, 이런 필요성에 의해 프로세스란 개념이 만들어졌으며, 이는 현대의 시분할 시스템(time-sharing) 시스템에서 <strong>작업의 단위</strong>가 되었습니다</p>
<blockquote>
<p>하나의 시스템은 프로세스들의 집합체이다.</p>
</blockquote>
<p>운영체제의 프로세스들을 </p>
<ol>
<li>시스템 코드를 실행(system call)하고</li>
<li>사용자 프로세스들은 사용자 코드를 실행한다. </li>
</ol>
<p>이들 모든 프로세스들은 잠재적으로 병행 수행이 가능하다</p>
<p>CPU는 이들 프로세스들을 다중화(multiplex)하여 각 프로세스들 사이에서 전환(switching)시킴으로써, 운영체제는 컴퓨터를 보다 생산적으로 만든다</p>
<h2 id="프로세스의-구성">프로세스의 구성</h2>
<p>실행 중인 프로그램은 메모리에 상주해 있는(load) 상태의 프로그램입니다. </p>
<p>이 프로세스라 불리는 메모리는 어떻게 구성되어 있을까요? 일반적으로 아래 그림과 같이 4가지 영역으로 나누어져서 각각의 일을 열심히 수행하고 있습니다.</p>
<p><img src="https://images.velog.io/images/cid-yoon/post/2c48582a-82be-4e55-8a15-4da3e63af91e/image.png" alt=""></p>
<p>참조 이미지) <a href="https://www.quora.com/What-is-meant-by-processes-in-OS">What process in operating system</a></p>
<h3 id="data">data</h3>
<blockquote>
<p>전역 변수나 정적(static) 변수의 할당을 위해 존재하는 영역 </p>
</blockquote>
<p>프로그램 작성 시, 우리가 전역 변수 혹은 정적 변수를 선언하는 경우 이 영역에 존재하게 됩니다. 그렇기에 우리는 프로그램 상에서 아무 때나(일반적으로) 부를 수 있게 됩니다.</p>
<h3 id="text">text</h3>
<blockquote>
<p>실행 파일을 구성하는 명령어들이 올라가 있는 메모리 영역</p>
</blockquote>
<p>프로그램이 실행되면 실행 파일에 존재하는 명령어들은 메모리상에 올라가 순차적으로 실행됩니다(PC : Program Counter) 이렇게 실행 파일을 구성하는 명령어들이 올라가 있는 메모리 영역입니다. </p>
<p>프로그램 작성 시, 프로그램 언어를 통하여 작성된 코드들은 해당 영역에서 컴퓨터가 알아들을 수 있는 명령어들로 변환되어 자신의 순서를 기다리게 됩니다.</p>
<h3 id="heap">heap</h3>
<blockquote>
<p>동적 할당(malloc, calloc)을 위해 존재하는 영역</p>
</blockquote>
<p>C++, C# 등의 언어에서 new라는 키워드로 생성되는 값들은 해당 영역에 존재하게 됩니다.</p>
<h3 id="stack">stack</h3>
<p>지역 변수의 할당과 함수 호출 시 전달되는 인자 값들의 저장을 위해 존재하는 영역입니다.</p>
<h3 id="그리고-register-set">그리고 Register Set</h3>
<p>CPU를 구성하는 레지스터(register : 명령어)들은 실행 파일의 실행을 위해 필요한 데이터들로 채워지게 됩니다. 따라서 레지스터들의 상태까지도 프로세스의 일부로 포함시켜 이야기할 수도 있습니다.</p>
<h2 id="정리">정리</h2>
<blockquote>
<p>실행 파일이 메모리에 적재될 때 프로그램은 프로세스가 됩니다</p>
</blockquote>
<p>프로그램(Program) 그 자체는 프로세스가 아닙니다. </p>
<p>프로그램은 명령어 리스트를 내용으로 가진 <strong>디스크에 저장된 파일</strong>(우리가 말하는 실행파일)과 같은 수동적인 존재(passive entity)이기도 하지만 다음에 실행할 명령어를 지정하는 프로그램 카운터와 연관된 자원의 집합을 가진 능동적인 존재(active entity)입니다.</p>
<p>우리는 동일한 프로그램의 구동을 통하여 동일한 프로세스를 만들 수 있습니다. 
이들은 같은 text 섹션의 내용을 통하여 동일한 행동을 수행하게 됩니다. 하지만 <strong>같은 프로세스가 아닙니다</strong></p>
<p>이들은 각각 별개의 프로세스로 관리됩니다. </p>
<p>프로그램은 text 영역을 통하여 동일한 동작을 수행하게 되지만 data, heap 및 stack 영역 할당 시, 운영체제에 의해 고유한 영역을 할당받게 됩니다. 이로 인해 운영체제는 프로세스를 구획화 하여 보다 안전하게 자원을 제어할 수 있게 됩니다.</p>
<p><strong>참고</strong>
[컴퓨터 프로그램] (<a href="https://ko.wikipedia.org/wiki/%EC%BB%B4%ED%93%A8%ED%84%B0_%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%A8">https://ko.wikipedia.org/wiki/%EC%BB%B4%ED%93%A8%ED%84%B0_%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%A8</a>)
<a href="https://ko.wikipedia.org/wiki/%EC%8B%9C%EB%B6%84%ED%95%A0_%EC%8B%9C%EC%8A%A4%ED%85%9C">시분할 시스템</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[부식과 지식 그 사이]]></title>
            <link>https://velog.io/@cid-yoon/%EB%B6%80%EC%8B%9D%EA%B3%BC-%EC%A7%80%EC%8B%9D-%EA%B7%B8-%EC%82%AC%EC%9D%B4</link>
            <guid>https://velog.io/@cid-yoon/%EB%B6%80%EC%8B%9D%EA%B3%BC-%EC%A7%80%EC%8B%9D-%EA%B7%B8-%EC%82%AC%EC%9D%B4</guid>
            <pubDate>Tue, 13 Apr 2021 13:48:17 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>내가 학습하여 익히는 지식보다 시간이 지남에 따라 사라지는 지식이 더 많아지고 있다</p>
</blockquote>
<p>이런 뉘양스가 맞는지 모르겠지만 최근들어 공감하고 고민하는 이야기</p>
<p>내가 가진 지식은 시간이 지남에 따라 부식되고 새로운 지식을 채워넣지만 이 경계선이 무너지게 되면 그때 개발자로서 수명이 끝나는것이 아닌가라는 고민을 한다</p>
<p>이 벨로그는 부식되어 부패되는 지식을 사라지지 않게 하기 위해
그리고 발효(fermentation)되어 새로운 방향으로 발전하기 위해 기록한다</p>
<p>부끄러워 하지 말자</p>
<blockquote>
<p>세상 사람들은 내가 무엇을 하던 관심이 없다</p>
</blockquote>
]]></description>
        </item>
    </channel>
</rss>