<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>tth-k.log</title>
        <link>https://velog.io/</link>
        <description>백엔드 취준생 / 코린이 ヾ(≧▽≦*)o</description>
        <lastBuildDate>Fri, 15 Dec 2023 05:07:34 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>tth-k.log</title>
            <url>https://velog.velcdn.com/images/tth-k/profile/6d8ba20f-6555-4095-9ac5-3fee3affe54b/image.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. tth-k.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/tth-k" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[Effective Java 3/E 북스터디 2장_item)6~9]]></title>
            <link>https://velog.io/@tth-k/Effective-Java-3E-%EB%B6%81%EC%8A%A4%ED%84%B0%EB%94%94-2%EC%9E%A5item69</link>
            <guid>https://velog.io/@tth-k/Effective-Java-3E-%EB%B6%81%EC%8A%A4%ED%84%B0%EB%94%94-2%EC%9E%A5item69</guid>
            <pubDate>Fri, 15 Dec 2023 05:07:34 GMT</pubDate>
            <description><![CDATA[<h2 id="2장-객체-생성과-파괴item-6--9">2장 객체 생성과 파괴(Item 6 ~ 9)</h2>
<blockquote>
<p>아이템 6) 불필요한 객체 생성을 피하라</p>
</blockquote>
<ul>
<li>똑같은 기능의 객체를 매번 생성하기보단 객체 하나를 재사용하는 편이 나을 때가 많다.<pre><code>String s = new String(&quot;apple&quot;); // 따라 하지 말 것!</code></pre><pre><code>String s = &quot;apple&quot;; // 개선된 코드</code></pre></li>
</ul>
<p>ex) 주어진 문자열이 유효한 로마 숫자인지를 확인하는 메서드 작성</p>
<pre><code>package step2;

// item6 : 불필요한 객체 생성을 피하라

public class item6_1 {
    // 성능을 훨씬 더 끌어올릴 수 있다
    static boolean isRomanNumeral(String s){
        return s.matches(&quot;^(?=.)M*(C[MD]|D?C{0,3})&quot;
                + &quot;(X[CL]|L?X{0,3})(I[XV]|V?I{0,3})$&quot;);
    }
}</code></pre><ul>
<li>String.matches는 정규표현식으로 문자열 형태를 확인하는 가장 쉬운 방법이지만, 성능이 중요한 상황에서 반복해 사용하기엔 적합하지 않다.</li>
</ul>
<pre><code>package step2;

// item6 : 불필요한 객체 생성을 피하라

import java.util.regex.Pattern;

public class item6_2 {
    // 값비싼 객체를 재사용해 성능을 개선한다.
    public static final Pattern ROMAN = Pattern.compile(
            &quot;^(?=.)M*(C[MD]|D?C{0,3})&quot;
                    + &quot;(X[CL]|L?X{0,3})(I[XV]|V?I{0,3})$&quot;
    );
    static boolean isRomanNumeral(String s){
        return ROMAN.matcher(s).matches();
    }
}</code></pre><ul>
<li><p>이렇게 개선하면 isRomanNumeral이 빈번하게 호출되는 상황에서 성능을 끌어올릴 수있다.</p>
<br>
</li>
<li><p>Boxing Type 대신 Primitive Type을 권장한다.</p>
</li>
<li><pre><code>package step2;
</code></pre></li>
</ul>
<p>// item6 : 불필요한 객체 생성을 피하라</p>
<p>public class item6_3 {
    // Boxing Type
    private static long sum1(){
        Long sum = 0L;
        for (long i = 0; i &lt; Integer.MAX_VALUE; i++) {
            sum += i;
        }
        return sum;
    }</p>
<pre><code>// Primitive Type
private static long sum2(){
    long sum = 0L;
    for (long i = 0; i &lt; Integer.MAX_VALUE; i++) {
        sum += i;
    }
    return sum;
}</code></pre><p>}</p>
<pre><code>- sum1과 sum2를 비교했을 때 sum2가 약 10배 정도 빠른 실험 결과가 나왔다.
- Boxing된 기본타입보다는 기본타입을 사용하고, 의도치 않은 AutoBoxing을 조심해야한다.

&gt; 아이템 7) 다 쓴 객체 참조를 해제하라
</code></pre><p>package step2;</p>
<p>// item7 : 다 쓴 객체 참조를 해제하라</p>
<p>import java.util.EmptyStackException;</p>
<p>public class Java_7 {
    // 제대로 구현한 pop 메서드
    public Object pop(){
        if (size == 0)
            throw new EmptyStackException();
        Object result = elements[--size];
        elements[size] = null; // 다 쓴 참조 해제
        return result;
    }
}</p>
<pre><code>
-  다 사용한 참조 null 처리 시 이점
    - null 처리한 참조를 실수로 사용하려 하면 프로그램은 즉시 NullPointerException을 던지며 종료된다.


- 하지만 모든 객체를 다 사용하자마자 일일히 null 처리 시 지저분해질 수 있다.

- 객체 참조를 null처리하는 일은 예외적인 경우여야 한다.

- 핵심정리
    - 메모리 누수는 겉으로 잘 드러나지 않아 시스템에 수년간 잠복하는 사례가 있다.
     - 누수는 리뷰코드나 힙 프로파일러 같은 디버깅 도구를 동원해야만 발견되기도 한다.
    - 예방법을 익혀두는게 중요하다.

&gt; item 8) finalizer와 cleaner 사용을 피하라

- Java의 2가지 객체 소멸자
    - finalizer
    - cleaner

- finalizer의 특징
    - 예측불가
    - 상황에 따라 위험할 수 있어 일반적으로 불필요하다.

- cleaner의 특징
    - finalizer의 대안으로 finalizer보다는 덜 위험하다.
    - 예측불가
    - 느리고, 일반적으로 불필요하다.

- finalizer와 cleaner가 할 수 없는 작업과 문제
    - 제때 실행되어야 하는 작업
    - 상태를 영구적으로 수정하는 작업
    - 심각한 성능 문제

- finalizer를 사용한 클래스는 finalizer 공격에 노출되어 심각한 보안문제를 일으킬 수 있다.
    - 객체 생성을 막으려면 생성자에서 예외를 던지는 것만으로도 충분하지만 finalizer가 있다면 그렇지 않다.
    - 해결방안 : final이 아닌 클래스를 finalizer 공격으로부터 방어하려면 아무 일도 하지 않는 finalizer 메서드를 만들고 final로 선언한다.

- finalizer와 cleaner를 대신해줄 방법 : **AutoCloseable**
    - AutoCloseable를 구현하고 크라이언트에서 인스턴스를 다 사용하고 나면 close 메서드를 호출하면 된다.

- 핵심정리
    - cleaner(자바 8까지는 finalizer)는 안전망 역할이나 중요하지 않은 네이티브 자원 회수용으로만 사용
    - 사용 시 불확실성과 성능저하에 주의해야 한다.

&gt; item9) try-finally 보다는 try-with-resources를 사용하라

- 자바 라이브러리에는 close 메서드를 호출해 직접 닫아줘야하는 자원이 많다. ex) InputStream, OutputStream, java.sql.Connection 등

