<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>bbak_joon.log</title>
        <link>https://velog.io/</link>
        <description>"차근차근"</description>
        <lastBuildDate>Sat, 27 Mar 2021 11:52:41 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>bbak_joon.log</title>
            <url>https://images.velog.io/images/bbak_joon/profile/8561dde7-a04c-45ca-baae-c7d5de70cb7a/social.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. bbak_joon.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/bbak_joon" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[Spring Framework - 핵심기술(개념)]]></title>
            <link>https://velog.io/@bbak_joon/Spring-Framework-%ED%95%B5%EC%8B%AC%EA%B8%B0%EC%88%A0%EA%B0%9C%EB%85%90</link>
            <guid>https://velog.io/@bbak_joon/Spring-Framework-%ED%95%B5%EC%8B%AC%EA%B8%B0%EC%88%A0%EA%B0%9C%EB%85%90</guid>
            <pubDate>Sat, 27 Mar 2021 11:52:41 GMT</pubDate>
            <description><![CDATA[<p>스프링에 대해 공부를 시작해보려합니다.</p>
<p>인프런에서 [스프링 프레임워크 핵심 기술] (<a href="https://www.inflearn.com/course/spring-framework_core/lecture/15502?tab=curriculum">https://www.inflearn.com/course/spring-framework_core/lecture/15502?tab=curriculum</a>) 강좌를 수강하며 내용 정리해보겠습니다!</p>
<h2 id="학습-목차">학습 목차</h2>
<ul>
<li>IoC 컨테이너와 빈</li>
<li>리소스</li>
<li>Validation</li>
<li>데이터 바인딩</li>
<li>SpEL(Spring Expression Language)</li>
<li>스프링 AOP</li>
<li>Null-Safety</li>
</ul>
<h2 id="스프링이란">스프링이란?</h2>
<blockquote>
<p>&quot;소규모 애플리케이션 또는 기업용 애플리케이션을 자바로 개발하는데 있어 유용하고 편리한 기능을 제공하는 프레임워크&quot;</p>
</blockquote>
<h2 id="❗️ioc-컨테이너">❗️IoC 컨테이너</h2>
<h3 id="스프링-ioc-컨테이너inversion-of-control">스프링 IoC 컨테이너(Inversion of Control)</h3>
<blockquote>
<p>의존 관계 주입(Dependency Injection)이라고도 하며, 어떤 객체가 사용하는 <strong>의존 객체를 직접 만들어서사용하는게 아니라, 주입 받아 사용하는 방법</strong>을 말한다.</p>
</blockquote>
<p>예시를 코드로 보면</p>
<pre><code class="language-java"></code></pre>
<h3 id="빈">빈</h3>
<blockquote>
<p>스프링 IoC 컨테이너가 관리하는 객체</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[Spring ]]></title>
            <link>https://velog.io/@bbak_joon/Spring</link>
            <guid>https://velog.io/@bbak_joon/Spring</guid>
            <pubDate>Wed, 03 Mar 2021 08:14:42 GMT</pubDate>
            <description><![CDATA[<p>저는 Spring에 대한 기본적인 지식 없이 운영업무를 맡게 되었습니다. 시스템 초기 구축이 아니라 구축되어 있는 시스템에 추가적인 개발 및 수정을 하면서 제대로된 이해 없이 업무만 진행하는 느낌을 받았습니다. 따라서 시간을 내 스프링에 대해 알아볼까 합니다!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[백준 1655번 - 평범한 배낭]]></title>
            <link>https://velog.io/@bbak_joon/%EB%B0%B1%EC%A4%80-12865%EB%B2%88-%ED%8F%89%EB%B2%94%ED%95%9C-%EB%B0%B0%EB%82%AD</link>
            <guid>https://velog.io/@bbak_joon/%EB%B0%B1%EC%A4%80-12865%EB%B2%88-%ED%8F%89%EB%B2%94%ED%95%9C-%EB%B0%B0%EB%82%AD</guid>
            <pubDate>Sun, 28 Feb 2021 13:38:04 GMT</pubDate>
            <description><![CDATA[<p><img src="https://images.velog.io/images/bbak_joon/post/fa70fcc9-d7d0-46c1-98d0-331734608357/image.png" alt="">
문제를 읽고 단순히 접근하면 입력받을 때 마다 정렬하여 중간값을 찾아 출력하면 되겠다고 생각합니다. 저 또한 그러했고, 쉽게 코딩 후 결과는 <strong>시간초과</strong>...</p>
<p>정렬과 중간값을 찾는 과정을 O(1)로 만들어야 한다는 것을 깨달은 후 여러 자료구조 형태를 고민하다 우선순위 큐를 사용해보았습니다.</p>
<p>이 문제는 우선순위 큐를 2개를 사용하여 입력되는 숫자들의 중간값을 top로 유지시키며 추출하는 문제입니다.</p>
<p>제가 처음 구상한 방법은 하나의 정렬된 상태를 만들기 위해 우선순위 큐 두개(<em>max heap 1개, min heap 1개</em>)로 나누는 방법입니다.</p>
<p>예를들어</p>
<p>입력된 숫자가 1, 2, 3, 4, 5, 6, 7, 8 이라고 하면</p>
<blockquote>
<p>우선순위 큐1(max heap) : 4, 3, 2, 1
우선순위 큐2(min heap) : 5, 6, 7, 8</p>
</blockquote>
<p>처럼 구성하는 방법입니다.</p>
<p>2개로 나뉘어져 있지만 우선순위 큐1을 거꾸로 시작하여 반시계방향으로 우선순위 큐2까지 보면 순서대로 1, 2, 3, 4, 5, 6, 7, 8임을 알 수 있고, 우선순위 큐1에 항상 중간값이 오는 걸 알 수 있습니다. </p>
<p>로직은 먼저 max heap에 숫자를 처음 입력받습니다.</p>
<p>그 수보다 크면 min heap, 작으면 max heap에 push합니다. </p>
<p>이후 max heap의 top를 기준으로 새로 입력받는 숫자가 작으면 max heap, 크면 mean heap으로 push합니다.</p>
<p>두 우선순위 큐의 갯수를 항상 같거나 1씩 차이나도록 설정해야 max heap에 중간값이 위치할 수 있습니다.</p>
<blockquote>
<p>우선순위 큐1(max heap) : 2 1
우선순위 큐2(min heap) : 3 4 5 6 7 8</p>
</blockquote>
<p>위 예시처럼 갯수가 한쪽으로 편향되면 안됩니다. 새로운 숫자를 입력받아 push를 할 때 두 큐의 개수가 같으면 한쪽에 push를 하고 나서 push한 큐의 top를 다른 큐에 옮깁니다. </p>
<p>두 큐의 개수가 다를 경우 push하기 전에 옮겨서 개수를 같게 맞춘 다음 위와 같은 작업을 실시합니다.</p>
<p>이렇게 두 우선순위 큐의 균형을 맞춰가며 중간값을 유지하는 로직으로 구현하였습니다.</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;vector&gt;
#include &lt;algorithm&gt;
#include &lt;queue&gt;

using namespace std;


int main(){
    ios_base::sync_with_stdio(false); cin.tie(NULL);    
    int num;
    cin &gt;&gt; num;
    priority_queue&lt;int, vector&lt;int&gt;, greater&lt;int&gt; &gt; min_queue;
    priority_queue&lt;int, vector&lt;int&gt;, less&lt;int&gt; &gt; max_queue;

    int input;
    cin &gt;&gt; input;
    max_queue.push(input);
    cout &lt;&lt; max_queue.top() &lt;&lt; &#39;\n&#39;;
    for(int i = 1; i &lt; num; i++){

        cin &gt;&gt; input;



        if(max_queue.top() &lt; input){
            if(max_queue.size() == min_queue.size()){
                min_queue.push(input);
                int temp = min_queue.top();
                min_queue.pop();
                max_queue.push(temp);
            }
            else{
                min_queue.push(input);
                if(max_queue.size() != min_queue.size()){
                    int temp = min_queue.top();
                    min_queue.pop();
                    max_queue.push(temp);
                }
            }

        }
        else{
            if(max_queue.size() == min_queue.size()){
                max_queue.push(input);
                int temp = max_queue.top();
                max_queue.pop();
                min_queue.push(temp);
            }
            else{
                max_queue.push(input);
                if(max_queue.size() != min_queue.size()){
                    int temp = max_queue.top();
                    max_queue.pop();
                    min_queue.push(temp);
                }
            }

        }
        if(max_queue.size() &lt; min_queue.size()){
            cout &lt;&lt; min_queue.top() &lt;&lt; &#39;\n&#39;;
        }
        else{
            cout &lt;&lt; max_queue.top() &lt;&lt; &#39;\n&#39;;

        }


    }

}</code></pre>
<h3 id="다른-분의-코드-참조-내용">다른 분의 코드 참조 내용</h3>
<p>다른 분들의 코드를 보며 공부를 하다 저의 로직보다 간단한 로직이 있었습니다. 제가 구현할 때 push할 때 max heap의 top와 비교하여 우선순위 큐를 골라 push하였는데 이는 필요없는 과정이였습니다. 항상 두 우선순위 큐의 갯수만 같도록 max heap과 min heap의 <strong>개수가 같을 때 max heap에 push</strong>, <strong>개수가 다를 때 min heap에 push</strong>를 통해 두 큐의 개수 유지를 합니다.(이 부분은 저와 같습니다.) 하지만 입력되는 수의 크기를 비교하여 push할 큐를 고르는 것이 아니라 push를 한 후 두 큐의 top을 비교하여 max heap의 top에 항상 작은 값들을 오게 합니다. 이는 우선순위 큐에 push 되는 것만으로 정렬이 되고, top를 비교하여 max heap에 작은 값을 옮겨준다면 최종형태가 저의 로직과 같아지는 것을 알게 되었습니다. 이 로직이 훨씬 조건문들이 적고 간편하며 직관적이라 생각됩니다.</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;queue&gt;
using namespace std;

int main(){
    ios_base::sync_with_stdio(false); cin.tie(NULL);    
    priority_queue&lt;int , vector&lt;int&gt;, greater&lt;int&gt; &gt; min_queue;
    priority_queue&lt;int, vector&lt;int&gt;, less&lt;int&gt; &gt; max_queue;

    int num;
    cin &gt;&gt; num;
    for(int i = 0; i &lt; num; i++){
        int input;
        cin &gt;&gt; input;
        if(max_queue.size() == min_queue.size()){
            max_queue.push(input);
        }
        else{
            min_queue.push(input);
        }
        // 두 우선순위 큐가 비어있지 않으면서 max heap의 top가 min heap의 top 보다 클 경우 swap
        if(!max_queue.empty() &amp;&amp; !min_queue.empty() &amp;&amp; max_queue.top() &gt; min_queue.top()){
            int swap_temp1 = max_queue.top();
            int swap_temp2 = min_queue.top();
            max_queue.pop();
            min_queue.pop();
            max_queue.push(swap_temp2);
            min_queue.push(swap_temp1);
        }

        cout &lt;&lt; max_queue.top() &lt;&lt; &#39;\n&#39;;
    }
}
</code></pre>
<h3 id="참조">참조</h3>
<p><a href="https://blog.naver.com/music4537/222249608344">https://blog.naver.com/music4537/222249608344</a></p>
<h3 id="추가적으로">추가적으로</h3>
<p>위 문제처럼 입출력이 n번만큼 자주 등장할 경우 endl이나 cin, cout을 사용하면 시간초과가 발생할 확률이 높습니다. </p>
<blockquote>
<p>ios_base::sync_with_stdio(false); cin.tie(NULL);    </p>
</blockquote>
<p>위 처리를 메인 내에서 해준다면 입출력속도를 향상시킬 수 있습니다. 또한 줄바꿈을 <strong>&#39;endl&#39;</strong> 대신 <strong>&#39;\n&#39;</strong>을 사용하는 것이 더 빠릅니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Maven]]></title>
            <link>https://velog.io/@bbak_joon/Maven</link>
            <guid>https://velog.io/@bbak_joon/Maven</guid>
            <pubDate>Wed, 24 Feb 2021 18:26:35 GMT</pubDate>
            <description><![CDATA[<h2 id="maven---java-빌드-도구">Maven - Java 빌드 도구</h2>
<p>아파치 메이븐(Apache Maven)은 자바 기반 프로젝트의 <strong>라이프사이클(Life Cycle)</strong>관리를 위한 빌드 도구입니다.</p>
<h3 id="라이프사이클life-cycle이란">라이프사이클(Life Cycle)이란?</h3>
<p>메이븐은 프레임워크 중 하나입니다. 따라서 정해진 순서에 따라 동작하며, 이러한 빌드 순서를 라이프사이클이라 합니다.</p>
<p>각 단계 - Phase(기능)에 대해 알아보면</p>
<ol>
<li>Default(Build) : 일반적인 빌드 프로세스를 위한 모델</li>
<li>Clean : 빌드 시 생성되었던 파일들을 삭제하는 단계</li>
<li>Validate : 프로젝트가 올바른지 확인하고 필요한 모든 정보를 사용할 수 있는지 확인하는 단계</li>
<li>Compile : 프로젝트 소스 컴파일하는 단계</li>
<li>Test : 유닛(단위)테스트를 수행하는 단계(테스트 실패 시 빌드 실패로 처리, 스킵 가능)</li>
<li>Package : 실제 컴파일된 소스코드와 리소스들을 jar, war 등의 파일로 배포를 위한 패키지(압축)로 만드는 단계</li>
<li>Verify : 통합 테스트 결과에 대한 검사를 실행하여 품질 기준을 충족하는지 확인하는 단계</li>
<li>Install : 패키지를 로컬 저장소에 설치하는 단계</li>
<li>Site : 프로젝트 문서와 사이트 작성하는 단계</li>
<li>Deploy : 만들어진 Package를 원격저장소에 release하는 단계</li>
</ol>
<p>최종 빌드 순서는 [Compile] -&gt; [test] -&gt; [package]</p>
<ul>
<li>compile : src/main/java 내 모든 소스코드가 컴파일</li>
<li>test : src/test/java, src/test/resources 테스트 자원 복사 및 테스트 소스 코드 컴파일</li>
<li>packaging : 컴파일과 테스트 완료 후 jar, war 같은 형태로 압축</li>
</ul>
<p>각 단계(Phase)는 의존관계를 가지고 있어 이전 Phase가 수행되어야 수행가능합니다. 즉, 모든 빌드 단계는 이전 단계가 성공적으로 실행되었을 때 실행된다는 것이 의존(Dependency)입니다.</p>
<p>이 자바 빌드 도구인 Maven의 특징, 장점, 단점을 알아봅시다.</p>
<h4 id="특징">특징</h4>
<ul>
<li>컴파일과 빌드를 동시에 수행합니다.</li>
<li>테스트를 병행하거나 서버 측 배포 자원을 관리할 수 있는 환경을 제공합니다.</li>
<li>라이브러리 관리 기능도 내포하고 있습니다.</li>
<li>필요한 라이브러리를 pom.xml에 정의해 놓으면 해당 라이브러리가 작동하는데 필요한 다른 라이브러리들까지 관리하여 자동으로 다운로드 해줍니다.</li>
</ul>
<h4 id="장점">장점</h4>
<ul>
<li>컴파일과 빌드를 동시에 수행 가능</li>
<li>서버의 Deploy자원을 관리할 수 있는 환경 제공</li>
<li>pom.xml 파일을 통해 관리하므로 개발, 유지보수 측면에서 오픈소스 라이브러리, 프로젝트 등 관리가 용이</li>
<li>IDE에 종속된 부분들을 제거 가능</li>
<li>Maven Profile 기능을 통해 배포 설정 파일을 관리하고 배포 파일을 생성 가능</li>
</ul>
<h4 id="단점">단점</h4>
<ul>
<li>메이븐에서 지원하지 않는 빌드 과정을 추가해야 하는 경우 복잡</li>
<li>특정 플러그인 설정이 달라지면 재사용성 및 확장성 저하, 가독성 저하, 중복 발생</li>
<li>이와 같은 단점들을 해결하기 위해, 그레이들(Gradle)이라는 새로운 빌드 툴 등장 -&gt; 안드로이드 앱 기본 빌드 툴</li>
</ul>
<h3 id="구조">구조</h3>
<p><img src="https://images.velog.io/images/bbak_joon/post/aadc0022-11de-430b-934b-ef566c5fb4e2/image.png" alt=""></p>
<h3 id="설정파일">설정파일</h3>
<p><strong>settings.xml</strong> : 메이븐을 빌드할 떄 의존관계에 있는 라이브러리, 플러그인을 위치 설정할 수 있음.</p>
<p>▶︎ 메이븐 빌드 툴과 관련한 설정파일
▶︎ MAVEN_HOME/conf 디렉토리에 위치(메이븐 설치 시 기본 제공)</p>
<p><strong>POM(Project Object Model)</strong> : 프로젝트 객체 모델
▶︎ POM은 pom.xml을 뜻하며, 메이븐을 이용하는 프로젝트의 root에 존재하는 파일
▶︎ 프로젝트별 1개, 모든 설정, 의존성 등을 알 수 있다.</p>
<p>예시</p>
<pre><code class="language-xml">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt; &lt;project&gt;
  &lt;!-- model version is always 4.0.0 for Maven 2.x POMs --&gt;
  &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;

  &lt;!-- project coordinates, i.e. a group of values which
       uniquely identify this project --&gt;

  &lt;groupId&gt;com.mycompany.app&lt;/groupId&gt;
  &lt;artifactId&gt;my-app&lt;/artifactId&gt;
  &lt;version&gt;1.0&lt;/version&gt;

  &lt;!-- library dependencies --&gt;

  &lt;dependencies&gt;
    &lt;dependency&gt;

      &lt;!-- coordinates of the required library --&gt;

      &lt;groupId&gt;junit&lt;/groupId&gt;
      &lt;artifactId&gt;junit&lt;/artifactId&gt;
      &lt;version&gt;3.8.1&lt;/version&gt;

      &lt;!-- this dependency is only used for running and compiling tests --&gt;

      &lt;scope&gt;test&lt;/scope&gt;

    &lt;/dependency&gt;
  &lt;/dependencies&gt;
&lt;/project&gt;</code></pre>
<h3 id="reference">Reference</h3>
<p><a href="https://namu.wiki/w/Maven">https://namu.wiki/w/Maven</a>
<a href="https://blog.naver.com/dktmrorl/222131777444">https://blog.naver.com/dktmrorl/222131777444</a>
<a href="https://ko.wikipedia.org/wiki/%EC%95%84%ED%8C%8C%EC%B9%98_%EB%A9%94%EC%9D%B4%EB%B8%90">https://ko.wikipedia.org/wiki/아파치_메이븐</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Spring - Pet Clinic Project (1/?)]]></title>
            <link>https://velog.io/@bbak_joon/Spring-%EA%B3%B5%EB%B6%80-1</link>
            <guid>https://velog.io/@bbak_joon/Spring-%EA%B3%B5%EB%B6%80-1</guid>
            <pubDate>Wed, 24 Feb 2021 15:16:58 GMT</pubDate>
            <description><![CDATA[<p><img src="https://images.velog.io/images/bbak_joon/post/39b3b673-ebfd-4a10-98a5-f9f38272afb5/OG-Spring.png" alt=""></p>
<p>안녕하세요. Spring 공부를 위해 대표적인 &#39;Pet Clinic&#39; 프로젝트를 가지고 과제를 진행해보게 되었습니다.</p>
<h3 id="준비-및-실행빌드로컬-기동-방법">준비 및 실행(빌드/로컬 기동) 방법</h3>
<p>먼저 git clone을 합니다.</p>
<blockquote>
<p>git clone <a href="https://github.com/spring-projects/spring-petclinic">https://github.com/spring-projects/spring-petclinic</a></p>
</blockquote>
<p>이후 </p>
<blockquote>
<p>./mvnw package </p>
</blockquote>
<p>를 통해 maven을 이용하여 빌드를 합니다.
(mvnw는 maven이 설치되어 있지 않더라도 가능한 명령어입니다.)</p>
<p>(maven에 대한 내용 : <a href="https://velog.io/@bbak_joon/Maven">https://velog.io/@bbak_joon/Maven</a>)</p>
<p>이후 로컬에서 기동 방법은 2가지입니다.</p>
<ol>
<li><p>jar파일로 컴파일 및 빌드</p>
<blockquote>
<p>java -jar target/*.jar</p>
</blockquote>
</li>
<li><p>IDE에서 메인 Application 실행(maven package 이후만 가능)</p>
<blockquote>
<p>⌃⇧R : 실행
⌘F2 : 종료</p>
</blockquote>
</li>
</ol>
<h3 id="로그-설정">로그 설정</h3>
<blockquote>
<p>src/main/resource/templates/application.properties</p>
</blockquote>
<p>위 경로에 있는 application.properties 파일을 통해 logging level을 설정할 수 있습니다.</p>
<p>loging level에는 INFO, DEBUG 두가지 단계가 있습니다.</p>
<blockquote>
<p>logging.level.org.springframework=INFO
logging.level.org.springframework.web=DEBUG</p>
</blockquote>
<p>DEBUG 단계에서 더 자세한 로그 메세지를 볼 수 있다.</p>
<h3 id="화면-호출">화면 호출</h3>
<blockquote>
<p>url : localhost:8080/owners/new</p>
</blockquote>
<p>화면호출 과정에 대해서 정리해보았습니다.</p>
<p>url 호출 이후 spring의 DispatcherServelet으로 가서 @GetMapping이라는 annotaion을 통해 해당 controller에서 owners/new와 매핑되는 함수를 호출합니다.
controller에서 리턴하는 문자열은 VIEW 이름에 해당합니다. resources/templates 내에 VIEW(html) 파일들이 존재하는데, 그중 리턴하는 이름의 VIEW 파일을 웹상에서 보여지게 됩니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[WEB 동작 방식]]></title>
            <link>https://velog.io/@bbak_joon/WEB-%EB%8F%99%EC%9E%91-%EB%B0%A9%EC%8B%9D</link>
            <guid>https://velog.io/@bbak_joon/WEB-%EB%8F%99%EC%9E%91-%EB%B0%A9%EC%8B%9D</guid>
            <pubDate>Tue, 23 Feb 2021 17:45:11 GMT</pubDate>
            <description><![CDATA[<h3 id="사용자들이-웹-접속-시-어떻게-구동되는지-간단하게-알아보겠습니다">사용자들이 웹 접속 시 어떻게 구동되는지 간단하게 알아보겠습니다.</h3>
<h2 id="과정">과정</h2>
<ol>
<li>브라우저는 DNS 서버로 가서 요청한 URL의 진짜 주소를 찾습니다.</li>
<li>브라우저가 서버에게 웹사이트의 사본을 클라이언트에게 보내달라는 Http 요청 메세지를 서버로 전송합니다.(메세지를 포함한 모든 서버, 클라이언트 사이 전송되는 데이터들은 TCP/IP 연결을 통해 전송됩니다)</li>
<li>이 메세지를 받은 서버가 클라이언트의 요청을 승인하고 200 메세지를 클라이언트에게 전송합니다. 이후 웹사이트의 파일들을 패킷 형식으로 브라우저에 전송하기 시작합니다.</li>
<li>브라우저는 패킷들을 조합하여 웹사이트를 클라이언트에게 보여줍니다.</li>
</ol>
<h2 id="dns">DNS</h2>
<p>실제 웹 주소는 IP주소입니다. 웹사이트와 관련없는 숫자로 구성되어 있기 때문에 도메인 이름 서버(DNS)가 발명되었습니다. 우리가 사용하는 URL 주소이며, 이 주소의 IP 주소를 찾아주는 특별한 서버를 DNS서버라 합니다.</p>
<h3 id="credit">CREDIT</h3>
<p><a href="https://developer.mozilla.org/ko/docs/Learn/Getting_started_with_the_web/%EC%9B%B9%EC%9D%98_%EB%8F%99%EC%9E%91_%EB%B0%A9%EC%8B%9D">참고자료</a></p>
]]></description>
        </item>
    </channel>
</rss>