- 자원이 제대로 닫힘을 보장하는 수단으로 try-finally가 쓰이지만 자원을 회수하는 최선의 방법이 아니다.</code></pre><p>package step2;</p>
<p>// item9 : try-finally 보다는 try-with-resources를 사용하라</p>
<p>import java.io.*;</p>
<p>public class Java_9_1 {
    // 자원이 둘 이상이면 try-finally 방식은 지저분하다.
    static void copy(String src, String dst) throws IOException {
        InputStream in = new FileInputStream(src);
        try {
            OutputStream out = new FileOutputStream(dst);
            try {
                byte[] buf = new byte[BUFFER_SIZE];
                int n;
                while ((n = in.read(buf)) &gt;= 0)
                    out.write(buf, 0, n);
            } finally {
                out.close();
            }
        } finally {
            in.close();
        }
    }
}</p>
<pre><code>
- 다음은 9_1 코드에 try-with-resources를 적용한 모습이다.</code></pre><p>package step2;</p>
<p>// item9 : try-finally 보다는 try-with-resources를 사용하라</p>
<p>import java.io.*;</p>
<p>public class Java_9_2 {
    // try-with-resources 적용
    static void copy(String src, String dst) throws IOException {</p>
<pre><code>    try (InputStream in = new FileInputStream(src);
         OutputStream out = new FileOutputStream(dst)) {
        byte[] buf = new byte[BUFFER_SIZE];
        int n;
        while ((n = in.read(buf)) &gt;= 0)
            out.write(buf, 0, n);
    }
}</code></pre><p>}</p>
<p>```</p>
<ul>
<li><p>훨씬 짧고 읽기 수월하며 추후 문제를 찾기에도 좋다.</p>
</li>
<li><p>핵심정리</p>
<ul>
<li>꼭 회수해야하는 자원을 다룰 때는 try-with-resources를 사용</li>
<li>코드는 더 짧고 분명해지고 만들어지는 예외 정보도 훨씬 유용하다.</li>
<li>finally가 필요한 상황이면 try-with-resources를 사용</li>
</ul>
</li>
</ul>
<p>** 이미지출처) Google yes24</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Effective Java 3/E 북스터디 2장_item)1~5]]></title>
            <link>https://velog.io/@tth-k/Effective-Java-3E-%EB%B6%81%EC%8A%A4%ED%84%B0%EB%94%94-2%EC%9E%A5item15</link>
            <guid>https://velog.io/@tth-k/Effective-Java-3E-%EB%B6%81%EC%8A%A4%ED%84%B0%EB%94%94-2%EC%9E%A5item15</guid>
            <pubDate>Thu, 07 Dec 2023 13:56:33 GMT</pubDate>
            <description><![CDATA[<h2 id="2장-객체-생성과-파괴item-1--5">2장 객체 생성과 파괴(Item 1 ~ 5)</h2>
<blockquote>
<p>아이템 1) 생성자 대신 정적 팩터리 메서드를 고려하라</p>
</blockquote>
<ul>
<li>정적 팩터리의 장점<ul>
<li>이름을 가질 수 있다.</li>
<li>호출될 때마다 인스턴스를 새로 생성하지는 않아도 된다.</li>
<li>반환 타입의 하위 타입 객체를 반환할 수 있는 능력이 있다.</li>
<li>입력 매개변수에 따라 매번 다른 클래스의 객체를 반환할 수 있다.</li>
<li>정적 팩터리 메서드를 작성하는 시점에는 반환할 객체의 클래스가 존재하지 않아도 된다.<br></li>
</ul>
</li>
<li>정적 팩터리의 단점<ul>
<li>정적 팩터리 메서드만 제공하면 public이나 protected 생성자가 필요하니 상속받은 클래스를 만들 수 없다.</li>
<li>프로그래머가 인지하기 어렵다.<br></li>
</ul>
</li>
<li>핵심정리<ul>
<li>정적 팩터리 메서드와 public 생성자는 각자의 쓰임새가 有</li>
<li>상대적인 장단점을 이해 후 사용</li>
<li>정적 팩터리를 사용하는데 유지한 경우가 더 많으므로 무작정 public 생성자를 제공하던 습관은 고치자</li>
</ul>
</li>
</ul>
<blockquote>
<p>아이템 2) 생성자에 매개변수가 많다면 빌더를 고려하라</p>
</blockquote>
<pre><code>package step2;

// item2 : 생성자에 대한 매개변수가 많으면 빌더를 고려하라
// 빌더 패턴 - 점층적 생성자 패턴과 자바빈즈 패턴의 장점으로 형성
public class item2 {
    private final int servingSize;
    private final int servings;
    private final int carlories;
    private final int fat;
    private final int sodium;
    private final int carbohyrate;

    public static class Builder{
        // 필수 매개변수
        private final int servingSize;
        private final int servings;

        // 선택 매개변수 - 기본값으로 초기화
        private int calories = 0;
        private int fat = 0;
        private int sodium = 0;
        private int carbohydrate = 0;

        public Builder(int servingSize, int servings){
            this.servingSize = servingSize;
            this.servings =servings;
        }

        public Builder calories(int val)
        {calories = val; return this;}

        public Builder fat(int val)
        {fat = val; return this;}

        public Builder sodium(int val)
        {sodium = val; return this;}

        public Builder carbohydrate(int val)
        {carbohydrate = val; return this;}

        public item2 build(){
            return new item2(this);
        }
        private item2(Builder builder){
            servingSize = builder.servingSize;
            servings = builder.servings;
            calories = builder.calories;
            fat = builder.fat;
            sodium = builder.sodium;
            carbohydrate = builder.carbohydrate;
        }
    }
}</code></pre><ul>
<li>핵심정리<ul>
<li>생성자나 정적 팩터이가 처리해야 할 매개변수가 많다면 빌더 패턴을 선택하는 게 더 낫다.</li>
<li>매개변수 중 다수가 필수가 아니거나 같은 타입니면 특히 더 그렇다.</li>
<li>빌더는 점층적 생성자보다 클라이언트 코드를 읽고 쓰기가 더 간결하고, 자바빈즈보다 훨씬 안전하다.</li>
</ul>
</li>
</ul>
<blockquote>
<p>아이템 3) private 생성자나 열거 타입으로 싱글턴임을 보증하라</p>
</blockquote>
<ul>
<li><p>싱글턴(singleton)</p>
<ul>
<li>인스턴스를 오직 하나만 생성할 수 있는 클래스</li>
<li>클래스를 싱글턴으로 만들면 이를 사용하는 클라이언트를 테스트하기 어려워질 수 있다.</li>
</ul>
</li>
<li><p>종류 및 특징</p>
</li>
</ul>
<ol>
<li>public static final 필드 방식<ul>
<li>해당 클래스가 싱글턴임이 API에 명백히 드러난다.</li>
<li>간결하다.<pre><code>package step2;
</code></pre></li>
</ul>
</li>
</ol>
<p>// item3 : private 생성자나 열거 타입으로 싱글턴임을 보증하라</p>
<p>public class item3_1 {
    // public static final 필드 방식의 싱글턴
    public static final item3_1 INSTANCE = new item3_1();
    private item3_1(){}</p>
<pre><code>public void leaveTheBuilding(){}</code></pre><p>}</p>
<pre><code>
2. 정적 팩터리 방식
    - API를 바꾸지 않고도 싱글턴이 아니게 변경할 수 있다.
    - 정적 팩터리를 제네릭 싱글턴 팩터리로 만들수 있다.
    - 정적 팩터리의 메서드 참조를 공급자(supplier)로 사용할 수 있다.
    - 코드 예시대로라면 가짜 Elvis가 탄생한다. 가짜 Elvis를 예방하고싶다면 Evlis 클래스에 다음의 readResolve 메서드를 추가하면 된다.</code></pre><p>package step2;</p>
<p>// item3 : private 생성자나 열거 타입으로 싱글턴임을 보증하라</p>
<p>public class item3_2 {
    // 정적 팩터리 방식의 싱글턴
    public static final item3_2 INSTANCE = new item3_2();
    private item3_2(){}
    public static item3_2 getInstance(){return INSTANCE;}</p>
<pre><code>public void leaveTheBuilding(){}

// 싱글턴임을 보장해주는 readResolve 메서드
private Object readResolve(){
    // &#39;진짜&#39; item3_2를 만들고 가짜 item3_2는 GC에 맡긴다.
    return INSTANCE;
}</code></pre><p>}</p>
<pre><code>3. 열거 타입 방식</code></pre><p>package step2;</p>
<p>// item3 : private 생성자나 열거 타입으로 싱글턴임을 보증하라</p>
<p>public enum item3_3 {
    // 열거타입 방식의 싱글턴
    INSTANCE;</p>
<pre><code>public void leaveTheBuilding(){}</code></pre><p>}</p>
<pre><code>
- 핵심정리
    - 조금 부자연스러워 보일 수는 있다.
    - 대부분 상황에서는 원소가 하나뿐인 열거 타입이 싱글턴을 만드는 가장 좋은 방법이다.
    - 단, 만들려는 싱글턴이 Enum 외의 클래스를 상속해야한다면 이 방법은 사용할 수 없다.

&gt;아이템 4) 인스턴스화를 막으려거든 private 생성자를 사용하라
</code></pre><p>package step2;</p>
<p>// item 4 : 인스터스화를 막으려거든 private 생성자를 사용하라</p>
<p>// 인스턴스를 막을 수 없는 유틸리티 클래스
public class item4 {
    // 기본 생성자가 만들어지는 것을 막는다.(인스턴스화 방지용)
    private item4(){
        throw new AssertionError();
    }
    // 나머지 코드 생략
}</p>
<pre><code>- 추상 클래스로 만드는 것은 인스턴스화를 막을 수 없다.
→ 하위 클래스를 만들어 인스턴스화하면 된다.

- 해결방안 : private 생성자를 추가하면 클래스의 인스턴스화를 막을 수 있다.

&gt;아이템 5) 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라

- 사용하는 자원에 따라 동작이 달라지는 클래스에는 정적 유틸리티 클래스나 싱글턴 방식이 적합하지 않다.
- 해결방안 : 인스턴스를 생성할 때 생성자에 필요한 자원을 넘겨주는 방식을 사용한다.</code></pre><p>package step2;</p>
<p>// item5 : 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라</p>
<p>public class item5 {
    // 의존 객체 주입은 유연성과 테스트 용이성을 높여준다.
    private final Lexticon dictionary;</p>
<pre><code>public item5(Lexticon dictionary){
    this.dictionary = Objects.requireNonNull(dictionary);
}
public boolean isValid(String word){}
public List&lt;String&gt; suggestions(String typo){}</code></pre><p>}</p>
<p>```</p>
<ul>
<li>핵심정리<ul>
<li>클래스가 내부적으로 하나 이상의 자원에 의존하고, 그 자원이 클래스 동작에 영향을 준다면 싱글턴과 정적 유틸리티 클래스는 사용하지 않는 것이 좋다.</li>
<li>이 자원들을 클래스가 직접 만들게 해서도 안된다.</li>
<li>대신 자원을 생성자에 넘겨준다면 의존 객체 주입 방법은 클래스의 유연성, 재사용성, 테스트 용이성을 개선해준다.</li>
</ul>
</li>
</ul>
<p> ** 이미지출처) Google yes24</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[스프링 프레임워크 첫걸음_week 8]]></title>
            <link>https://velog.io/@tth-k/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%94%84%EB%A0%88%EC%9E%84%EC%9B%8C%ED%81%AC-%EC%B2%AB%EA%B1%B8%EC%9D%8Cweek-8</link>
            <guid>https://velog.io/@tth-k/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%94%84%EB%A0%88%EC%9E%84%EC%9B%8C%ED%81%AC-%EC%B2%AB%EA%B1%B8%EC%9D%8Cweek-8</guid>
            <pubDate>Mon, 27 Nov 2023 07:47:52 GMT</pubDate>
            <description><![CDATA[<h2 id="9장-애플리케이션-만들기ox퀴즈">9장 애플리케이션 만들기(OX퀴즈)</h2>
<h3 id="9-1-애플리케이션-설명">9-1 애플리케이션 설명</h3>
<blockquote>
<h4 id="기능-목록">기능 목록</h4>
</blockquote>
<ol>
<li><p>작성 할 기능 목록 <br></p>
<table>
<thead>
<tr>
<th align="center">NO</th>
<th align="center">기능</th>
<th align="center">설명</th>
</tr>
</thead>
<tbody><tr>
<td align="center">1</td>
<td align="center">등록</td>
<td align="center">퀴즈를 등록</td>
</tr>
<tr>
<td align="center">2</td>
<td align="center">갱신</td>
<td align="center">등록된 퀴즈를 갱신</td>
</tr>
<tr>
<td align="center">3</td>
<td align="center">삭제</td>
<td align="center">등록된 퀴즈를 삭제</td>
</tr>
<tr>
<td align="center">4</td>
<td align="center">목록 표시</td>
<td align="center">등록된 퀴즈의 목록 표시</td>
</tr>
<tr>
<td align="center">5</td>
<td align="center">게임</td>
<td align="center">퀴즈 게임 실시</td>
</tr>
<tr>
<td align="center"><br></td>
<td align="center"></td>
<td align="center"></td>
</tr>
</tbody></table>
</li>
<li><p>URL 목록</p>
<table>
<thead>
<tr>
<th align="center">NO</th>
<th align="center">역할</th>
<th align="center">HTTP메서드</th>
<th align="center">URL</th>
</tr>
</thead>
<tbody><tr>
<td align="center">1</td>
<td align="center">퀴즈 목록 표시</td>
<td align="center">GET</td>
<td align="center">/quiz</td>
</tr>
<tr>
<td align="center">2</td>
<td align="center">등록 처리 실행</td>
<td align="center">POST</td>
<td align="center">/quiz/insert</td>
</tr>
<tr>
<td align="center">3</td>
<td align="center">갱신 화면을 표시</td>
<td align="center">GET</td>
<td align="center">/quiz/{id}</td>
</tr>
<tr>
<td align="center">4</td>
<td align="center">갱신 처리를 실행</td>
<td align="center">POST</td>
<td align="center">/quiz/update</td>
</tr>
<tr>
<td align="center">5</td>
<td align="center">삭제 처리를 실행</td>
<td align="center">POST</td>
<td align="center">/quiz/delete</td>
</tr>
<tr>
<td align="center">6</td>
<td align="center">퀴즈 화면을 표시</td>
<td align="center">GET</td>
<td align="center">/quiz/play</td>
</tr>
<tr>
<td align="center">7</td>
<td align="center">퀴즈 답 체크</td>
<td align="center">POST</td>
<td align="center">/quiz/check</td>
</tr>
</tbody></table>
</li>
</ol>
<blockquote>
<h4 id="예제-애플리케이션의-레이어">예제 애플리케이션의 레이어</h4>
</blockquote>
<ol>
<li>애플리케이션 레이어<ul>
<li>클라이언트에서 받은 요청을 제어하고 도메인 레이어를 사용하여 애플리케이션을 제어<br></li>
</ul>
</li>
<li>도메인 레이어<ul>
<li>도메인 객체에 대해 애플리케이션의 서비스 처리를 실행<br></li>
</ul>
</li>
<li>인프라스트럭처 레이어<ul>
<li>도메인 객체에 대해 CRUD 조작을 해서 데이터의 영속화(데이터를 영구 저장하는)를 담당</li>
</ul>
</li>
</ol>
<blockquote>
<h4 id="레이어별-컴포넌트-설명">레이어별 컴포넌트 설명</h4>
</blockquote>
<ul>
<li>애플리케이션 레이어</li>
</ul>
<ol>
<li><p>Controller</p>
<ul>
<li>요청을 처리에 매핑하고 결과를 뷰에 넘겨주는 제어를 한다.</li>
<li>주요 처리는 Controller 안에서 실행하지 않고 &#39;도메인레이어&#39;의 Service를 호출한다.  <br></li>
</ul>
</li>
<li><p>Form</p>
<ul>
<li>화면의 폼을 표현한다.</li>
<li>화면에서 입력한 값을 Controller에 넘겨준다.</li>
<li>또한 Controller에서 화면에 결과를 출력 할 때도 사용한다.</li>
<li>도메인 레이어가 애플리케이션 레이어에 의존하지 않도록 Form에서 도메인 객체로 변환하거나 도메인 객체에서 From으로 변환하는 것을 애플리케이션에서 수행해야 한다.  <br></li>
</ul>
</li>
<li><p>View</p>
<ul>
<li><p>화면 표시를 담당한다.</p>
<br>
</li>
</ul>
</li>
</ol>
<ul>
<li>도메인 레이어</li>
</ul>
<ol>
<li>도메인 객체<ul>
<li>서비스 처리를 실행할 때 필요한 자원이다.(Entity 등)  <br></li>
</ul>
</li>
<li>Service<ul>
<li>애플리케이션의 서비스 처리를 담당한다.  <br></li>
</ul>
</li>
<li>Repository<ul>
<li>Repository는 인터페이스다.</li>
<li>데이터베이스의 데이터 조작 내용만 정의한다.(구현내용은 작성하지 않는다.)  <br>
</li>
</ul>
</li>
</ol>
<ul>
<li>인프라스트럭처 레이어</li>
</ul>
<ol>
<li>RepositoryImpl<ul>
<li>도메인 레이어에서 정의한 Repository의 구현 클래스이다.</li>
<li>&#39;O/R Mapper&#39;가 Repository의 구현클래스를 생성하는 경우도 있다.  <br></li>
</ul>
</li>
<li>O/R Mapper<ul>
<li>O(Object; 객체)와 R(Relational; 관계형 데이터베이스) 간의 데이터를 매핑한다.  <br>

</li>
</ul>
</li>
</ol>
<blockquote>
<h4 id="생성할-컴포넌트-목록">생성할 컴포넌트 목록</h4>
</blockquote>
<table>
<thead>
<tr>
<th align="center">NO</th>
<th align="center">레이어</th>
<th align="center">컴포넌트</th>
<th align="center">이름</th>
<th align="center">비고</th>
</tr>
</thead>
<tbody><tr>
<td align="center">1</td>
<td align="center">애플리케이션 레이어</td>
<td align="center">View</td>
<td align="center">-</td>
<td align="center">화면 표시</td>
</tr>
<tr>
<td align="center">2</td>
<td align="center">애플리케이션 레이어</td>
<td align="center">Controller</td>
<td align="center">QuizController</td>
<td align="center">제어 역할 담당</td>
</tr>
<tr>
<td align="center">3</td>
<td align="center">애플리케이션 레이어</td>
<td align="center">Form</td>
<td align="center">QuizForm</td>
<td align="center">화면의 게임 폼을 표현</td>
</tr>
<tr>
<td align="center">4</td>
<td align="center">도메인 레이어</td>
<td align="center">Service</td>
<td align="center">QuizService</td>
<td align="center">인터페이스로 생성</td>
</tr>
<tr>
<td align="center">5</td>
<td align="center">도메인 레이어</td>
<td align="center">ServiceImpl</td>
<td align="center">QuizServiceImpl</td>
<td align="center">Service를 구현</td>
</tr>
<tr>
<td align="center">6</td>
<td align="center">도메인 레이어</td>
<td align="center">도메인 객체</td>
<td align="center">Quiz</td>
<td align="center">엔티티 역할</td>
</tr>
<tr>
<td align="center">7</td>
<td align="center">도메인 레이어</td>
<td align="center">Repository</td>
<td align="center">QuizRepository</td>
<td align="center">인터페이스로 생성</td>
</tr>
<tr>
<td align="center">8</td>
<td align="center">인프라스트럭처 레이어</td>
<td align="center">RepositoryImpl</td>
<td align="center">-</td>
<td align="center">O/R Mapper로 자동 생성</td>
</tr>
<tr>
<td align="center">9</td>
<td align="center">인프라스트럭처 레이어</td>
<td align="center">O/R Mapper</td>
<td align="center">-</td>
<td align="center">스프링 데이터 JDBC를 사용</td>
</tr>
</tbody></table>
<h3 id="9-2-ox-퀴즈용-데이터베이스-생성---생략">9-2 OX 퀴즈용 데이터베이스 생성 -&gt; 생략</h3>
]]></description>
        </item>
        <item>
            <title><![CDATA[스프링 프레임워크 첫걸음_week 7]]></title>
            <link>https://velog.io/@tth-k/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%94%84%EB%A0%88%EC%9E%84%EC%9B%8C%ED%81%AC-%EC%B2%AB%EA%B1%B8%EC%9D%8Cweek-7</link>
            <guid>https://velog.io/@tth-k/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%94%84%EB%A0%88%EC%9E%84%EC%9B%8C%ED%81%AC-%EC%B2%AB%EA%B1%B8%EC%9D%8Cweek-7</guid>
            <pubDate>Mon, 27 Nov 2023 05:49:07 GMT</pubDate>
            <description><![CDATA[<h2 id="8장-유효성-검사-기능-알아보기">8장 유효성 검사 기능 알아보기</h2>
<h3 id="8-1-유효성-검사의-종류">8-1 유효성 검사의 종류</h3>
<blockquote>
<h4 id="유효성-검사란">유효성 검사란?</h4>
</blockquote>
<p>입력내용이 요건에 만족하는지 그 타당성을 확인하는 입력체크</p>
<ul>
<li>단일 항목 검사</li>
<li>상관 항목 검사(서로 관련이 있는 항목을 함께 체크하는 방법)</li>
</ul>
<blockquote>
<h4 id="단일-항목-검사란">단일 항목 검사란?</h4>
</blockquote>
<p>입력 항목 하나에 대해 설정하는 입력 체크 기능
from 클래스 등의 필드에 어노테이션을 부여해서 사용한다.</p>
<p>&lt;단일 항목 검사에 이용되는 주요 어노테이션&gt;</p>
<table>
<thead>
<tr>
<th align="center">어노테이션</th>
<th align="center">기능설명</th>
<th align="center">사용 예</th>
</tr>
</thead>
<tbody><tr>
<td align="center">@NotNull</td>
<td align="center">null 값이 아닌 것을 검증함</td>
<td align="center">@Notnull<br>Integer no;</td>
</tr>
<tr>
<td align="center">@NotEmpty</td>
<td align="center">문자열이 null 혹은 공백문자(&quot;&quot;)가 아닌 것을 검증함</td>
<td align="center">@NotEmpty<br>String name;</td>
</tr>
<tr>
<td align="center">@NotBlank</td>
<td align="center">문자열이 null 혹은 공백(스페이스나 탭 등)이 아닌 것을 검증함</td>
<td align="center">@NotBlank<br>String name;</td>
</tr>
<tr>
<td align="center">@Max</td>
<td align="center">지정한 숫자 이하인 것을 검증함</td>
<td align="center">#100 이하인 것을 검증<br>@Max(100)<br>Integer price;</td>
</tr>
<tr>
<td align="center">@Min</td>
<td align="center">지정한 숫자 이상인 것을 검증함</td>
<td align="center">#10 이상인 것을 검증<br>@Min(10)<br>Integer price;</td>
</tr>
<tr>
<td align="center">@Size</td>
<td align="center">문자열이나 컬렉션이 지정한 범위의 크기 내인 것을 검증</td>
<td align="center">#요소의 수가 0에서 10의 범위인 것을 검증<br>(문자열은 문자열 길이, 컬렉션은 사이즈)<br>@Size(min = 0, max = 10)<br>List &lt; Integer &gt; selected;</td>
</tr>
<tr>
<td align="center">@AssetTrue</td>
<td align="center">값이 true인 것을 검증함</td>
<td align="center">@AssetTrue<br>Boolean empty;</td>
</tr>
<tr>
<td align="center">@AssertFalse</td>
<td align="center">값이 false인 것을 검증함</td>
<td align="center">@AssertFalse<br>Boolen empty;</td>
</tr>
<tr>
<td align="center">@Pattern</td>
<td align="center">지정한 정규 표현과 일치하는 것을 검증함</td>
<td align="center">#영숫자 검증<br>@Pattern(regexp)&quot;[a-Za-Z0-9]*&quot;)*</td>
</tr>
<tr>
<td align="center">@Range</td>
<td align="center">지정한 숫자 범위 안에 있는 것을 검증</td>
<td align="center">#1이상, 10이하 인것을 검증<br>@Range min = 1, max = 10)<br>Integer point;</td>
</tr>
<tr>
<td align="center">@Decimal<br>Max</td>
<td align="center">지정한 숫자 이하인 것을 검증</td>
<td align="center">#100.0 이하 검증(소수점 이하를 포함해서 검증할 때는<br>MAX가 아니고DecimalMax를 사용@DecimalMax(&quot;100.0&quot;)<br>BigDecimal val;</td>
</tr>
<tr>
<td align="center">@Decimal<br>Min</td>
<td align="center">지정한 숫자 이상인 것을 검증</td>
<td align="center">#10.0 이상 검증(소수점 이하를 포함해서 검증할 때는<br>Min이 아니라 DecimalMin를 사용<br>@DecimalMin(&quot;10.0&quot;)<br>BigDecimal val;</td>
</tr>
<tr>
<td align="center">@Digits</td>
<td align="center">정수부와 소수부의 자릿수 검증</td>
<td align="center">#정수부가 3, 소수부가 1인것을 검증<br>@Digits(integer = 3, fraction = 1)<br>BigDcimal val;</td>
</tr>
<tr>
<td align="center">@Future</td>
<td align="center">미래의 날짜인 것을 검증</td>
<td align="center">@Future<br>Date date;</td>
</tr>
<tr>
<td align="center">@Past</td>
<td align="center">과거의 날짜인 것을 검증</td>
<td align="center">@Past<br>Date date;</td>
</tr>
<tr>
<td align="center">@Vaild</td>
<td align="center">중첩된 form을 검증</td>
<td align="center">@Vaild<br>SampleForm sampleForm;</td>
</tr>
<tr>
<td align="center">@Length</td>
<td align="center">문자열 길이가 지정한 범위 안에 있는 것을 검증<br>(문자열 전용 size)</td>
<td align="center">@Length(min = 0, max = 10)<br>String name;</td>
</tr>
<tr>
<td align="center">@Email</td>
<td align="center">문자열이 이메일 주소 형식인지 검증</td>
<td align="center">@Email<br>String email;</td>
</tr>
<tr>
<td align="center">@CreditCard<br>Number</td>
<td align="center">문자열이 신용카드 번호 형식인지 검증</td>
<td align="center">@CreditCardNumber<br>String card;</td>
</tr>
<tr>
<td align="center">@URL</td>
<td align="center">문자열이 URL 형식인지 검증</td>
<td align="center">@URL<br>String url;</td>
</tr>
</tbody></table>
<br>

<p>&lt;null 체크 어노테이션&gt;</p>
<table>
<thead>
<tr>
<th align="center">어노테이션</th>
<th align="center">null인 경우</th>
<th align="center">공백 문자(&quot;&quot;)인 경우</th>
<th align="center">스페이스나 탭인 경우</th>
<th align="center">타입(용도)</th>
</tr>
</thead>
<tbody><tr>
<td align="center">@NotNull</td>
<td align="center">체크 에러</td>
<td align="center">허가</td>
<td align="center">허가</td>
<td align="center">Integer</td>
</tr>
<tr>
<td align="center">@NotEmpty</td>
<td align="center">체크 에러</td>
<td align="center">체크에러</td>
<td align="center">허가</td>
<td align="center">컬렉션, 문자열, 배열용</td>
</tr>
<tr>
<td align="center">@NotBlank</td>
<td align="center">체크 에러</td>
<td align="center">체크에러</td>
<td align="center">체크에러</td>
<td align="center">컬렉션, 문자열, 배열용</td>
</tr>
</tbody></table>
<blockquote>
<h4 id="커스텀-유효성-검사란">커스텀 유효성 검사란?</h4>
</blockquote>
<p>단일 항목 검사는 하나의 필드를 체크한다.
여러 필드에 대해 혼합해서 체크하는 것을 상관 항목(서로 관련이 있는 항목) 검사라고 한다.</p>
<p>상관 항목 검사 종류</p>
<ul>
<li>Bean Validation을 사용하는 방법</li>
<li>스프링 프레임워크에서 제공하는 Validator 인터페이스를 구현하는 방법</li>
</ul>
<h3 id="8-2-단일-항목-검사를-사용하는-프로그램-만들기---생략">8-2 단일 항목 검사를 사용하는 프로그램 만들기 -&gt; 생략</h3>
<h3 id="8-3-메세지-관리에-대해-알아보기---생략">8-3 메세지 관리에 대해 알아보기 -&gt; 생략</h3>
<h3 id="8-4-커스텀-유효성-검사기를-사용하는-프로그램-만들기---생략">8-4 커스텀 유효성 검사기를 사용하는 프로그램 만들기 -&gt; 생략</h3>
]]></description>
        </item>
        <item>
            <title><![CDATA[스프링 프레임워크 첫걸음_week 6]]></title>
            <link>https://velog.io/@tth-k/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%94%84%EB%A0%88%EC%9E%84%EC%9B%8C%ED%81%AC-%EC%B2%AB%EA%B1%B8%EC%9D%8Cweek-6</link>
            <guid>https://velog.io/@tth-k/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%94%84%EB%A0%88%EC%9E%84%EC%9B%8C%ED%81%AC-%EC%B2%AB%EA%B1%B8%EC%9D%8Cweek-6</guid>
            <pubDate>Mon, 27 Nov 2023 04:20:52 GMT</pubDate>
            <description><![CDATA[<h2 id="7장-요청-파라미터-취득하기">7장 요청 파라미터 취득하기</h2>
<h3 id="7-1-요청-파라미터의-종류">7-1 요청 파라미터의 종류</h3>
<blockquote>
<h4 id="요청-파라미터란">요청 파라미터란?</h4>
</blockquote>
<p>서버에 전송되는 값을 요청 파라미터(request parameter)라고 한다.</p>
<ul>
<li>요청 파라미터의 종류<ul>
<li>요청 쿼리 스트링(query string)으로 보내지는 값(GET으로 서버로 데이터 전송)</li>
<li>요청 본문(body)에 저장되어 보내지는 값(POST로 서버로 데이터 전송)
※ 내용 : 뷰에서 입력값 및 선택한 값이나  숨김 파라미터 등에서 미리 뷰에 입력해둔 값 등</li>
<li>뷰에서 클릭한 버튼의 name 속성 값
※ 내용 : 하나의 뷰에 버튼이 여러 개 있을 때 어느 버튼인지 판별할 수 있는 값</li>
<li>URL 경로(path)의 일부로 보내지는 값
※ 내용 : 링크 등으로 URL의 일부로 보내지는 값</li>
</ul>
</li>
</ul>
<blockquote>
<h4 id="요청-파라미터의-취득-방법">요청 파라미터의 취득 방법</h4>
</blockquote>
<ul>
<li><p>@RequestParam 사용</p>
<ul>
<li>@RequestParam 어노테이션을 이용해 파라미터를 하나씩 취득</li>
</ul>
</li>
<li><p>From 클래스 사용(From 클래스는 따로 만들어야 함)</p>
<ul>
<li>스프링 MVC가 form 클래스 내의 필드에 대해 값을 저장한다.</li>
<li>요청 파라미터를 모아서 하나의 객체로 받아들이기 때문에 자주 사용되는 방법이다.</li>
<li>받을 때는 &#39;형변환&#39;이나 &#39;포맷 지정&#39;이 가능하다.</li>
</ul>
</li>
</ul>
<h3 id="7-2-입력값을-받는-프로그램-만들기requestparam---생략">7-2 입력값을 받는 프로그램 만들기(@RequestParam) -&gt; 생략</h3>
<h3 id="7-3-입력값을-받는-프로그램-만들기from-클래스---생략">7-3 입력값을 받는 프로그램 만들기(From 클래스) -&gt; 생략</h3>
<h3 id="7-4-url에-포함된-값을-받는-프로그램-만들기---생략">7-4 URL에 포함된 값을 받는 프로그램 만들기 -&gt; 생략</h3>
]]></description>
        </item>
        <item>
            <title><![CDATA[스프링 프레임워크 첫걸음_week 5]]></title>
            <link>https://velog.io/@tth-k/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%94%84%EB%A0%88%EC%9E%84%EC%9B%8C%ED%81%AC-%EC%B2%AB%EA%B1%B8%EC%9D%8Cweek-5</link>
            <guid>https://velog.io/@tth-k/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%94%84%EB%A0%88%EC%9E%84%EC%9B%8C%ED%81%AC-%EC%B2%AB%EA%B1%B8%EC%9D%8Cweek-5</guid>
            <pubDate>Wed, 15 Nov 2023 07:05:52 GMT</pubDate>
            <description><![CDATA[<h2 id="5장-mvc-모델-알아보기">5장 MVC 모델 알아보기</h2>
<h3 id="5-1-mvc-모델-알아보기">5-1 MVC 모델 알아보기</h3>
<blockquote>
<h4 id="mvc-모델이란">MVC 모델이란?</h4>
</blockquote>
<ul>
<li><p>MVC 모델이란 &#39;프로그램의 처리 역할을 나누어서 프로그램을 작성하는 방법&#39;으로 웹 시스템 개발에 자주 사용되고 있다.</p>
</li>
<li><p>역할 종류</p>
<ul>
<li>M : 모델(Model)</li>
<li>V : 뷰(View)</li>
<li>C : 컨트롤러(Controller)</li>
</ul>
</li>
<li><p>모델(Model: M)</p>
<ul>
<li>시스템에서 비즈니스 로직을 담당한다.</li>
<li>비즈니스 로직이란 시스템의 코어 부분 혹은 시스템의 목적을 처리하는 부분 등으로 해석할 수 있다.</li>
<li>예시) 회원가입시 아이디의 중복확인, 본인인증, 비밀번호 규칙 확인 등</li>
</ul>
</li>
<li><p>뷰(View: V)</p>
<ul>
<li>한마디로 설명하면 &#39;외형&#39;이다.</li>
<li>사용자 입력과 결과 출력 등 시스템에서 표현 부분을 담당하며 웹 애플리케이션에서는 주로 화면을 담당한다.</li>
</ul>
</li>
<li><p>컨트롤러(Controller: C)</p>
<ul>
<li>서비스 처리를 담당하는 모델과 화면 표시를 담당하는 뷰를 제어하는 역할을 한다.</li>
<li>사용자가 입력한 내용을 뷰에서 받고 받은 데이터를 기준으로 모델에 내용을 전달한다.</li>
<li>모델에서 받은 데이터를 뷰에 전달해서 화면에 표시하는 역할을 한다.</li>
</ul>
</li>
</ul>
<blockquote>
<h4 id="mvc-모델의-개요와-이점">MVC 모델의 개요와 이점</h4>
</blockquote>
<ul>
<li>이점<ul>
<li>역할 분담을 통해 효율적인 개발 가능</li>
<li>개발하는 엔지니어의 분업화가 용이</li>
<li>설계 변경에 유연하게 대응 가능</li>
</ul>
</li>
</ul>
<h3 id="5-2-스프링-mvc-알아보기">5-2 스프링 MVC 알아보기</h3>
<blockquote>
<h4 id="스프링-mvc란">스프링 MVC란?</h4>
</blockquote>
<ul>
<li><p>웹 애플리케이션을 간단하게 만들 수 있는 기능을 제공하는 프레임워크</p>
</li>
<li><p>주요 기능 : 화면 전환, 사용자가 사용하는 브라우저와 서버 간의 입출력 데이터 전달을 단순화하는 등</p>
</li>
<li><p>구성요소</p>
<ul>
<li>DispatcherServlet : 모든 요청을 수신하는 프런트 컨트롤러</li>
<li>Model : 컨트롤러에서 뷰에 넘겨주는 표시용 데이터 등을 저장하는 객체</li>
<li>컨트롤러 : 요청에 대응해서 처리할 내용이 있는 곳</li>
<li>서비스 처리 : 데이터베이스에 접속해서 데이터를 취득하거나 데이터를 가공하는 등 여러 가지 작업을 실행, 개발자가 설계하고 구현한다.
(※ 스프링 MVC와 관계없음)</li>
<li>뷰 : 화면 표시 처리를 합니다(구체적으로는 JSP 등의 처리)</li>
</ul>
</li>
</ul>
<blockquote>
<h4 id="요청을-받고-응답을-보낼-때까지의-흐름">요청을 받고 응답을 보낼 때까지의 흐름</h4>
</blockquote>
<ol>
<li><p>모든 요청을 수신하는 프런트 컨트롤러인 DispatcherServlet이 클라이언트로부터 요청을 수신한다.</p>
</li>
<li><p>DispatcherServlet이 컨트롤러의 요청 핸들러 메서드를 호출한다.</p>
</li>
<li><p>컨트롤러는 비즈니스 로직 처리를 호출하고, 처리 결과를 받는다.</p>
</li>
<li><p>처리 결과를 모델로 설정하고, 뷰 이름을 반환한다.</p>
</li>
<li><p>반환된 뷰 이름을 받아 DispatcherServlet이 뷰 이름에 대응하는 뷰에 대해 화면 표시 처리를 의뢰한다.</p>
</li>
<li><p>클라이언트가 응답을 받고 브라우저에 화면이 표시된다.</p>
</li>
</ol>
<p>과정이 복잡해보이지만 번거로운 처리는 스프링 MVC가 담당하기 때문에 실제로 작성하는 부분은 컨트롤러, 비즈니스 로직 처리, 뷰의 세 가지뿐인것을 알 수 있다.</p>
<h3 id="5-3-스프링-mvc-사용해보기---생략">5-3 스프링 MVC 사용해보기 -&gt; 생략</h3>
]]></description>
        </item>
        <item>
            <title><![CDATA[스프링 프레임워크 첫걸음_week 4]]></title>
            <link>https://velog.io/@tth-k/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%94%84%EB%A0%88%EC%9E%84%EC%9B%8C%ED%81%AC-%EC%B2%AB%EA%B1%B8%EC%9D%8Cweek-4</link>
            <guid>https://velog.io/@tth-k/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%94%84%EB%A0%88%EC%9E%84%EC%9B%8C%ED%81%AC-%EC%B2%AB%EA%B1%B8%EC%9D%8Cweek-4</guid>
            <pubDate>Fri, 10 Nov 2023 02:13:03 GMT</pubDate>
            <description><![CDATA[<h2 id="4장-데이터베이스-작업">4장 데이터베이스 작업</h2>
<h3 id="4-1-데이터베이스-생성">4-1 데이터베이스 생성</h3>
<blockquote>
<h4 id="데이터베이스란">데이터베이스란?</h4>
</blockquote>
<ul>
<li><p>데이터베이스(DataBase)란 데이터를 보관하기 위한 &#39;상자&#39;라고 볼 수 있다.</p>
</li>
<li><p>데이터베이스에서 데이터를 모을 때는 특정한 규칙을 적용 후 데이터를 정리해서 보관한다.</p>
</li>
<li><p>데이터베이스 = DB</p>
</li>
</ul>
<blockquote>
<h4 id="관계형-데이터베이스란">관계형 데이터베이스란?</h4>
</blockquote>
<ul>
<li><p>관계형 데이터베이스(Relational DataBase)는 데이터를 표 형식으로 표현하고, 여러 표에서 항목의 값 사이에 관계를 맺고 있는 데이터베이스를 말한다.</p>
</li>
<li><p>표 = 테이블(Table)</p>
</li>
<li><p>테이블과 테이블 사이의 관계 = Relationship</p>
</li>
<li><p>관계형 데이터베이스는 가장 일반적으로 사용되는 데이터베이스라 줄여서
RDB로 불린다.</p>
</li>
</ul>
<blockquote>
<h4 id="postgresql로-데이터베이스-확인---생략">PostgreSQL로 데이터베이스 확인 -&gt; 생략</h4>
</blockquote>
<h3 id="4-2-테이블-생성">4-2 테이블 생성</h3>
<blockquote>
<h4 id="테이블이란">테이블이란?</h4>
</blockquote>
<ul>
<li><p>위에서 테이블은 데이터를 보관하기 위한 상자라고 설명했지만,</p>
</li>
<li><p><em>데이터베이스 안에서 실제로 규칙을 가진 데이터가 저장 되는 상자라고 한다.*</em></p>
</li>
<li><p>테이블은 데이터를 항목으로 해서 이차원 표 형식으로 정리해서 저장한다.</p>
</li>
</ul>
<blockquote>
<h4 id="레코드와-칼럼">레코드와 칼럼</h4>
</blockquote>
<ul>
<li>테이블의 가로 행(row) = 레코드(record)</li>
<li>하나의 레코드 = 한 건의 데이터</li>
<li>테이블의 세로(column) = 칼럼(column)</li>
<li>하나의 칼럼 = 데이터의 각 요소</li>
</ul>
<blockquote>
<h4 id="pdadmin-4로-테이블-생성---생략">pdAdmin 4로 테이블 생성 -&gt; 생략</h4>
</blockquote>
<h3 id="4-3-데이터-입력">4-3 데이터 입력</h3>
<blockquote>
<h4 id="sql이란">SQL이란?</h4>
</blockquote>
<ul>
<li><p>SQL은 데이터베이스를 조작하기 위한 언어이다.</p>
</li>
<li><p>정식 명칭 : Structured Query Language</p>
</li>
<li><p>CRUD란?</p>
<ul>
<li>영속적으로 데이터를 취급하는 4개의 기본적인 기능의 앞글자를 따서 만든 단어이다.</li>
<li>Create : 생성</li>
<li>Read : 읽기</li>
<li>Update : 갱신</li>
<li>Delete : 삭제</li>
</ul>
</li>
<li><p>CRUD 명령어, 구문</p>
<ul>
<li>Create : INSERT INTO 테이블명(칼럼명, 칼럼명...) VALUES(값, 값...)<ul>
<li>Read : SELECT 칼럼명 FROM 테이블명;</li>
</ul>
</li>
<li>Update : UPDATAE 테이블명 SET 칼럼명 = 값 WHERE 갱신할_레코드를_특정하는_조건;
※ WHERE로 조건을 지정하지 않는 경우 모든 레코드가 대상이 된다.</li>
<li>Delete : DELETE FROM 테이블명 WHERE 삭제할_레코드를_특정하는_조건;
※ WHERE로 조건을 지정하지 않는 경우 모든 레코드가 대상이 된다.</li>
</ul>
</li>
</ul>
<blockquote>
<h4 id="테이블에-데이터-입력---생략">테이블에 데이터 입력 -&gt; 생략</h4>
</blockquote>
<h3 id="4-4-엔티티와-리포지토리-알아보기">4-4 엔티티와 리포지토리 알아보기</h3>
<blockquote>
<h4 id="엔티티란">엔티티란?</h4>
</blockquote>
<ul>
<li><p>엔티티를 한마디로 표현하면 &#39;데이터를 담아두는 객체&#39;이다.</p>
</li>
<li><p>데이터베이스 테이블의 한 행(레코드)에 대응하는 객체이다.</p>
</li>
<li><p>엔티티의 필드는 테이블의 한 열(칼럼)에 대응한다.</p>
</li>
<li><p>엔티티는 실제 데이터를 담아 두는 개체이다. 사용할 때 다음 세 가지를 기억하자</p>
<ul>
<li>클래스명 : 클래스명은 대응하는 데이터베이스의 테이블명으로 하는 경우가 많다.</li>
<li>데이터 베이스에 값 넘겨주기 : 데이터베이스에 값을 등록/갱신하는 경우에는 엔티티에 값을 넣어서 넘겨준다.</li>
<li>데이터베이스에서 값 가져오기 : 데이터베이스에서 값을 가져오는 경우에는 값을 엔티티에 넣어서 가져온다.</li>
</ul>
</li>
</ul>
<blockquote>
<h4 id="리포지토리repository란">리포지토리(Repository)란?</h4>
</blockquote>
<ul>
<li><p>Repository = 데이터베이스를 조작하는 class</p>
</li>
<li><p>리포지토리를 생성하려면 반드시 인터페이스를 정의하고 구현해야한다.</p>
<ul>
<li>이유) 리포지토리 인터페이스의 필드에 리포지토리 구현 클래스를 DI하여 특정 구현에 의존하는 것을 피할 수 있기 때문이다.</li>
</ul>
</li>
<li><p>참고) 자바에서는 인터페이스를 구현한 클래스의 점미사에 &#39;Impl&#39;을 붙이는 경우가 많다.(Impl = implements의 약자)</p>
</li>
</ul>
<h3 id="4-5-스프링-데이터-jdbc-사용해보기">4-5 스프링 데이터 JDBC 사용해보기</h3>
<blockquote>
<h4 id="or-매퍼란">O/R 매퍼란?</h4>
</blockquote>
<ul>
<li><p>간단하게 설명하면 애플리케이션에서 사용하는 O(Object) : &#39;객체&#39;와 R(Relational): &#39;관계형 데이터베이스&#39;의 데이터를 매핑하는 것이다.</p>
</li>
<li><p>O/R 매퍼는 미리 설정된 객체와 관계형 데이터베이스 간의 대응 관계 정보를 가지고 인터페이스의 데이터에 대응하는 테이블에 내보내거나
데이터 베이스에서 값을 읽어 들여 인터페이스에 대입하는 작업을 자동으로 실행한다.</p>
</li>
</ul>
<blockquote>
<h4 id="스프링-데이터-jdbc란">스프링 데이터 JDBC란?</h4>
</blockquote>
<ul>
<li><p>스프링 데이터 JDBC = O/R 매퍼</p>
</li>
<li><p>스프링 데이터가 제공하는 CrudRepository를 상속해서 자동으로 CRUD를 지원하는 메서드를 사용할 수 있다.</p>
</li>
</ul>
<blockquote>
<h4 id="스프링-데이터-jdbc-프로그램-생성---생략">스프링 데이터 JDBC 프로그램 생성 -&gt; 생략</h4>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[스프링 프레임워크 첫걸음_week 3]]></title>
            <link>https://velog.io/@tth-k/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%94%84%EB%A0%88%EC%9E%84%EC%9B%8C%ED%81%AC-%EC%B2%AB%EA%B1%B8%EC%9D%8Cweek-3</link>
            <guid>https://velog.io/@tth-k/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%94%84%EB%A0%88%EC%9E%84%EC%9B%8C%ED%81%AC-%EC%B2%AB%EA%B1%B8%EC%9D%8Cweek-3</guid>
            <pubDate>Wed, 08 Nov 2023 06:47:45 GMT</pubDate>
            <description><![CDATA[<h2 id="3장-스프링프레임워크의-핵심-기능-알아보기">3장 스프링프레임워크의 핵심 기능 알아보기</h2>
<h3 id="3-1-스프링-프레임워크의-핵심-기능">3-1 스프링 프레임워크의 핵심 기능</h3>
<blockquote>
<h4 id="의존성-주입_첫번째-기능">의존성 주입_첫번째 기능</h4>
</blockquote>
<p>Dependency Injection으로 약어는 DI,
의존성 주입은 &#39;의존하는 부분을 외부에서 주입하는 것&#39;이다.</p>
<p>다시 말하자면 &#39;DI는 프로그램에서 의존 부분을 외부에서 주입한다&#39;로 이해하면 된다.</p>
<blockquote>
<h4 id="관점-지향-프로그래밍_두번째-기능">관점 지향 프로그래밍_두번째 기능</h4>
</blockquote>
<p>Aspect Oriented Programming으로 약어는 AOP,
AOP는 다음 두 가지 요소로 구성된다.</p>
<ul>
<li>중심적 관심사(Primary Concern) : 실현해야 할 가능을 나타내는 프로그램</li>
<li>횡된적 관심사(Crosscultting-Concerns) : 본질적인 기능은 아니지만 품질이나 유지보수 등의 관점에서 반드시 필요한 기능을 나타내는 프로그램</li>
</ul>
<p>간단히 설명하면 공통 처리 등의 &#39;횡단적 관심사&#39;를 추출하고 프로그램의 여러 곳에서 호출할 수 있게 설정함으로써 개발자는 실현해야 할 기능인</p>
<p>&#39;중심적 관심사&#39;에만 집중해서 작성하면 되는 구조이다.</p>
<h3 id="3-2-di-컨테이너-알아보기">3-2 DI 컨테이너 알아보기</h3>
<blockquote>
<h4 id="의존성">의존성</h4>
</blockquote>
<p>어떤 프로그램에 &#39;사용하는 객체&#39;와 &#39;사용되는 객체&#39;의 관계가 있다고 가정해보자</p>
<ul>
<li>사용하는 객체 : A클래스</li>
<li>사용되는 객체 : B클래스</li>
</ul>
<p>A클래스에서 B클래스를 사용하려면 new 키워드를 이용해 B클래스의 인스턴스를 생성하고 B클래스의 메서드를 사용하게 된다.</p>
<p>이때 B클래스에서 구현했던 메서드를 변경하면 그 영향으로 A클래스에서도 메서드를 변경해야한다.</p>
<p>이런 관계를 <strong>&#39;A클래스는 B클래스에 의존한다&#39;</strong> 라고 한다.</p>
<p>의존성 유형</p>
<ul>
<li>클래스 의존(구현 의존)</li>
<li>인터페이스 의존</li>
</ul>
<blockquote>
<h4 id="클래스-의존">클래스 의존</h4>
</blockquote>
<ul>
<li>사용하는 객체 : A클래스</li>
<li>사용되는 객체 : B클래스</li>
</ul>
<p>가정 1) A클래스에서 B클래스의 methodX 메서드를 호출</p>
<p>변경사항) 설계가 변경돼서 &#39;사용되는 객체&#39;를 새롭게 생성된 C클래스로 변경하고 methodY 메서드를 호출하도록 변경해야함</p>
<p>수정사항) A클래스에서 기존 B클래스가 아닌 C클래스 요소로 전부 수정해야함</p>
<p>이렇게 가정 1 처럼 &#39;사용하는 객체&#39; 클래스에서 &#39;사용되는 객체&#39; 클래스 타입을 직접 지정해버리면 &#39;사용되는 객체&#39; 클래스를 변경 할 경우</p>
<p><strong>이를 사용하고 있는 곳을 모두 수정해야한다.</strong></p>
<p>이러한 요소가 한두 군데라면 문제가 없지만 10군데, 100군데 그 이상이 있을 경우 수정 작업과 수정에 의한 테스트 작업이 엄청 늘어난다.</p>
<blockquote>
<h4 id="인터페이스-의존">인터페이스 의존</h4>
</blockquote>
<ul>
<li>사용하는 객체 : A클래스</li>
<li>사용되는 객체 : B클래스</li>
</ul>
<p>가정 2) I 인터페이스가 있고 그것을 구현한 B클래스가 있다. A클래스에서 B클래스의 methodX를 호출한다.</p>
<p>주의할 점) A클래스에서는 인터페이스로 추상화된 I를 이용한다.</p>
<p>변경사항) 설계가 변경돼서 &#39;사용되는 객체&#39;를 새롭게 생성된 C클래스로 변경하고 methodX 메서드를 호출하도록 변경해야함</p>
<p>수정사항) 클래스 의존과 다르게 A클래스의 한 곳만 수정하면 된다.</p>
<p>장점</p>
<ul>
<li>인터페이스는 참조를 받는 유형으로 사용할 수 있으므로 <strong>변수의 이름을 변경하지 않아도 된다.</strong></li>
<li>인터페이스가 선언된 메서드를 이용하면 클래스가 바뀌어도 <strong>메서드명을 변경하지 않아도 된다.</strong></li>
</ul>
<blockquote>
<h4 id="인터페이스에-의존하는-프로그램-만들기---생략">인터페이스에 의존하는 프로그램 만들기 -&gt; 생략</h4>
</blockquote>
<blockquote>
<h4 id="di-컨테이너">DI 컨테이너</h4>
</blockquote>
<ul>
<li>의존하는 부분이란 &#39;사용하는 객체&#39; 클래스에 &#39;사용되는 객체&#39; 클래스가 작성된 상태이다.</li>
<li>외부로부터 주입이란 &#39;사용하는 객체&#39; 클래스 밖에서 &#39;사용되는 객체&#39; 인스턴스를 주입하는 것이다.</li>
</ul>
<p>지금까지는 인스턴스를 생성하는데 new 키워드를 사용했지만 인스턴스 생성과 같은 작업을 프레임워크에 맡길 수 있고 그 역할을 하는 것이 DI컨테이너이다.</p>
<p>스프링 프레임워크는 임의로 구현한 클래스를 인스턴스로 만들어주는 기능을 제공한다.</p>
<blockquote>
<h4 id="다섯-가지-규칙">다섯 가지 규칙</h4>
</blockquote>
<ol>
<li>인터페이스를 이용하여 의존성을 만든다.</li>
<li>인스턴스를 명시적으로 생성하지 않는다.</li>
<li>어노테이션을 클래스에 부여한다.</li>
<li>스프링 프레임워크에서 인스턴스를 생성한다.</li>
<li>인스턴스를 이용하고 싶은 곳에 어노테이션을 부여한다.</li>
</ol>
<blockquote>
<h4 id="di-프로그램-만들기---생략">DI 프로그램 만들기 -&gt; 생략</h4>
</blockquote>
<h3 id="3-3-어노테이션-역할-알아보기">3-3 어노테이션 역할 알아보기</h3>
<blockquote>
<h4 id="어노테이션을-세-가지-항목으로-설명">어노테이션을 세 가지 항목으로 설명</h4>
</blockquote>
<ol>
<li>어노테이션(annotation)은 주석을 의미하는 영어표현이다.</li>
<li>&#39;@xxx&#39;와 같은 형태로 작성한다.</li>
<li>외부 소프트웨어에 필요한 처리 내용을 전달한다.</li>
</ol>
<blockquote>
<h4 id="레이어별로-사용할-인스턴스-생성-어노테이션">레이어별로 사용할 인스턴스 생성 어노테이션</h4>
</blockquote>
<p>애플리케이션을 만들 때는 레이어로 나누는 것이 좋다.
레이어(Layer)는 &#39;층&#39;이라는 의미로, 계층 구조로 되어 있는 각 층을 말한다.</p>
<p>쉽게 설명하자면 복잡한 전체 내용을 한 번에 정리해 이해하지 말고 계층화 해
각 계층별로 대상의 의미를 이해하는 것이다.</p>
<ul>
<li>&#39;도메인 주도 설계&#39;(Domain-Driven Design) 레이어 종류<ul>
<li>애플리케이션 레이어 : 애플리케이션 레이어는 클라이언트와의 데이터 입출력을 제어하는 레이어이다.</li>
</ul>
</li>
</ul>
<ul>
<li><p>도메인 레이어 : 도메인 레이어는 애플리케이션의 중심이 되는 레이어로서 업무 처리를 수행하는 레이어이다.</p>
</li>
<li><p>인프라스트럭처 레이어 : 인프라스트럭처 레이어는 데이터베이스에 대한 데이터 영속성 등을 담당하는 레이어이다.</p>
</li>
<li><p>레이어별 인스턴스 생성 어노테이션 설명
  &lt;주요처리&gt;</p>
<ul>
<li>@Controller : 애플리케이션 레이어의 컨트롤러에 부여</li>
<li>@Service : 도메인 레이어의 업무 처리에 부여</li>
<li>@Repository : 인프라 레이어의 데이터베이스 액세스 처리에 부여
&lt;보조처리&gt;</li>
<li>@Compoenet : @Controller, @Service, @Repository의 용도 이외의 인스턴스 생성 대상 클래스의 부여, 하위 로직을 처리할 때 사용</li>
</ul>
</li>
</ul>
<blockquote>
<h4 id="커스텀-어노테이션">커스텀 어노테이션</h4>
</blockquote>
<ul>
<li>커스텀 어노테이션을 만들 때는 jav.lang.Annotation 인터페이스를 상속하고 만든다.</li>
<li>커스텀 어노테이션을 정의할 때는 전용 자바 파일을 생성할 필요가 있다.</li>
</ul>
<h3 id="3-4-aop관점-지향-프로그래밍의-기초지식">3-4 AOP(관점 지향 프로그래밍)의 기초지식</h3>
<blockquote>
<h4 id="aop-예제">AOP 예제</h4>
</blockquote>
<p>데이터베이스 액세스 처리에는 예외 발생 시 처리하는 내용이 반드시 포함되어야한다.</p>
<p>&#39;구현하고 싶은 프로그램 = 중심적 관심사&#39;
&#39;부수적 프로그램 = 횡단적 관심사&#39;</p>
<p>위 2개로 분리하여 프로그램을 작성하는 법을 알아보겠다.</p>
<ul>
<li>AOP의 고유 용어</li>
</ul>
<ol>
<li><p>어드바이스(Advice) : 횡단적 관심사의 구현, 로그 출력 및 트랙잭션 제어</p>
</li>
<li><p>에스팩트(Aspect) : 어드라이스를 정리한 것(클래스)</p>
</li>
<li><p>조인포인트(JoinPoint) : 어드바이스를 중심적인 관심사에 적용하는 타이밍. 메서드 실행 전, 메서드 실행 후 등 실행되는 타이밍</p>
</li>
<li><p>포인트컷(Pointcut): 어드바이스를 삽입할 수 있는 위치</p>
</li>
<li><p>인터셉터(Interceptor) : 처리의 제어를 인터셉트하기 위한 구조 또는 프로그램</p>
</li>
<li><p>타깃(Target) : 어드바이스가 도입되는 대상</p>
</li>
</ol>
<ul>
<li>어드바이스의 다섯 가지 종류(어드바이스 이름은 어노테이션과 동일하다)</li>
</ul>
<ol>
<li><p>@Before : 중심적 관심사가 실행되기 이전에 횡단적 관심사를 싱행</p>
</li>
<li><p>@AfterReturning : 중심적 관심사가 정상적으로 종료된 후에 횡단적 관심사를 실행</p>
</li>
<li><p>@AfterThrowing : 중심적 관심사로부터 예외가 던져진 후로 횡단적 관심사를 실행</p>
</li>
<li><p>@After : 중심적 관심사의 실행 후에 횡단적 광심사를 실행</p>
</li>
<li><p>@Around : 중심적 관심사가 호출 전후에 횡단적 관심사를 실행</p>
</li>
</ol>
<blockquote>
<h4 id="포인트컷-식">포인트컷 식</h4>
</blockquote>
<ul>
<li><p>execution 지시자의 구문
  <strong>execute(반환값 패키지.클래스,메서드(인수))</strong></p>
</li>
<li><p>와일드 카드</p>
</li>
</ul>
<ol>
<li><p>*(애스터리스크) : 임의의 문자열, 임의의 패키지 한 계층</p>
</li>
<li><p>. .(점두개) : 패키지의 경우 0개 이상의 패키지, 인수의 경우 0개 이상의 인수</p>
</li>
<li><p>+(플러스) : 클래스명 뒤에 기술해 클래스와 그 서브클래스 및 구현 클래스를 모두 나타낸다.</p>
</li>
</ol>
<blockquote>
<h4 id="aop-프로그램-만들기---생략">AOP 프로그램 만들기 -&gt; 생략</h4>
</blockquote>
<blockquote>
<h4 id="요약">요약</h4>
</blockquote>
<ol>
<li><p>AOP에서는 프로그램을 2개의 요소인 중심적 관심사와 횡단적 관심사로 구성되어 있다고 생각한다.</p>
</li>
<li><p>중심적 관심사란 구현해야 할 기능, 비즈니스 로직을 말한다.</p>
</li>
<li><p>횡단적 관심사란 품질이나 유지보수 등의 관점에서 꼭 필요한 기능이다.</p>
</li>
<li><p>AOP에서 횡단적 관심사를 분리함으로써 기존 코드를 수정하지 않아도 프로그램 중에 특정 기능(공통 처리)을 추가할 수 있다.</p>
</li>
<li><p>스프링 프레임워크는 다양한 공통 기능을 AOP에서 제공한다.</p>
</li>
</ol>
<h3 id="3-5-spring-initializr-알아보기---생략">3-5 Spring Initializr 알아보기 -&gt; 생략</h3>
]]></description>
        </item>
        <item>
            <title><![CDATA[스프링 프레임워크 첫걸음_week 2]]></title>
            <link>https://velog.io/@tth-k/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%94%84%EB%A0%88%EC%9E%84%EC%9B%8C%ED%81%AC-%EC%B2%AB%EA%B1%B8%EC%9D%8Cweek-2</link>
            <guid>https://velog.io/@tth-k/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%94%84%EB%A0%88%EC%9E%84%EC%9B%8C%ED%81%AC-%EC%B2%AB%EA%B1%B8%EC%9D%8Cweek-2</guid>
            <pubDate>Sun, 29 Oct 2023 14:48:20 GMT</pubDate>
            <description><![CDATA[<h2 id="2장-기초-지식-배우기">2장 기초 지식 배우기</h2>
<h3 id="2-1-자바-기초-지식-복습">2-1 자바 기초 지식 복습</h3>
<blockquote>
<h4 id="인터페이스interface란">인터페이스(Interface)란?</h4>
</blockquote>
<p>자바에서 클래스에 포함하는 메서드의 구체적인 내용을 작성하지 않고 상수와 메서드 타입만 정의한 것</p>
<blockquote>
<h4 id="컬렉션collection이란">컬렉션(Collection)이란?</h4>
</blockquote>
<p>복수의 데이터를 더 쉽게 사용할 수 있게 하는 클래스</p>
<blockquote>
<h4 id="컬렉션의-종류">컬렉션의 종류</h4>
</blockquote>
<ul>
<li>List : 순서대로 데이터를 저장, 데이터의 중복 허용</li>
<li>Set : 순서를 유지하지 않는 집합, 중복을 허용하지 않음</li>
<li>Map : 키와 값의 쌍으로 이루어진 데이터 집합, 순서는 유지되지 않고 키의 중복을 허용하지 않으며 값 중복을 허용</li>
</ul>
<blockquote>
<h4 id="list의-주요-구현-클래스컬렉션-프레임워크에서-제공하는-인터페이스">List의 주요 구현 클래스(컬렉션 프레임워크에서 제공하는 인터페이스)</h4>
</blockquote>
<ul>
<li>ArrayList : 요소를 배열로 유지, 검색 고속 처리, 요소의 수가 많아지면 추가/삭제 처리시간 多</li>
<li>LinkedList : 요소끼리 전후 양방향의 링크로 참조하는 리스트 구조를 이용해 관리,
ArrayList보다 추가/삭제 처리시간이 빠름, 특정 요소 검색과 같은 인덱스 값에 의한 무작위 액세스에는 적합하지 않음</li>
</ul>
<blockquote>
<h4 id="리스트-프로그램-만들기-→-패스">리스트 프로그램 만들기 → 패스</h4>
</blockquote>
<h3 id="2-2-웹-애플리케이션-만들기의-필수-지식-확인">2-2 웹 애플리케이션 만들기의 필수 지식 확인</h3>
<blockquote>
<h4 id="클라이언트와-서버">클라이언트와 서버</h4>
</blockquote>
<p>클라이언트 : 서비스를 요청
서버 : 서비스를 제공</p>
<p>즉, <strong>서버가 서비스를 제공해 그 서비스를 클라이언트가 사용하는 관계</strong></p>
<blockquote>
<h4 id="브라우저">브라우저</h4>
</blockquote>
<p>브라우저란? 인터넷을 사용할 때 이용하는 소프트웨어
Ex) Google Chrome, Firefox, Microsoft Edge, Safari 등등</p>
<blockquote>
<h4 id="애플리케이션과-웹-애플리케이션">애플리케이션과 웹 애플리케이션</h4>
</blockquote>
<p>애플리케이션 = 응용 프로그램 소프트웨어의 약어
즉, 프로그래밍 언어로 작성한 소프트웨어</p>
<p>웹 애플리케이션 = 인터넷을 통해 사용되는 응용 프로그램
Ex) e-커머스, e-러닝 등</p>
<blockquote>
<h4 id="웹-서버">웹 서버</h4>
</blockquote>
<p>웹서버 : 웹 애플리케이션을 배포하는 서버</p>
<ul>
<li>웹서버는 항상 실행되며 클라이언트로부터 액세스(요청)을 계속 기다림</li>
</ul>
<blockquote>
<h4 id="http-통신프로토콜">HTTP 통신(프로토콜)</h4>
</blockquote>
<p>클라이언트와 웹서버는 HTTP 요청(Request)와 HTTP 응답(Response)으로 상호작용 하는 것을 HTTP 통신이라 함(클라이언트의 요청에 대해 웹서버가 응답함)</p>
<blockquote>
<h4 id="get-메서드와-post-메서드">GET 메서드와 POST 메서드</h4>
</blockquote>
<p>GET 메서드 : 브라우저에서 웹 서버로 값을 전달할 때 URL 뒤에 값을 더하여 보내는 방식</p>
<ul>
<li>URL 뒤에 오는 정보를 &#39;쿼리스트링(query string)&#39; 또는 &#39;쿼리 문자열&#39;이라 함</li>
<li>URL 끝에 &#39;?&#39;가 붙어 쿼리 스트링의 시작을 나타냄</li>
<li>형식은 &#39;이름=값&#39;</li>
<li>여러 값을 전달하려면 &#39;&amp;&#39;로 연결</li>
</ul>
<p>POST 메서드 : 브라우저로부터 웹 서버에 값을 보낼 때 &#39;요청 본문(request body)&#39;이라고 하는 URL에 보이지 않는 장소에 값을 넣어서 보내는 방법</p>
<p>GET 메서드와 POST 메서드의 차이점
명칭으로부터 추측할 수 있음(GET은 받는다, POST는 보낸다)
즉, GET는 지정한 URL에 대한 내용을 받기 위한 메서드, POST는 지정한 URL에 입력 정보를 보내기 위한 메서드</p>
<h3 id="2-3-개발에-사용하는-편리한-라이브러리와-도구">2-3 개발에 사용하는 편리한 라이브러리와 도구</h3>
<blockquote>
<h4 id="lombok이란">Lombok이란?</h4>
</blockquote>
<p>프로그램의 세계에서는 편리한 프로그램을 모듈화한 것을 &#39;라이브러리&#39;라고 함
Lombok은 그런 라이브러리 중 하나에 속함</p>
<ul>
<li>Lombok을 사용하면 getter와 setter 등의 코드를 작성하지 않아도 자동으로 구현함</li>
</ul>
<blockquote>
<h4 id="gradle이란">Gradle이란?</h4>
</blockquote>
<p>Gradle은 빌드도구인데 이때 빌드는 &#39;요구된 실행 환경에서 동작할 수 있는 형식에 애플리케이션이나 라이브러리를 조립하는 것&#39; 이라 의미함</p>
<p>빌드도구의 반복적인 작업 자동화</p>
<ul>
<li>필요한 라이브러리를 리포지토리(라이브러리가 저장되어 있는 곳)에서 다운로드 함</li>
<li>소스코드를 컴파일함</li>
<li>테스트를 실행하여 보고서 출력</li>
<li>클래스 파일의 아카이브(여러 파일이나 폴더를 하나로 정리하는 것)를 생성합니다.</li>
<li>아카이브를 스테이징 환경(프로덕션 환경에 가까운 환경) 등에 배포합니다.</li>
</ul>
<p>즉, Gradle은 빌드 파일에서 설정을 작성하는 것으로 여러 가지 작업을 자동으로 해주는 편리한 도구하고 생각하면 됨</p>
<p><img src="https://velog.velcdn.com/images/tth-k/post/eb87150c-ae7d-4044-b133-986d0866cc8c/image.jfif" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[스프링 프레임워크 첫걸음_week 1]]></title>
            <link>https://velog.io/@tth-k/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%94%84%EB%A0%88%EC%9E%84%EC%9B%8C%ED%81%AC-%EC%B2%AB%EA%B1%B8%EC%9D%8Cday-1</link>
            <guid>https://velog.io/@tth-k/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%94%84%EB%A0%88%EC%9E%84%EC%9B%8C%ED%81%AC-%EC%B2%AB%EA%B1%B8%EC%9D%8Cday-1</guid>
            <pubDate>Tue, 17 Oct 2023 01:49:04 GMT</pubDate>
            <description><![CDATA[<h2 id="1장-스프링-프레임워크-알아보기">1장 스프링 프레임워크 알아보기</h2>
<h3 id="1-1-스프링-프레임워크-개요">1-1 스프링 프레임워크 개요</h3>
<blockquote>
<h4 id="프레임워크란">프레임워크란?</h4>
</blockquote>
<p>💀소프트웨어나 애플리케이션 개발을 간단하게 해주는 뼈대💀</p>
<blockquote>
<h4 id="장단점">장단점</h4>
</blockquote>
<p>장점 : 프레임워크가 개발에 필요한 최소한의 기능을 제공하기 때문에 자신이 모든 기능을 작성 할 필요가 없어 개발에 필요한 시간과 비용을 줄 일 수 있다.</p>
<p>단점 : 프레임워크 고유의 사용법을 이해할 필요가 있다.</p>
<blockquote>
<p>스프링 프레임워크란?</p>
</blockquote>
<p>자바 개발 환경에서 사용되는 프레임워크 줄여서 스프링이라고도 한다.</p>
<blockquote>
<p>스프링 프레임워크의 구성</p>
</blockquote>
<ul>
<li>스프링 부트(Spring Boot)<ul>
<li>스프링 애플리케이션을 복잡한 설정없이 빠르게 작성하는 기능을 제공</li>
</ul>
</li>
</ul>
<ul>
<li>스프링 프로젝트(Spring project)
  1) 스프링 MVC(Spring MVC) : 웹 애플리케이션을 간단하게 생성하는 기능 제공
  2) 스프링 데이터(Spring Data) : 데이터 접근에 관한 기능 제공
  3) 스프링 배치(Spring Batch) : 배치 처리 기능 제공
  4) 스프링 시큐리티(Spring Security) : 인증/허가 기능 제공</li>
</ul>
<ul>
<li>스프링 코어
  1) 스프링 DI(Spring DI) : 의존성 주입(Dependency Injection) 기능 제공
  2) 스프링 AOP(Spring AOP) : 관점 지향 프로그래밍(Aspect Oriented Programming) 기능 제공</li>
</ul>
<h3 id="1-2--1-4-개발-환경-준비자바-ide-postgresql-→-패스">1-2 ~ 1-4 개발 환경 준비(자바, IDE, PostgreSQL) → 패스</h3>
<p><img src="https://velog.velcdn.com/images/tth-k/post/ce82328f-dad1-492c-b9db-336f87e2fc1f/image.jpg" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[백엔드 신입 개발자가 쌓아야하는 역량은?
(feat. 자료구조/알고리즘/코딩테스트)]]></title>
            <link>https://velog.io/@tth-k/%EB%B0%B1%EC%97%94%EB%93%9C-%EC%8B%A0%EC%9E%85-%EA%B0%9C%EB%B0%9C%EC%9E%90%EA%B0%80-%EC%8C%93%EC%95%84%EC%95%BC%ED%95%98%EB%8A%94-%EC%97%AD%EB%9F%89%EC%9D%80feat.-%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98%EC%BD%94%EB%94%A9%ED%85%8C%EC%8A%A4%ED%8A%B8</link>
            <guid>https://velog.io/@tth-k/%EB%B0%B1%EC%97%94%EB%93%9C-%EC%8B%A0%EC%9E%85-%EA%B0%9C%EB%B0%9C%EC%9E%90%EA%B0%80-%EC%8C%93%EC%95%84%EC%95%BC%ED%95%98%EB%8A%94-%EC%97%AD%EB%9F%89%EC%9D%80feat.-%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98%EC%BD%94%EB%94%A9%ED%85%8C%EC%8A%A4%ED%8A%B8</guid>
            <pubDate>Thu, 31 Aug 2023 08:53:21 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h3 id="🤔백엔드-신입-개발자가-쌓아야하는-역량은">🤔백엔드 신입 개발자가 쌓아야하는 역량은??</h3>
</blockquote>
<p>결론부터 말하자면 커뮤니케이션 능력과 문제파악 및 해결능력으로 생각된다.
그리고 제목에도 적었지만 위 능력외에도 쌓아야하는 역량이 더 있다.
자세한 이유는 아래 적어놓았다.</p>
<blockquote>
<h4 id="1-커뮤니케이션-능력">1. 커뮤니케이션 능력</h4>
</blockquote>
<p>백엔드 개발은 <strong>혼자서만 하는 작업이 아니다.</strong>
여러 팀과 협력하여 프로젝트를 진행하고, 클라이언트 또는 다른 개발자와 요구사항을 논의해야 한다. 커뮤니케이션 능력은 오해와 혼란을 방지하고, 원활한 협업을 돕는다.</p>
<p>ex) 리뷰 및 피드백 수용, 명확하고 간결한 표현 등</p>
<blockquote>
<h4 id="2-문제파악-및-해결-능력">2. 문제파악 및 해결 능력</h4>
</blockquote>
<p>백엔드 개발은 복잡한 시스템에서 발생하는 <strong>다양한 문제를 해결</strong>해야한다.
문제를 정확하게 파악하고 효과적인 해결책을 찾는 능력은 필수라고 생각한다.</p>
<p>ex) 디버깅/로깅, 시스템적 사고 등</p>
<blockquote>
<h4 id="3-자료구조와-알고리즘">3 자료구조와 알고리즘</h4>
</blockquote>
<p>효율적인 코드와 시스템을 설계하기 위해서는 자료구조와 알고리즘에 대한 이해가 필요하다.</p>
<ul>
<li>자료구조
자료구조의 사전적인 정의는 효율적인 접근 및 수정을 가능케 하는 자료의 조직, 관리, 저장을 의미한다. 아래 이미지에 있는 구조들이 전부는 아니지만 큰 틀은 이해해야 코드와 시스템을 설계 할 수있다.</li>
</ul>
<p><img src="https://velog.velcdn.com/images/tth-k/post/4f987489-7adc-4039-9938-3fdccc12c8b3/image.png" alt=""></p>
<ul>
<li>알고리즘
알고리즘의 사전적인 정의는 문제 풀이에 필요한 계산 절차 또는 처리 과정의 순서를 뜻한다.
이해를 돕기 위해 아래 간단한 예시인 이미지를 첨부했다.</li>
</ul>
<p><img src="https://velog.velcdn.com/images/tth-k/post/4046bd1b-4d7f-4989-bfdf-5859b116f7bb/image.png" alt=""></p>
<p>(이미지출처: 구글)</p>
<blockquote>
<h4 id="4-코딩테스트">4. 코딩테스트</h4>
</blockquote>
<p>위에 나온 자료구조와 알고리즘은 한번에 완성작이 나올 수 없다고 생각한다.
그래서 지금까지 공부한 내용들을 응용하며 연습하는게 좋은 방법이라 할 수 있다.
그게 바로 <strong>코딩테스트!</strong>
한번 풀었던 문제는 다음번에 풀 때 까먹기 쉬워 여러번 반복하며 복습하는 습관이 중요하다.
온라인으로 문제를 풀 수 있는 사이트가 있으니 코딩테스트로 자료구조와 알고리즘의 역량을 더 기르고 백엔드로 개발자로써 더욱 성장해야겠다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[앞으로의 공부 계획
(feat.백엔드 공부법)]]></title>
            <link>https://velog.io/@tth-k/%EC%95%9E%EC%9C%BC%EB%A1%9C%EC%9D%98-%EA%B3%B5%EB%B6%80-%EA%B3%84%ED%9A%8Dfeat.%EB%B0%B1%EC%97%94%EB%93%9C-%EA%B3%B5%EB%B6%80%EB%B2%95</link>
            <guid>https://velog.io/@tth-k/%EC%95%9E%EC%9C%BC%EB%A1%9C%EC%9D%98-%EA%B3%B5%EB%B6%80-%EA%B3%84%ED%9A%8Dfeat.%EB%B0%B1%EC%97%94%EB%93%9C-%EA%B3%B5%EB%B6%80%EB%B2%95</guid>
            <pubDate>Mon, 21 Aug 2023 01:42:57 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>❔❕ 현재 내 상태는?</p>
</blockquote>
<p>직장을 그만두었고 공부에 집중 할 수 있는 시간적 여유가 많다.</p>
<blockquote>
<p>✨ 공부계획</p>
</blockquote>
<p>AM</p>
<ul>
<li>09:00 ~ 10:00</li>
<li><ul>
<li><ul>
<li>기상 및 아침식사**</li>
</ul>
</li>
</ul>
</li>
<li>10:00 ~ 11:59</li>
<li><ul>
<li><ul>
<li>잠을 깨우는 오전 코딩테스트(1~3문제)🌞**</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>PM</p>
<ul>
<li>12:00 ~ 01:00</li>
<li><ul>
<li><ul>
<li>점심식사**</li>
</ul>
</li>
</ul>
</li>
<li>01:00 ~ 06:00</li>
<li><ul>
<li><ul>
<li>권장가이드라인 진도 + 자바의 정석_남궁성(추가이해용도)**</li>
</ul>
</li>
</ul>
</li>
<li><ul>
<li><ul>
<li>제로베이스 과제**</li>
</ul>
</li>
</ul>
</li>
<li>06:00 ~ 09:00</li>
<li><ul>
<li><ul>
<li>운동 및 저녁식사**</li>
</ul>
</li>
</ul>
</li>
<li>09:00 ~ 11:59</li>
<li><ul>
<li><ul>
<li>남은 진도, 과제 및 이해 안갔던 문제와 이론 검토**</li>
</ul>
</li>
</ul>
</li>
</ul>
<blockquote>
<p>💪 백엔드 공부법</p>
</blockquote>
<p>처음에는 기초지식이 없어 인터넷 강의와 이론위주로 공부를 했었다.
하지만 이론 위주로 하다가 앞 내용을 잊어버리기 쉬웠다.
그래서 실기로 예제를 따라 적거나 <strong>코딩테스트를 직접 풀어보는 방법이 기억에 더 남았다.</strong></p>
<p>이제 시작한지 3주 정도 지났는데 너무 자세한 부분까지 알기에는 벅찬 느낌을 많이 받았다.
그래서 진도도 많이 안나가지는 것 같고 자존감도 떨어졌다.</p>
<p>멘토님이 조언해주신 것 <strong>큰 개념위주로 전반적인 흐름을 이해하고 공부를 하는 것</strong>이 부담감도 덜고 더 열심히 공부를 할 수 있을 것 같다.</p>
<p>그리고 공부를 하는데에는 기초체력이 정말 중요한 것 같다.
하루종일 컴퓨터 앞에 앉아있으려니 허리가 아파 저녁에 <strong>운동은 필수</strong>로 해야한다!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[나는 어떤 백엔드 개발자가 되고 싶은가?]]></title>
            <link>https://velog.io/@tth-k/%EB%82%98%EB%8A%94-%EC%96%B4%EB%96%A4-%EB%B0%B1%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C%EC%9E%90%EA%B0%80-%EB%90%98%EA%B3%A0-%EC%8B%B6%EC%9D%80%EA%B0%80</link>
            <guid>https://velog.io/@tth-k/%EB%82%98%EB%8A%94-%EC%96%B4%EB%96%A4-%EB%B0%B1%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C%EC%9E%90%EA%B0%80-%EB%90%98%EA%B3%A0-%EC%8B%B6%EC%9D%80%EA%B0%80</guid>
            <pubDate>Fri, 18 Aug 2023 07:27:29 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>💭백엔드 커리어 로드맵</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/tth-k/post/5ae60ca4-59e0-4aeb-9542-015979d62243/image.png" alt=""></p>
<p>위 이미지는 구글링으로 검색한 이미지이며 일부를 글로 요약해보면 아래와 같다.</p>
<p><strong>1. 프로그래밍 언어와 기본 개념</strong></p>
<ul>
<li>선택한 언어(예: Python, Java, Node.js 등)의 기초 문법 및 개념 이해</li>
<li>객체 지향 프로그래밍(OOP) 및 함수형 프로그래밍 개념 숙지</li>
</ul>
<p><strong>2. 데이터베이스</strong></p>
<ul>
<li>관계형 데이터베이스(SQL)와 NoSQL 데이터베이스(MongoDB, Redis 등) 사용법 이해</li>
<li>데이터 모델링과 쿼리 최적화에 대한 기본 지식 습득</li>
</ul>
<p><strong>3. 웹 개발 기초</strong></p>
<ul>
<li>HTTP 프로토콜 및 RESTful API 디자인 이해</li>
<li>웹 서버와 웹 애플리케이션의 동작 원리 이해</li>
</ul>
<p><strong>4. 백엔드 프레임워크와 도구</strong></p>
<ul>
<li>선택한 백엔드 프레임워크(Spring, Express, Django 등) 학습</li>
<li>버전 관리 시스템(Git) 사용법 익히기</li>
</ul>
<p><strong>5. 보안 및 인증</strong></p>
<ul>
<li>사용자 인증 및 권한 관리 구현</li>
<li>기본적인 웹 보안 취약점 이해하고 방어 방법 숙지</li>
</ul>
<p><strong>6. 마이크로서비스 및 컨테이너</strong></p>
<ul>
<li>컨테이너 기술(Docker, Kubernetes)을 이용한 애플리케이션 배포 및 관리 학습</li>
<li>마이크로서비스 아키텍처 이해 및 구축 방법 숙지</li>
</ul>
<p><strong>7. 클라우드 플랫폼</strong></p>
<ul>
<li>AWS, Azure, Google Cloud 등의 클라우드 플랫폼 사용법 익히기</li>
<li>클라우드 기반 서버 구성과 관리 방법 습득</li>
</ul>
<p><strong>8. 성능 최적화와 로깅</strong></p>
<ul>
<li>애플리케이션 성능 분석 및 최적화 기법 숙지</li>
<li>로깅과 모니터링 도구 활용하여 시스템 상태 관리</li>
</ul>
<p><strong>9. 테스트와 자동화</strong></p>
<ul>
<li>단위 테스트, 통합 테스트, E2E 테스트 등 테스트 방법 습득</li>
<li>CI/CD 도구를 사용한 자동화된 빌드, 배포, 테스트 프로세스 구축</li>
</ul>
<blockquote>
<p>🤔나는 어떤 개발자가 되고싶을까?</p>
</blockquote>
<ol>
<li><p><strong>소통이 잘되는 개발자가 되고싶다.</strong>
개발능력이 뛰어나도 소통이 안된다면 완성을 못하는것과 동일하다고 생각하기 때문에 소통이 잘되는 개발자가 되고싶다.</p>
</li>
<li><p><strong>대체되지 않는 개발자가 되고싶다.</strong>
위에 보이는 로드맵을 보면 마지막은 계속적인 배움이다.
계속적인 배움을 통해 성장하며 대체되지 않는 개발자가 되고싶다.</p>
</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[백준_알고리즘 수업 - 힙정렬2(24174번)]]></title>
            <link>https://velog.io/@tth-k/%EB%B0%B1%EC%A4%80%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EC%88%98%EC%97%85-%ED%9E%99%EC%A0%95%EB%A0%AC224174%EB%B2%88</link>
            <guid>https://velog.io/@tth-k/%EB%B0%B1%EC%A4%80%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EC%88%98%EC%97%85-%ED%9E%99%EC%A0%95%EB%A0%AC224174%EB%B2%88</guid>
            <pubDate>Sun, 13 Aug 2023 12:35:15 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>문제</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/tth-k/post/f7813625-9d29-4df4-80cf-ca05d3a5e714/image.png" alt=""></p>
<blockquote>
<p>입출력 및 예제들</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/tth-k/post/73aa9024-bc65-4ec4-92dd-5f79b75b2d90/image.png" alt=""></p>
<blockquote>
<p>코드 작성</p>
</blockquote>
<pre><code>import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {

    public static int cnt = 0, target = 0;
    public static int[] output;
    public static boolean isOut = false;

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        int num = Integer.parseInt(st.nextToken());
        target = Integer.parseInt(st.nextToken());
        int[] arr = new int[num + 1];
        arr[0] = 0;
        st = new StringTokenizer(br.readLine());
        for (int i = 1; i &lt; arr.length; i++) arr[i] = Integer.parseInt(st.nextToken());
        heapSort(arr);
        if (!isOut) {
            System.out.print(-1);
        }
    }

    public static void swap (int[] arr, int a, int b){
        cnt++;
        int tmp = arr[a];
        arr[a] = arr[b];
        arr[b] = tmp;
        if(cnt == target){
            StringBuilder sb = new StringBuilder();
            for (int i = 1; i &lt; arr.length; i++) {
                sb.append(arr[i]);
                sb.append(&quot; &quot;);
            }
            System.out.print(sb.toString());
            isOut = true;
        }
    }

    public static void heapSort(int[] arr) {
        buildMinHeap(arr, arr.length - 1);
        for (int i = arr.length - 1; i &gt; 1 ; i--) {
            swap(arr, 1 , i);
            heapify(arr, 1, i - 1);
        }
    }

    public static void buildMinHeap(int[] arr, int num) {
        for (int i = num / 2; i &gt;= 1 &amp;&amp; !isOut; i--) {
            heapify(arr, i, num);
        }
    }

    public static void heapify(int[] arr, int k, int num) {
        int left = 2 * k;
        int right = 2 * k + 1;
        int smaller = -1;

        if (right &lt;= num) {
            smaller = arr[left] &lt; arr[right] ? left : right;
        } else if (left &lt;= num) {
            smaller = left;
        } else {
            return;
        }

        if (arr[smaller] &lt; arr[k]) {
            swap(arr,k,smaller);
            heapify(arr, smaller, num);
        }
    }
}</code></pre><blockquote>
<p>Etc</p>
</blockquote>
<p>이것도 구글링을 통해 얻은 코드라 gpt의 도움을 받아 해석해보았다..</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[백준_요세푸스 문제(1158번)]]></title>
            <link>https://velog.io/@tth-k/%EB%B0%B1%EC%A4%80%EC%9A%94%EC%84%B8%ED%91%B8%EC%8A%A4-%EB%AC%B8%EC%A0%9C1158%EB%B2%88</link>
            <guid>https://velog.io/@tth-k/%EB%B0%B1%EC%A4%80%EC%9A%94%EC%84%B8%ED%91%B8%EC%8A%A4-%EB%AC%B8%EC%A0%9C1158%EB%B2%88</guid>
            <pubDate>Fri, 11 Aug 2023 14:32:45 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p> 문제</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/tth-k/post/6cd6d430-560a-4229-936e-ac7fac97370d/image.png" alt=""></p>
<blockquote>
<p>입출력 및 예제들</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/tth-k/post/780b9225-2821-4362-adbd-6f604f9d5251/image.png" alt=""></p>
<blockquote>
<p>코드작성</p>
</blockquote>
<pre><code>import java.util.Scanner;
import java.util.LinkedList;
import java.util.Queue;

public class Main {

    public static void main(String[] args) {

        Scanner in = new Scanner(System.in);
        Queue&lt;Integer&gt; q = new LinkedList&lt;&gt;();

        int N = in.nextInt();
        int K = in.nextInt();


        for(int i = 1; i &lt;= N; i++) {
            q.add(i);
        }

        StringBuilder sb = new StringBuilder();
        sb.append(&#39;&lt;&#39;);

        /*
         *  마지막 부분의 출력은 &gt; 괄호 전에 공백이 없기 때문에
         *  일괄적으로 출력하기 위해 마지막 원소만 남겨질 때까지만
         *  반복하고 마지막 원소는 그대로 출력함
         */

        while(q.size() &gt; 1) {

            for(int i = 0; i &lt; K - 1; i++) {
                int value = q.poll();
                q.offer(value);
            }

            sb.append(q.poll()).append(&quot;, &quot;);
        }

        // 마지막 원소 출력한 뒤 &gt; 도 추가
        sb.append(q.poll()).append(&#39;&gt;&#39;);
        System.out.println(sb);
    }

}</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[백준_해시 해킹(26008번)]]></title>
            <link>https://velog.io/@tth-k/%EB%B0%B1%EC%A4%80%ED%95%B4%EC%8B%9C-%ED%95%B4%ED%82%B926008%EB%B2%88</link>
            <guid>https://velog.io/@tth-k/%EB%B0%B1%EC%A4%80%ED%95%B4%EC%8B%9C-%ED%95%B4%ED%82%B926008%EB%B2%88</guid>
            <pubDate>Thu, 10 Aug 2023 16:20:39 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>문제</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/tth-k/post/b962ffc9-0787-4a5d-9cf9-b17945c3dbcb/image.png" alt=""></p>
<blockquote>
<p>입출력</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/tth-k/post/c97b6ebe-9928-4a00-88e8-dc0096acde34/image.png" alt=""></p>
<blockquote>
<p>예제들</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/tth-k/post/ee9f3b6a-d60f-489c-82a0-01c5d3d1ba71/image.png" alt=""></p>
<blockquote>
<p>코드작성</p>
</blockquote>
<pre><code>import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        long answer = 1L;

        int n = sc.nextInt();
        int m = sc.nextInt();
        int a = sc.nextInt();
        int h = sc.nextInt();

        for(int i = 0; i &lt; n-1; i ++){
            answer = (answer * m)%1000000007;
        }
        System.out.println(answer);
    }
}</code></pre><blockquote>
<p>Etc</p>
</blockquote>
<p>너무 어려운 것 같아 다른 블로그를 참고했다..
출처) <a href="https://nukoori.tistory.com/40">https://nukoori.tistory.com/40</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[백준_최소, 최대(10818번)]]></title>
            <link>https://velog.io/@tth-k/%EB%B0%B1%EC%A4%80%EC%B5%9C%EC%86%8C-%EC%B5%9C%EB%8C%80</link>
            <guid>https://velog.io/@tth-k/%EB%B0%B1%EC%A4%80%EC%B5%9C%EC%86%8C-%EC%B5%9C%EB%8C%80</guid>
            <pubDate>Thu, 10 Aug 2023 10:32:02 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>문제</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/tth-k/post/6efa3d89-5ad2-48d0-9f33-60e808928765/image.png" alt=""></p>
<blockquote>
<p>입출력 및 예제들</p>
</blockquote>
<p><img src="blob:https://velog.io/55c0984d-200a-4c3b-a98e-89fbb6b54494" alt="업로드중.."></p>
<blockquote>
<p>코드작성</p>
</blockquote>
<pre><code>import.java.util.Arrays;
import java.util.Scanner;

public class Main {
    public static void main(String args[]){
    Scanner sc = new Scanner(System.in);

    int N = sc.nextInt();
    int[] arr = new int[N];

    for (int i = 0; i &lt; N; i++){
        arr[i] = sc.nextInt();
    }

    // 오름차순 정리
    // 인덱스 첫번째 원소는 최솟값([0]), 마지막원소는 최대값([N-1])
    Arrays.sort(arr);
    System.out.print(arr[0] + &quot; &quot; + arr[N-1]);

    }
}</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[백준_회전하는 큐(1021번)]]></title>
            <link>https://velog.io/@tth-k/%EB%B0%B1%EC%A4%80%ED%9A%8C%EC%A0%84%ED%95%98%EB%8A%94-%ED%81%901021%EB%B2%88</link>
            <guid>https://velog.io/@tth-k/%EB%B0%B1%EC%A4%80%ED%9A%8C%EC%A0%84%ED%95%98%EB%8A%94-%ED%81%901021%EB%B2%88</guid>
            <pubDate>Thu, 10 Aug 2023 09:25:04 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>문제</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/tth-k/post/ac594616-e480-4672-a51f-b40d3eafa3bf/image.png" alt=""></p>
<blockquote>
<p>입출력 및 예제</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/tth-k/post/a4b05a09-a795-46da-bdf4-6b8bc3c686eb/image.png" alt=""></p>
<blockquote>
<p>코드작성</p>
</blockquote>
<pre><code>import java.util.LinkedList;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int N = scanner.nextInt(); // 큐의 크기
        int M = scanner.nextInt(); // 뽑아내려는 원소의 개수


        // 1부터 N까지 반복문 실행 후 큐에 순차적으로 1~N까지의 숫자를 추가
        LinkedList&lt;Integer&gt; queue = new LinkedList&lt;&gt;();
        for (int i = 1; i &lt;= N; i++) {
            queue.add(i);
        }

        //  뽑아내려는 원소의 값을 저장할 배열 생성 후 M번 반복하여 뽑아내려는 원소를 입력받고 원소값을 배열에 저장
        int[] targets = new int[M];
        for (int i = 0; i &lt; M; i++) {
            targets[i] = scanner.nextInt();
        }

        // 뽑아내려는 원소들을 하나씩 반복하여 처리 → 무한루프시작
        // 큐에서 뽑아내려는 원소의 인덱스를 찾음
        // 큐의 반 크기를 계산
        int count = 0; // 뽑아내는 횟수를 저장할 변수 초기화
        for (int target : targets) {
            while (true) {
                int index = queue.indexOf(target);
                int halfSize = queue.size() / 2;


                if (queue.getFirst() == target) {
                    queue.pollFirst();
                    break;
                }

                if (index &lt;= halfSize) {
                    queue.addLast(queue.pollFirst());
                } else {
                    queue.addFirst(queue.pollLast());
                }
                count++;
            }
        }
        System.out.println(count);
    }
}
</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[백준_포스택(25556번)]]></title>
            <link>https://velog.io/@tth-k/%EB%B0%B1%EC%A4%80%ED%8F%AC%EC%8A%A4%ED%83%9D25556%EB%B2%88</link>
            <guid>https://velog.io/@tth-k/%EB%B0%B1%EC%A4%80%ED%8F%AC%EC%8A%A4%ED%83%9D25556%EB%B2%88</guid>
            <pubDate>Thu, 10 Aug 2023 08:17:33 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>문제</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/tth-k/post/cbc3c913-8d3f-4d52-a036-f5c95eefdd55/image.PNG" alt=""></p>
<blockquote>
<p>입출력 및 예제들</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/tth-k/post/910998fe-f736-42c8-8282-09e9504c9b31/image.PNG" alt=""></p>
<blockquote>
<p>코드작성</p>
</blockquote>
<pre><code>import java.util.Scanner;
import java.util.Stack;

public class Main {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int num = sc.nextInt();
        int[] array = new int[num];
        Stack&lt;Integer&gt;[] a = new Stack[4];

        for (int i = 0; i &lt; num; i++) {
            array[i] = sc.nextInt();
        }

        for (int i = 0; i &lt; 4; i++) {
            a[i] = new Stack&lt;&gt;(); // 스택 배열a의 각각의 스택을 초기화하고
            a[i].push(0); // 0을 push
        }

        // 현재 item이 스택 a[i]의 맨 위의 값보다 크다면, 해당 스택에 &#39;item&#39;을 push
        for (int item : array) {
            for (int i = 0; i &lt; 4; i++) {
                if (item &gt; a[i].peek()) {
                    a[i].push(item);
                    break;
                }
                // 모든 스택에서 현재 숫자 `item`보다 작거나 같은 값을 가진 스택이 없다면, &quot;NO&quot;를 출력하고 프로그램 종료
                if (i == 3 &amp;&amp; item &lt;= a[i].peek()) {
                    System.out.println(&quot;NO&quot;);
                    return;
                }
            }
        }
        System.out.println(&quot;YES&quot;);
    }
}</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[{프론트엔드와 백엔드의 차이}
- 내가 백엔드 개발자가 되고 싶은 이유]]></title>
            <link>https://velog.io/@tth-k/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C%EC%99%80-%EB%B0%B1%EC%97%94%EB%93%9C%EC%9D%98-%EC%B0%A8%EC%9D%B4-%EB%82%B4%EA%B0%80-%EB%B0%B1%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C%EC%9E%90%EA%B0%80-%EB%90%98%EA%B3%A0-%EC%8B%B6%EC%9D%80-%EC%9D%B4%EC%9C%A0</link>
            <guid>https://velog.io/@tth-k/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C%EC%99%80-%EB%B0%B1%EC%97%94%EB%93%9C%EC%9D%98-%EC%B0%A8%EC%9D%B4-%EB%82%B4%EA%B0%80-%EB%B0%B1%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C%EC%9E%90%EA%B0%80-%EB%90%98%EA%B3%A0-%EC%8B%B6%EC%9D%80-%EC%9D%B4%EC%9C%A0</guid>
            <pubDate>Wed, 09 Aug 2023 07:13:43 GMT</pubDate>
            <description><![CDATA[<h1 id="👀프론트엔드front-end">👀프론트엔드(Front-End)?</h1>
<ul>
<li>프론트엔드는 해석 그대로 눈에 보이는 화면(영역)을 구축하고 구현하는 개발자이다.</li>
<li>사용언어 : HTML, CSS, JavaScript 등</li>
<li>Ex)<ul>
<li>웹디자인 및 레이아웃, UI개발, 웹 성능 최적화 등</li>
</ul>
</li>
</ul>
<h1 id="✨백엔드back-end">✨백엔드(Back-End)?</h1>
<ul>
<li>백엔드도 말 그대로 Back, 보이지 않는 부분(서버관리 등)을 개발, 관리하는 개발자이다.</li>
<li>사용언어 : Java, Phython, Ruby, GO, C# 등</li>
<li>Ex)<ul>
<li>서버 개발, 데이터베이스 관리, API 설계 및 개발 등
✔ 이때 API는 서로 다른 시스템이나 애플리케이션 간에 데이터를 교환하거나 서비스를 요청하고 제공하는데 사용한다.(프론트엔드는 백엔드에게 API를 받아 작업을 한다.)</li>
</ul>
</li>
</ul>
<h1 id="💭-백엔드-개발자가-되고-싶은-이유">💭 백엔드 개발자가 되고 싶은 이유</h1>
<p>비전공자 + 문과였던 내가 갑자기 개발자가 되고 싶었던 이유는 재직 중 일때 당시 하던 업무의 난이도가 평범하고 미래를 생각 했을 때 금방 대체 될 수 있다고 생각이 들었다. 그래서 주변 지인들 중 개발을 본업으로 갖고 있는 사람들에게 의견을 물어보았다. 나이가 많아져도 실력만 있다면 프리랜서로 활동하며 일을 할 수 있다는 말에 개발에 관심을 갖게 되었다. 개발자는 프론트와 백엔드 말고도 많은 종류가 있는데 그 중에서 백엔드를 고른 이유는 겉으로 보이진 않지만 기능들을 원활하게 진행 시킬 수 있을 때 그 성취감이 좋을 것 같아 선택했다. 배운지 아직 2주도 되지 않았지만 오류가 생겨 해결했을 때 쾌감은 너무 행복한 것 같다. 앞으로도 더 열심히 공부해서 대체되지 않는 개발자가 되고싶다!</p>
]]></description>
        </item>
    </channel>
</rss>