<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Life,  Develop, Positive</title>
        <link>https://velog.io/</link>
        <description>어렵다고 피하지 말고 도전하자! 긍정!</description>
        <lastBuildDate>Thu, 05 Jan 2023 06:02:55 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>Life,  Develop, Positive</title>
            <url>https://velog.velcdn.com/images/code_j/profile/473a5260-a73b-459f-b925-da5d0002570a/social_profile.jpeg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. Life,  Develop, Positive. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/code_j" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[프로그래밍 패러다임 - 선언과 명령]]></title>
            <link>https://velog.io/@code_j/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D-%ED%8C%A8%EB%9F%AC%EB%8B%A4%EC%9E%84-%EC%84%A0%EC%96%B8%EA%B3%BC-%EB%AA%85%EB%A0%B9</link>
            <guid>https://velog.io/@code_j/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D-%ED%8C%A8%EB%9F%AC%EB%8B%A4%EC%9E%84-%EC%84%A0%EC%96%B8%EA%B3%BC-%EB%AA%85%EB%A0%B9</guid>
            <pubDate>Thu, 05 Jan 2023 06:02:55 GMT</pubDate>
            <description><![CDATA[<h1 id="프로그래밍-패러다임">프로그래밍 패러다임</h1>
<p>프로그래머에게 프로그래밍의 관점을 갖게 해주는 역할을 하는 방법론이다. 선언형과 명령형으로 나뉘며 선언형에는 함수형이 있고 명령형에는 객체지향형과 절차지향형이 있다.</p>
<h2 id="선언형과-함수형-프로그래밍">선언형과 함수형 프로그래밍</h2>
<p>선언형은 <code>무엇을</code> 풀어내는가에 집중하는 패러다임이며, <code>프로그램은 함수로 이루어진 것이다.</code>라는 면제가 담겨 있다. 함수형은 작은 <code>순수 함수</code>들을 블록처럼 쌓아 로직을 구현하고 <code>고차 함수</code>를 통해 재사용성을 높인 프로그래밍이다. </p>
<h4 id="순수-함수">순수 함수</h4>
<p>출력이 입력에만 의존하는 함수를 의미한다. 아래와 같이 함수에 입력받는 a와 b만 사용하여 결과값을 도출한다.</p>
<pre><code class="language-python">def sum(a, b):
    return a + b</code></pre>
<h4 id="고차-함수">고차 함수</h4>
<p>함수가 함수를 값처럼 매개변수로 받아 로직을 수행하는 것을 말한다.</p>
<h4 id="일급-객체">일급 객체</h4>
<ul>
<li>변수나 메서드에 함수를 할당할 수 있다.</li>
<li>함수 안에 함수를 매개변수로 담을 수 있다.</li>
<li>함수가 함수를 반환할 수 있다.</li>
</ul>
<h2 id="객체지향-프로그래밍">객체지향 프로그래밍</h2>
<p>OOP(Object-Oriented Programming)는 객체들의 집합으로 프로그램의 상호 작용을 표현하며 데이터를 객체로 취급하여 객체 내부에 선언된 메서드를 활용하는 방식을 말한다. 설계에 많은 시간이 소요되고 처리 속도가 느린편이다.</p>
<h3 id="특징">특징</h3>
<p>추상화, 캡슐화, 상속성, 다형성이라는 특징을 가진다.</p>
<ul>
<li><p><strong>추상화</strong> : 복잡한 시스템으로부터 핵심적인 개념 또는 기능을 간추려내는 것을 의미한다. 여러 특징 중에서 필요한 특징만 뽑아내는 것이라고 생각하면 된다.</p>
</li>
<li><p><strong>캡슐화</strong> : 객체의 속성과 메서드를 하나로 묶오 외부에서 알 수 없도록 숨기는 것을 말한다.</p>
</li>
<li><p><strong>상속성</strong> :상위 클래스의 특성을 하위 클래스가 상속받아 사용하거나 추가 및 확장하는 것을 말한다.</p>
</li>
<li><p><strong>다형성</strong> : 하나의 메스드나 클래스가 다양한 방법으로 동작하는 것을 의미하는데 오버로딩, 오버라이딩이 대표적이다.</p>
</li>
</ul>
<h4 id="오버로딩">오버로딩</h4>
<p>같은 이름을 가진 메서드를 여러 개 생성하는 것을 말한다. 타입, 매개변수의 유형, 개수 등으로 나뉘어 생성한다. <code>정적</code> 다형성이라고 한다.</p>
<h4 id="오버라이딩">오버라이딩</h4>
<p>상위 클래스에게 상속받은 메서드를 하위 클래스가 재정의하는 것을 의미한다. <code>동적</code> 다형성이라고 한다.</p>
<h3 id="설계-원칙">설계 원칙</h3>
<p>객체지향은 SOLID 원칙을 지키며 설계한다.</p>
<h4 id="단일-책임-원칙---srpsingle-reponsibility-principle">단일 책임 원칙 - SRP(Single Reponsibility Principle)</h4>
<p>모든 클래스는 각각 하나의 책임만 가져야 하는 원칙이다.</p>
<h4 id="개방-폐쇄-원칙---ocpopen-closed-principle">개방-폐쇄 원칙 - OCP(Open Closed Principle)</h4>
<p>유지 보수 사항이 생긴다면 코드를 쉽게 확잘할 수 있도록 하고 수정할 때는 닫혀 있어야 하는 원칙이다. 기존 코드를 변경하지 않고 확장을 쉽게 해야된다는 의미이다.</p>
<h4 id="리스코프-치환-원칙---lspliskov-substritution-principle">리스코프 치환 원칙 - LSP(Liskov Substritution Principle)</h4>
<p>프로그앰의 정확성을 깨뜨리지 않으면서 하위 타입의 인스턴스로 바꿀 수 있어야 하는 것을 의미한다. 부모 객체에 자식 객체를 넣어도 문제가 없어야 하는 것이다.</p>
<h4 id="인터페이스-분리-원칙---ispinterface-segregation-principle">인터페이스 분리 원칙 - ISP(Interface Segregation Principle)</h4>
<p>하나의 일반적인 인터페이스보다 구체적인 여러 개의 인터페이스를 만들어야 하는 원칙이다.</p>
<h4 id="의존-역전-원칙---dipdependency-inversion-principle">의존 역전 원칙 - DIP(Dependency Inversion Principle)</h4>
<p>자신보다 변하기 쉬운 것에 의존하던 것을 추상화된 인터페이스나 상뤼 클래스를 두어 변하기 쉬운 것에 영향반지 않게 하는 원칙이다. 예를 들어 마네킹에게 여러 옷을 입히는데 마네킹은 그대로 유지되어야 하는 것이다. 상위 계층은 하위 계층에 대한 구현으로부터 독립해야 한다는 것이다.</p>
<h2 id="절차형-프로그래밍">절차형 프로그래밍</h2>
<p>로직이 수행되어야 할 연속적인 계산 과정으로 이루어지며 코드의 가독성이 좋고 실행 속도가 빠르다. 대부분 계산이 많은 작업에 사용되는데 대기 과학 관련 연산 작업이나 머신 러닝의 배치 작업이 예이다. 단점으로는 모듈화가 어렵고 유지 보수성이 떨어진다는 점이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[디자인 패턴과 프로그래밍 패러다임 - 그 외 패턴]]></title>
            <link>https://velog.io/@code_j/%EB%94%94%EC%9E%90%EC%9D%B8-%ED%8C%A8%ED%84%B4%EA%B3%BC-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D-%ED%8C%A8%EB%9F%AC%EB%8B%A4%EC%9E%84-%EA%B7%B8%EC%99%B8-%ED%8C%A8%ED%84%B4</link>
            <guid>https://velog.io/@code_j/%EB%94%94%EC%9E%90%EC%9D%B8-%ED%8C%A8%ED%84%B4%EA%B3%BC-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D-%ED%8C%A8%EB%9F%AC%EB%8B%A4%EC%9E%84-%EA%B7%B8%EC%99%B8-%ED%8C%A8%ED%84%B4</guid>
            <pubDate>Thu, 05 Jan 2023 03:50:12 GMT</pubDate>
            <description><![CDATA[<h2 id="이터레이터-패턴">이터레이터 패턴</h2>
<p>이터레이터를 사용하여 컬렉션의 요소들에 접근하는 패턴이다. 순회할 수 있는 여러 가지 자료현의 구조와는 상관없이 이터레이터라는 하나의 인터페이스로 순회가 가능하다.</p>
<h2 id="노출모듈-패턴">노출모듈 패턴</h2>
<p>즉시 실행 함수를 통해 private, public 같은 접근 제어자를 만드는 패턴이다.</p>
<h4 id="public">public</h4>
<p>클래스에 정의된 함수에서 접근 가능하며 자식 클래스와 외부 클래스에서 접근 가능하다.</p>
<h4 id="protected">protected</h4>
<p>클래스에 정의된 함수에서 접근 가능하며 자식 클래스에서 접근 가능하지만 외부 클래스에서는 접근이 안된다.</p>
<h4 id="private">private</h4>
<p>클래스에 정의된 함수에서 접근 가능하며 자식이나 외부 클래스는 접근 불가능하다.</p>
<h4 id="즉시-실행-함수">즉시 실행 함수</h4>
<p>함수를 정의하자마자 바로 호출하는 함수를 의마한다. 초기화 코드, 라이브러리 내 전역 변수의 충돌 방지 용도로 사용한다.</p>
<h2 id="mvc-패턴">MVC 패턴</h2>
<p>Model, View, Controller로 이루어진 디자인 패턴이다. 재사용성과 확장성이 용이하다는 장점이 있고, 애플리케이션이 복잡해질수록 모델과 뷰의 관계가 복잡해진다는 단점이 있다.</p>
<h4 id="모델">모델</h4>
<p>애플리케이션의 데이터인 데이터베이스, 상수, 변수 등을 의미한다.</p>
<h4 id="뷰">뷰</h4>
<p>사용자 인터페이스 요소를 의미한다. 모델을 기반으로 사용자가 볼 수 있는 화면을 뜻한다.</p>
<h4 id="컨트롤러">컨트롤러</h4>
<p>하나 이상의 모델과 뷰를 잇는 역할을 하며 메인 로직을 수행하는 담당이다. 모델과 뷰의 생명주기를 관리하며 모델과 뷰의 변경 사항을 받으면 이를 해석하여 처리한다.</p>
<h2 id="mvp-패턴">MVP 패턴</h2>
<p>MVC 패턴에서 파생되었으며 컨트롤러가 프레젠터(Presenter)로 변경된 패턴이다. 뷰와 프레젠터가 일대일 관계이기에 강한 결합을 가지는 디자인 패턴이다.</p>
<h2 id="mvvm-패턴">MVVM 패턴</h2>
<p>MVC 패턴의 컨트롤러를 대신하여 뷰모델(View Model)을 사용하는 패턴이다. 뷰모델은 뷰를 추상화한 계층이며 MVC 패턴과 다르게 커맨드와 데이터 바인딩을 가진다. 뷰와 뷰모델 사이의 양방향 데이터 바인딩을 지원하고 UI를 별도로 수정하지 않고 재사용할 수 있다. Vue.js가 대표적인 프레임워크다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[디자인 패턴과 프로그래밍 패러다임 - 프록시 패턴]]></title>
            <link>https://velog.io/@code_j/%EB%94%94%EC%9E%90%EC%9D%B8-%ED%8C%A8%ED%84%B4%EA%B3%BC-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D-%ED%8C%A8%EB%9F%AC%EB%8B%A4%EC%9E%84-%ED%94%84%EB%A1%9D%EC%8B%9C-%ED%8C%A8%ED%84%B4</link>
            <guid>https://velog.io/@code_j/%EB%94%94%EC%9E%90%EC%9D%B8-%ED%8C%A8%ED%84%B4%EA%B3%BC-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D-%ED%8C%A8%EB%9F%AC%EB%8B%A4%EC%9E%84-%ED%94%84%EB%A1%9D%EC%8B%9C-%ED%8C%A8%ED%84%B4</guid>
            <pubDate>Wed, 04 Jan 2023 02:43:55 GMT</pubDate>
            <description><![CDATA[<h2 id="프록시-패턴과-프록시-서버">프록시 패턴과 프록시 서버</h2>
<h3 id="프록시-패턴">프록시 패턴</h3>
<p>대상 객체에 접근하기 전 그 접근에 대한 흐름을 가로채 대상 객체 앞단의 인터페이스 역할을 하는 디잔인 패턴이다. 객체의 속성, 변환 등을 보완 가능하며 보안, 데이터 검증, 캐싱, 로깅에 사용된다.</p>
<h4 id="캐싱">캐싱</h4>
<p>캐시 안에 정보를 담아 요구하는 요청에 대한 데이터를 서버로 요청하지 않고 캐시에 있는 데이터를 활용하는 것이다.</p>
<h3 id="프록시-서버">프록시 서버</h3>
<p>서버와 클라이언트 사이에서 클라이언트가 자신을 통해 다른 네트워크 서비스에 간접적으로 접속할 수 있게 해주는 서버를 말한다. Nginx, CloudFlare가 프록시 서버로 사용되는 예이다. Node.js를 사용할 때 버퍼 오버플로우 취약점을 방지하기 위해 앞단에 프록시 서버로 Nginx가 사용된다. </p>
<p>프록시 서버는 익명의 사용자가 직접적인 서버 접근을 막아주고 한 단계를 더 거침으로써 보안성을 높여준다. 실제 서버가 사용하는 포트를 숨기고 앞단에서 로깅을 할 수 있다.</p>
<h4 id="버퍼-오버플로우">버퍼 오버플로우</h4>
<p>버퍼는 보통 데이터가 저장되는 메모리 공간으로, 메모리 공간을 벗어나는 경우를 말한다. 사용되지 않아야 할 영역에 데이터가 사용되어 공격이 발생하기도 한다.</p>
<h4 id="cdn">CDN</h4>
<p>콘텐츠 전송 네트워크(CDN)는 데이터 사용량이 많은 애플리케이션의 웹 페이지 로드 속도를 높이는 상호 연결된 서버 네트워크이다. DDOS 공격 방어 및 HTTPS 구축에 이점이 있다.</p>
<h4 id="ddos-공격-방어">DDOS 공격 방어</h4>
<p>짧은 기간 동안 네트워크에 많은 요청을 보내 마비시키는 공격으로 CloudFlare는 의심스러운 트래픽과 사용자가 아닌 시스템을 통하는 트래픽을 자동으로 차단해준다.</p>
<h4 id="https-구축">HTTPS 구축</h4>
<p>서버는 인증서를 기반으로 HTTPS를 구축한다. 하지만 CloudFlare를 사용하면 별도의 인증서 설치 없이 손쉽게 구축이 가능하다.</p>
<h3 id="cors와-프런트엔드의-프록시-서버">CORS와 프런트엔드의 프록시 서버</h3>
<p>CORS(Cross-Origin Resource Sharing)는 서바가 웹 브라우저에서 리소스를 로드할 때 다른 오리진을 통해 로드하지 못하게 하는 HTTP 헤더 기반 메커니즘이다.</p>
<p>프론트엔드에서 테스팅을 하는데 서보와 포트 번호가 다른 경우 CORS 에러가 발생하는데 이때 프록시 서버를 둬서 포트를 서버에 맞게 바꿔 맞춰주는 것이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[디자인 패턴과 프로그래밍 패러다임 - 옵저버 패턴]]></title>
            <link>https://velog.io/@code_j/%EB%94%94%EC%9E%90%EC%9D%B8-%ED%8C%A8%ED%84%B4%EA%B3%BC-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D-%ED%8C%A8%EB%9F%AC%EB%8B%A4%EC%9E%84-%EC%98%B5%EC%A0%80%EB%B2%84-%ED%8C%A8%ED%84%B4</link>
            <guid>https://velog.io/@code_j/%EB%94%94%EC%9E%90%EC%9D%B8-%ED%8C%A8%ED%84%B4%EA%B3%BC-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D-%ED%8C%A8%EB%9F%AC%EB%8B%A4%EC%9E%84-%EC%98%B5%EC%A0%80%EB%B2%84-%ED%8C%A8%ED%84%B4</guid>
            <pubDate>Wed, 04 Jan 2023 01:24:11 GMT</pubDate>
            <description><![CDATA[<h2 id="옵저버-패턴">옵저버 패턴</h2>
<p>주체가 어떤 객체의 상태 변화를 관찰하다가 상태 변화가 있을 때마다 메서드 등을 통해 옵저버 목록에 있는 옵저버들에게 변화를 알려주는 디자인 패턴이다.</p>
<img src="https://velog.velcdn.com/images/code_j/post/2caa6326-2596-41a6-bb8f-829fbd344ebc/image.png" width="50%" height="50%">


<p>여기서 주체란 객체의 산태 변화를 보고 있는 관찰자이며, 옵저버들이란 이 객체의 상태 변화에 따라 전달되는 메서드 등을 기반으로 <code>추가 변화 사항</code>이 생기는 객체들을 의미한다.</p>
<img src="https://velog.velcdn.com/images/code_j/post/64db66e8-dd6a-4f57-bbd2-0f5c7786c8d6/image.png" width="50%" height="50%">

<p>또한, 주체와 객체를 따로 두지 않고 상태가 변경되는 객체를 기반으로 구축하기도 한다. 옵저버 패턴을 활용한 서비스는 트위처가 있다. 그리고 주로 이벤트 기반 시스템에 사용하며 MVC 패턴에서도 사용된다.</p>
<img src="https://velog.velcdn.com/images/code_j/post/d2dac06e-b68f-4b26-a951-a4cf6ef33982/image.png" width="60%" height="50%">

<p>예를 들어 주체라고 볼 수 있는 모델에서 변경 사항이 생겨 update() 메서드로 옵저버인 뷰에 알려주고 이를 기반으로 컨트롤러 등이 작동하는 것이다.</p>
<p>아래는 옵저버 패턴의 자바 코드 예시이다.</p>
<pre><code class="language-java">package cs.kmjang;

import java.util.ArrayList;
import java.util.List;

interface Subject {
    public void register(Observer obj);

    public void unregister(Observer obj);

    public void notifyObservers();

    public Object getUpdate(Observer obj);
}

interface Observer {
    public void update();
}

class Topic implements Subject {
    private List&lt;Observer&gt; observers;
    private String message;

    public Topic() {
        this.observers = new ArrayList&lt;&gt;();
        this.message = &quot;&quot;;
    }

    @Override
    public void register(Observer obj) {
        if (!observers.contains(obj)) observers.add(obj);
    }

    @Override
    public void unregister(Observer obj) {
        observers.remove(obj);
    }

    @Override
    public void notifyObservers() {
        this.observers.forEach(Observer::update);
    }

    @Override
    public Object getUpdate(Observer obj) {
        return this.message;
    }

    public void postMessage(String msg) {
        System.out.println(&quot;Message sended to Topic: &quot; + msg);
        this.message = msg;
        notifyObservers();
    }
}

class TopicSubscriber implements Observer {
    private String name;
    private Subject topic;

    public TopicSubscriber(String name, Subject topic) {
        this.name = name;
        this.topic = topic;
    }

    @Override
    public void update() {
        String msg = (String) topic.getUpdate(this);
        System.out.println(name + &quot;:: got message &gt;&gt; &quot; + msg);
    }
}

public class HelloWorld {
    public static void main(String[] args) {
        Topic topic = new Topic();
        Observer a = new TopicSubscriber(&quot;a&quot;, topic);
        Observer b = new TopicSubscriber(&quot;b&quot;, topic);
        Observer c = new TopicSubscriber(&quot;c&quot;, topic);
        topic.register(a);
        topic.register(b);
        topic.register(c);

        topic.postMessage(&quot;amumu is op champion!!&quot;);
    }
}
/*
Message sended to Topic: amumu is op champion!!
a:: got message &gt;&gt; amumu is op champion!!
b:: got message &gt;&gt; amumu is op champion!!
c:: got message &gt;&gt; amumu is op champion!!
*/</code></pre>
<p>topic을 기반으로 옵저버 패턴을 구현했다. 여기서 topic은 주체이자 객체가 된다. <code>class Topic implement Subject</code>를 통해 <code>Subject interface</code>를 구현했고 <code>Observer a = new TopicSubscriber(&quot;a&quot;, topic);</code>으로 옵저버를 선언할 때 해당 이름과 어떠한 토픽의 옵저버가 될 것인지를 정한다.</p>
<h2 id="자바의-상속과-구현">자바의 상속과 구현</h2>
<h3 id="상속">상속</h3>
<p>상속(extend)은 자식 클래스가 부모 클래스의 메서드 등을 상속받아 사용하며 자식 클래스에서 추가 및 확장을 할 수 있는 것을 말한다. 이로 인해 재사용성, 중복성의 최소화가 이루어진다. 상황에 따라 재정의(Overriding)도 가능하다.</p>
<h3 id="구현">구현</h3>
<p>구현(implement)은 부모 인터페이스를 자식 클래스에서 재정의(Overriding)하여 구현하는 것을 말하며, 상속과는 달리 반드시 부모 클래스의 메서드를 재정의하여 구현해야 한다.</p>
<h3 id="상속과-구현의-차이">상속과 구현의 차이</h3>
<p>상속은 일반 클래스, abstract 클래스를 기반으로 구현하며, 구현은 인터페이스를 기반으로 구현한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[디자인 패턴과 프로그래밍 패러다임 - 전략 패턴]]></title>
            <link>https://velog.io/@code_j/%EB%94%94%EC%9E%90%EC%9D%B8-%ED%8C%A8%ED%84%B4%EA%B3%BC-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D-%ED%8C%A8%EB%9F%AC%EB%8B%A4%EC%9E%84-%EC%A0%84%EB%9E%B5-%ED%8C%A8%ED%84%B4</link>
            <guid>https://velog.io/@code_j/%EB%94%94%EC%9E%90%EC%9D%B8-%ED%8C%A8%ED%84%B4%EA%B3%BC-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D-%ED%8C%A8%EB%9F%AC%EB%8B%A4%EC%9E%84-%EC%A0%84%EB%9E%B5-%ED%8C%A8%ED%84%B4</guid>
            <pubDate>Tue, 03 Jan 2023 08:36:36 GMT</pubDate>
            <description><![CDATA[<h2 id="전략-패턴">전략 패턴</h2>
<p>정책 패턴이라고도 하며, 객체의 행위를 바꾸고 싶은 경우 <code>직접</code> 수정하지 않고 전략이라고 부르는 <code>캡슐화한 알고리즘</code>을 컨텍스트안에서 바꿔주면서 상호 교체가 가능하게 만드는 패턴이다.</p>
<img src="https://velog.velcdn.com/images/code_j/post/629f9b7a-498c-4e9a-95be-9d32fc8988bf/image.png" width="50%" height="50%">

<p>예제 코드는 아래와 같다. 캡슐화된 PaymentStrategy 인터페이스를 상속받아 KAKAOCardStrategy와 LUNACardStrategy 둘 중 선택적으로 사용 가능하게 만드는 것이다</p>
<pre><code class="language-java">import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

interface PaymentStrategy { 
    public void pay(int amount);
} 

class KAKAOCardStrategy implements PaymentStrategy {
    private String name;
    private String cardNumber;
    private String cvv;
    private String dateOfExpiry;

    public KAKAOCardStrategy(String nm, String ccNum, String cvv, String expiryDate){
        this.name=nm;
        this.cardNumber=ccNum;
        this.cvv=cvv;
        this.dateOfExpiry=expiryDate;
    }

    @Override
    public void pay(int amount) {
        System.out.println(amount +&quot; paid using KAKAOCard.&quot;);
    }
} 

class LUNACardStrategy implements PaymentStrategy {
    private String emailId;
    private String password;

    public LUNACardStrategy(String email, String pwd){
        this.emailId=email;
        this.password=pwd;
    }

    @Override
    public void pay(int amount) {
        System.out.println(amount + &quot; paid using LUNACard.&quot;);
    }
} 

class Item { 
    private String name;
    private int price; 
    public Item(String name, int cost){
        this.name=name;
        this.price=cost;
    }

    public String getName() {
        return name;
    }

    public int getPrice() {
        return price;
    }
} 

class ShoppingCart { 
    List&lt;Item&gt; items;

    public ShoppingCart(){
        this.items=new ArrayList&lt;Item&gt;();
    }

    public void addItem(Item item){
        this.items.add(item);
    }

    public void removeItem(Item item){
        this.items.remove(item);
    }

    public int calculateTotal(){
        int sum = 0;
        for(Item item : items){
            sum += item.getPrice();
        }
        return sum;
    }

    public void pay(PaymentStrategy paymentMethod){
        int amount = calculateTotal();
        paymentMethod.pay(amount);
    }
}  

public class HelloWorld{
    public static void main(String []args){
        ShoppingCart cart = new ShoppingCart();

        Item A = new Item(&quot;kundolA&quot;,100);
        Item B = new Item(&quot;kundolB&quot;,300);

        cart.addItem(A);
        cart.addItem(B);

        // pay by LUNACard
        cart.pay(new LUNACardStrategy(&quot;kundol@example.com&quot;, &quot;pukubababo&quot;));
        // pay by KAKAOBank
        cart.pay(new KAKAOCardStrategy(&quot;Ju hongchul&quot;, &quot;123456789&quot;, &quot;123&quot;, &quot;12/01&quot;));
    }
}
/*
400 paid using LUNACard.
400 paid using KAKAOCard.
*/</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[디자인 패턴과 프로그래밍 패러다임 - 팩토리 패턴]]></title>
            <link>https://velog.io/@code_j/%EB%94%94%EC%9E%90%EC%9D%B8-%ED%8C%A8%ED%84%B4%EA%B3%BC-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D-%ED%8C%A8%EB%9F%AC%EB%8B%A4%EC%9E%84-%ED%8C%A9%ED%86%A0%EB%A6%AC-%ED%8C%A8%ED%84%B4</link>
            <guid>https://velog.io/@code_j/%EB%94%94%EC%9E%90%EC%9D%B8-%ED%8C%A8%ED%84%B4%EA%B3%BC-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D-%ED%8C%A8%EB%9F%AC%EB%8B%A4%EC%9E%84-%ED%8C%A9%ED%86%A0%EB%A6%AC-%ED%8C%A8%ED%84%B4</guid>
            <pubDate>Mon, 02 Jan 2023 06:11:01 GMT</pubDate>
            <description><![CDATA[<h2 id="팩토리-패턴">팩토리 패턴</h2>
<p>객체를 사용하는 코드에서 객체 생성 부분을 떼어내 추상화한 패턴이자 상속 관계에 있는 두 클래스에서 상위 클래스가 중요한 뼈대를 결정하고, 하위 클래스에서 객체 생성에 관한 구체적인 내용을 결정하는 패턴이다.</p>
<p>상위 클래스와 하위 클래스가 분리되기 때문에 느슨한 결합을 하며 상위 클래스에서는 인스턴스 생성 방식에 대해 전형 알 필요가 없으므로 더 많은 유연성을 갖게 된다. 그리고 객체 생성 로직이 따로 떼어져 있으므로 코드를 리팩토링하더라도 한 곳만 고칠 수 있게 되니 유지 보수성이 증가한다.</p>
<pre><code class="language-java">abstract class Coffee { 
    public abstract int getPrice(); 

    @Override
    public String toString(){
        return &quot;Hi this coffee is &quot;+ this.getPrice();
    }
}

class CoffeeFactory { 
    public static Coffee getCoffee(String type, int price){
        if(&quot;Latte&quot;.equalsIgnoreCase(type)) return new Latte(price);
        else if(&quot;Americano&quot;.equalsIgnoreCase(type)) return new Americano(price);
        else{
            return new DefaultCoffee();
        } 
    }
}

class DefaultCoffee extends Coffee {
    private int price;

    public DefaultCoffee() {
        this.price = -1;
    }

    @Override
    public int getPrice() {
        return this.price;
    }
}

class Latte extends Coffee { 
    private int price; 

    public Latte(int price){
        this.price=price; 
    }
    @Override
    public int getPrice() {
        return this.price;
    } 
}

class Americano extends Coffee { 
    private int price; 

    public Americano(int price){
        this.price=price; 
    }
    @Override
    public int getPrice() {
        return this.price;
    } 
} 

public class HelloWorld{ 
     public static void main(String []args){ 
        Coffee latte = CoffeeFactory.getCoffee(&quot;Latte&quot;, 4000);
        Coffee ame = CoffeeFactory.getCoffee(&quot;Americano&quot;,3000); 
        System.out.println(&quot;Factory latte ::&quot;+latte);
        System.out.println(&quot;Factory ame ::&quot;+ame); 
     }
} 
/*
Factory latte ::Hi this coffee is 4000
Factory ame ::Hi this coffee is 3000
*/</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[디자인 패턴과 프로그래밍 패러다임 - 싱글톤 패턴]]></title>
            <link>https://velog.io/@code_j/%EB%94%94%EC%9E%90%EC%9D%B8-%ED%8C%A8%ED%84%B4%EA%B3%BC-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D-%ED%8C%A8%EB%9F%AC%EB%8B%A4%EC%9E%84-%EC%8B%B1%EA%B8%80%ED%86%A4-%ED%8C%A8%ED%84%B4</link>
            <guid>https://velog.io/@code_j/%EB%94%94%EC%9E%90%EC%9D%B8-%ED%8C%A8%ED%84%B4%EA%B3%BC-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D-%ED%8C%A8%EB%9F%AC%EB%8B%A4%EC%9E%84-%EC%8B%B1%EA%B8%80%ED%86%A4-%ED%8C%A8%ED%84%B4</guid>
            <pubDate>Mon, 02 Jan 2023 05:48:46 GMT</pubDate>
            <description><![CDATA[<p>우선 시작하기에 앞서 해당 학습은 자바스크립트는 <a href="https://playcode.io/new">플레이코드</a> 그리고 자바는 <a href="https://www.tutorialspoint.com/online_java_compiler.php">코딩그라운드(java)</a>에서 진행한다.</p>
<h1 id="디자인-패턴">디자인 패턴</h1>
<p>프로그램을 설계할 때 발생했던 문제점들을 객체 간의 상호 관계 등을 이용하여 해결할 수 있도록 하나의 <code>규약</code> 형태로 만들어 놓은 것을 의미한다.</p>
<h2 id="싱글톤-패턴">싱글톤 패턴</h2>
<p>하나의 클래스에 오직 하나의 인스턴스만 가지는 패턴이다. 하나의 클래스를 기반으로 여러 개의 개별적인 인스턴스를 만들 수 있지만, 그렇게 하지 않고 하나의 클래스를 기반으로 단 하나의 인스턴스를 만들어 이를 기반으로 로직을 만드는 데 쓰이며, 보통 데이터베이스 연결 모듈에 많이 사용한다.</p>
<img src="https://velog.velcdn.com/images/code_j/post/88418911-a342-4769-8ff5-46e270bd4daa/image.png" width="80%" height="50%">


<p>하나의 인스턴스를 만들어 놓고 해당 인스턴스를 다른 모듈들이 공유하며 사용하기 때문에 인스턴스를 생성할 때 드는 비용이 줄어드는 장점이 있다. 하지만 의존성이 높아진다는 단점이 있다.</p>
<pre><code class="language-java">class Singleton {
    private static class singleInstanceHolder {
        private static final Singleton INSTANCE = new Singleton();
    }
    public static Singleton getInstance() {
        return singleInstanceHolder.INSTANCE;
    }

}

public class HelloWorld{

     public static void main(String []args){
        Singleton a = Singleton.getInstance();
        Singleton b = Singleton.getInstance();
        System.out.println(a.hashCode());
        System.out.println(b.hashCode());
        if (a == b) {
            System.out.println(true);
        }
     }
}</code></pre>
<p>그 외에도 Node.js에서 MongoDB를 연결할 때 사용하는 mongoose 모듈도 connect()라는 함수가 싱글톤으로 반환한다. 또한 MySQL을 연결할 때도 같게 하나의 인스턴스로 처리된다.</p>
<h3 id="싱글톤-패턴의-단점">싱글톤 패턴의 단점</h3>
<p>싱글톤 패턴은 TDD(Test Driven Development)를 할 때 걸림돌이 된다. TDD를 할 때 단위 테스트를 주로 하는데, 단위 테스트는 테스트가 서로 독립적이어야 하며 테스트를 어떤 순서로든 실행할 수 있어야 한다.</p>
<p>하지만 싱글톤은 미리 생성된 하나의 인스턴스를 기반으로 구현하는 패턴이므로 각 테스트마다 <code>독립적인</code> 인스턴스를 만들기가 어렵다.</p>
<h2 id="의존성-주입">의존성 주입</h2>
<p>싱글톤은 사용하기 쉽고 굉장히 실용적인지만 모듈 간의 결합을 강하게 만들 수 있다는 단점이 있다. 이때 의존성 주입(DI, Dependency Injection)을 통해 모듈간의 결합을 좀 더 느슨하게 만들어 해결할 수 있다.</p>
<p>의존성은 종속성이라고도 하며 A가 B에 의존성이 있다는 것은 B의 변경 사항에 대해 A 또한 변해야 된다는 것을 의미한다. 메인 모듈이 <code>직접</code> 하위 모듈에 의존성을 주기보다는 중간에 의존성 주입자를 통해 <code>간접적</code>으로 의존성을 주입하는 방식이다. 이를 통해 메인 모듈은 하위 모듈에 대한 의존성이 낮아지게 된며 이를 <code>디커플링 된다</code>라고 표현한다.</p>
<h3 id="의존성-주입-장점">의존성 주입 장점</h3>
<p>모듈들을 쉽게 교체할 수 있는 구조이기 테스팅하기 쉽고 마이그레이션하기도 수월하다. 구현할 때 추상화 레이어를 넣고 이를 기반으로 구현체를 넣어 주기 때문에 의존성 방향이 일관되고, 쉽게 추론 가능하며, 모듈 간의 관계들이 조금 더 명확해진다.</p>
<h3 id="의존성-주입-단점">의존성 주입 단점</h3>
<p>모듈들이 분리되므로 클래스 수가 늘어나 복잡성이 증가되고 약간의 런타임 패널티가 생기기도 한다.</p>
<h3 id="의존성-주입-원칙">의존성 주입 원칙</h3>
<p><code>상위 모듈은 하위 모듈에서 어떠한 것도 가져오지 않아야 하며 둘 다 추상화에 의존한다. 이때 추상화는 세부 사항에 의존하지 말야아 한다.</code> 라는 원칙을 지켜야한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[2023년을 시작하며]]></title>
            <link>https://velog.io/@code_j/2023%EB%85%84%EC%9D%98-%EC%8B%9C%EC%9E%91</link>
            <guid>https://velog.io/@code_j/2023%EB%85%84%EC%9D%98-%EC%8B%9C%EC%9E%91</guid>
            <pubDate>Sun, 01 Jan 2023 10:08:42 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/code_j/post/32cf9898-d0a2-4d49-ad43-d5a5ee554d12/image.jpg" alt=""></p>
<p>오늘의 시작은 백엔드 로드맵으로 시작한다. 위 이미지는  <a href="https://roadmap.sh/backend">roadmap.sh</a>에서 확인할 수 있으며 해당 사이트에서는 해당 로드맵에 보이는 모든 부분에 부가적인 설명을 확인할 수 있으니 들어가 보는 것을 추천한다.</p>
<p>왜 2023년의 시작을 백엔드 개발 로드맵으로 시작했는가 물어본다면 내가 앞으로 어떤 개발자가 될지 보여주는 흐름도라고 보면 될 것이다. 물론 저 로드맵에 있는 모든 기술을 다룰 수는 없겠지만 어떻게 스스로 계발할지에 대한 흐름은 잡을 수 있기 때문이다.</p>
<h3 id="앞으로-무엇을-공부할-것인가">앞으로 무엇을 공부할 것인가?</h3>
<p>지금까지는 하나 꽂히면 그냥 시작하기 바빴던 것 같다. 물론 정리는 하지 않고 바로 적용해보며 구조를 파악하고 어떤 기능을 하는지 확인하는 방법을 주로 사용했다. 결론부터 말하자면 시간이 지나면 잊힌다. 내가 어떻게 적용했고 환경은 어떻게 세팅했는지 기억이 나지 않는다. 말 그대로 그냥 해보기만 한 것이다.</p>
<p>현재 나에게 부족한 것부터 시작할 계획이다. 개발 경력에 비하여 부끄럽지만, 대학교 전공 시간에 배웠던 <code>CS 기초 지식</code>을 다시 학습할 생각이다. 면접을 진행하며 조금만 질문이 깊어지면 두루뭉술하게 알고 있던 나의 지식 기반을 들키고 말았다.</p>
<p>우선 내가 학습하기 위해 구입한 도서들이다. </p>
<p>CS 지식 : <a href="https://search.shopping.naver.com/book/catalog/32478035848?cat_id=50010920&amp;frm=PBOKPRO&amp;query=%EB%A9%B4%EC%A0%91%EC%9D%84+%EC%9C%84%ED%95%9C+CS&amp;NaPm=ct%3Dlc8jagf4%7Cci%3Deadfc8ea23efb365f656be9dc5320624b1c62860%7Ctr%3Dboknx%7Csn%3D95694%7Chk%3D9b0592b65df2e4527f43ac4c37f86bf9f65b4a27">면접을 위한 CS 전공지식 노트</a>
코딩테스트 : <a href="https://search.shopping.naver.com/book/catalog/32441237189?cat_id=50010920&amp;frm=PBOKPRO&amp;query=%EC%9D%B4%EA%B2%83%EC%9D%B4+%EC%B7%A8%EC%97%85%EC%9D%84+%EC%9C%84%ED%95%9C+%EC%BD%94%EB%94%A9+%ED%85%8C%EC%8A%A4%ED%8A%B8%EB%8B%A4&amp;NaPm=ct%3Dlcd70oyo%7Cci%3Da1ce06335933da6a6f6fb4a2f25edd5b7f822240%7Ctr%3Dboknx%7Csn%3D95694%7Chk%3Dbb6981d1f9f61b82f6843d2fd5b4165fb6b7545a">이것이 취업을 위한 코딩 테스트다 with 파이썬</a>
파이썬 심화 : <a href="https://search.shopping.naver.com/book/catalog/32464820688?cat_id=50010920&amp;frm=PBOKPRO&amp;query=%ED%8C%8C%EC%9D%B4%EC%8D%AC+%EC%BD%94%EB%94%A9%EC%9D%98+%EA%B8%B0%EC%88%A0&amp;NaPm=ct%3Dlcd71gqo%7Cci%3D2a247196ea08d55d3ad63921ede4c45ca745cfee%7Ctr%3Dboknx%7Csn%3D95694%7Chk%3Da8db051e8714fcdb990362c8730b03d344272a85">Effective Python 2nd 이펙티브 파이썬 : 파이썬 코딩의 기술</a></p>
<p>우선 이렇게 3개의 책으로 학습을 진행할 예정이다. 예전에 내가 신일 때 함께 일하던 선배의 말이 기억난다. <code>5년 차가 되면 자기가 아는 것이 끝이라고 생각하는 사람들이 많아진다. 그때 본인이 크게 성장의 필요성을 느낄 때가 와야 성장할 수 있다.</code>라고 말해주셨다.</p>
<p>그때는 당연히 취업한 상황이고 나는 배울 게 많다는 생각에 잘 알지 못했었다. 주어진 업무를 처리하는 것만 해도 하루가 부족한 기간이었다. 그렇게 1년 2년이 지나니 현재에 내가 되어있었다. 그렇다. 나는 위에서 선배가 말해주었던 사람이 되어있었다. 내가 일할 때 부족함이 없다고 생각하고 새로운 도전을 좋아하지만, 그냥 겉핥기에 불가했던 것이었다. </p>
<p>절대 그렇게 되지 않을거라고 생각했다. 나는 잘할거라고 그래 일은 열심히 잘했다. 맡은 업무 잘 끝내며 좋은 평가를 받았던 그 것이 마약이었다. 나를 그 당시에 만족하게 만들던 행복한 마약이었다. 이제라도 깨달은게 다행이라고 생각한다. 기초부터 다시 점검하며 쌓아올리자. 최신의 기술도 중요하지만 그 기반이 되는 기초가 더욱 중요한 것이다.</p>
<h3 id="앞으로-어떻게-공부할-것인가">앞으로 어떻게 공부할 것인가?</h3>
<p>위에서도 말했지만 나는 그냥 잡히는 대로 공부했다. 유튜브에서 공부하는 방법을 찾아보며 이렇게 해야지 생각하지만, 행동으로 옮기지는 못했었다. 이제는 해야 한다. 하지 않으면 안된다. 지금 생각하는 방법은 위 책 3권을 하루에 나눠서 공부하는 것이다.</p>
<p>CS 전공지식 2시간 코딩테스트 2시간 파이썬 심화 2시간 이런 식으로 말이다. 공부하며 더 좋은 방법이 있다면 적용해볼 것이다. 지금 당장 공부하기 위한 것이 아니라 계속 지속해서 사용할 수 있는 공부법을 터득해야 한다. 그래서 나의 일상이 되어야 한다.</p>
<p>오늘도 이래저래 떠든 거 같지만, 나의 공간이니 뭐 누가 읽을 것일지는 모르겠지만 미안하게도 이렇게 생각나는 말을 다 떠들어야 속이 좀 시원해지니 어쩔 수 없다. 추후 새로운 공부법에 관한 내용이나 공부한 내용을 정리하여 블로그에 하나씩 게시하도록 하겠다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[2023년을 준비하며...]]></title>
            <link>https://velog.io/@code_j/2023%EB%85%84%EC%9D%84-%EC%A4%80%EB%B9%84%ED%95%98%EB%A9%B0</link>
            <guid>https://velog.io/@code_j/2023%EB%85%84%EC%9D%84-%EC%A4%80%EB%B9%84%ED%95%98%EB%A9%B0</guid>
            <pubDate>Sat, 31 Dec 2022 13:03:31 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>최근 면접을 보며 까마득하게 잊고 있던 나의 모습을 다시 마주하게 되었다. </p>
</blockquote>
<p>2022년이 이렇게 빨리 지나갈 줄은 꿈에도 몰랐다. 오늘이 2022년 마지막 날이다. 2020년 더존비즈온으로 이직하면서 새로운 도전에 설렜었다. 하지만, 2년이 넘는 외로운 타지 생활과 만족스럽지 않은 회사의 모습을 보며 새롭게 이직을 선택하게 되었다.</p>
<p>이게 맞는 선택인가 많이 고민했다. 자신이 있었다. 나는 일을 잘하는 사람이라고 생각했기 때문이다. 현실을 직시하기 전까지는 말이다. 2022년 8월 12일 퇴사 후 4개월의 시간 동안 회사 16곳에 지원하였지만, 서류 탈락 9번, 코딩테스트 탈락 3번, 과제 탈락 1번, 1차 면접 탈락 3번이라는 처절한 결과를 맞이하고 현실의 벽을 느끼고 말았다.</p>
<p>이제 상상하던 나의 모습이 아닌 현실적인 모습을 마주하게 된 것이다. 물론 실패를 통해 내가 뭘 해야 할지 알게 되었다. 항상 생각했었다. 코딩테스트가 실제로 개발하는 데 얼마나 도움이 되길래 보는 것이냐고 말이다. 이 생각은 나의 부족한 점을 회피하기 위한 하나의 자기 위로였다고 말이다.</p>
<p>퇴사 후 4개월의 시간을 이것을 깨닫기 위한 시간이었다고 생각하기로 했다. 사실 아깝다고 생각했다. 4개월이라는 시간을 내가 좀 더 빨리 깨달았다면 제대로 사용할 수 있지 않았느냐고 말이다. 근데 이미 지나간 시간을 생각하고 후회하면 어쩌겠는가 돌아갈 수 없는 게 시간인걸...</p>
<p>그렇다고 이 4개월이라는 시간을 허투루 사용하지는 않았다. 가족을 위해 투자한 시간도 있었고 연인과 추억을 쌓기도 했으며 공부도 꾸준히 했다. 그 공부의 방향이 잘못된 걸 이제 알았을 뿐이다. 어떤 시간이든 의미 없는 시간은 없으므로 긍정적으로 생각하기로 했다.</p>
<p>2023년에는 제대로 된 계획을 세우고 진행할 생각이다. 하나를 계속 붙잡는 게 아니라 여러 가지를 한 번에 잡을 방법으로 말이다. 돌이켜보니 하루에 5시간 이상 공부를 했지만 나에게 남은 건 무엇인가 생각해보면 딱 집어서 말하기 어렵다. 이런 생각을 할 때면 나 자신을 미워하게 된다. 왜 똑똑하게 공부하지 못했을까 나의 미래를 위해 어떤 게 필요한지 알지 못했느냐고 말이다.</p>
<p>그냥 2022년이 끝난다고 생각하니 아쉬움에 이렇게 글을 남기게 되었다. 현실의 쓴맛을 봤으니 이 글에서 나의 부정적인 생각을 다 내려놓고 이제는 달콤함 나의 미래를 위해 긍정적인 생각만 할 것이다. 또 나약해질 나를 위해 이렇게 기록한다.</p>
<hr>
<h3 id="넌-나약하지-않다-그저-잠시-길을-잃었을-뿐-항상-해왔던-것처럼-다시-길을-찾아-도전하자-그게-진정한-너의-모습이다"><em><strong>넌 나약하지 않다. 그저 잠시 길을 잃었을 뿐 항상 해왔던 것처럼 다시 길을 찾아 도전하자. 그게 진정한 너의 모습이다.</strong></em></h3>
<hr>
]]></description>
        </item>
        <item>
            <title><![CDATA[[docker] Mac M1에서 SCRAM 인증 문제]]></title>
            <link>https://velog.io/@code_j/docker-Mac-M1%EC%97%90%EC%84%9C-SCRAM-%EC%9D%B8%EC%A6%9D-%EB%AC%B8%EC%A0%9C</link>
            <guid>https://velog.io/@code_j/docker-Mac-M1%EC%97%90%EC%84%9C-SCRAM-%EC%9D%B8%EC%A6%9D-%EB%AC%B8%EC%A0%9C</guid>
            <pubDate>Sun, 25 Dec 2022 11:56:23 GMT</pubDate>
            <description><![CDATA[<p>Pycon Korea 2021에서 신동현님이 진행하신 <a href="https://www.youtube.com/watch?v=mTmlhcYvwwc&amp;t=759s">API Response 효율적으로 테스트하기</a>를 보며 테스트를 진행하는데 docker 빌드를 진행하면서 발생한 문제에 대한 글이다.</p>
<p>동현님이 Github를 통해 공유하신 <a href="https://github.com/qu3vipon/pyconkr2021-APITest">프로젝트</a>를 클론 받아서 구동하며 발생하였으며 아래와 같이 오류가 발생하였다.</p>
<pre><code class="language-shell">django.db.utils.OperationalError: SCRAM authentication requires libpq version 10 or above</code></pre>
<p>구글에 해당 문제 대해 찾아보니 <a href="https://stackoverflow.com/questions/62807717/how-can-i-solve-postgresql-scram-authentication-problem">Stack Overflow</a>에서 공유된 내용을 확인해보니 M1 칩을 사용하는 경우에 발생하는 문제로 보였다.</p>
<p>해당 문제를 해결하려면 빌드를 진행하기 전에 환경 변수 값을 아래와 같이 명령하면 된다.</p>
<pre><code class="language-shell"> export DOCKER_DEFAULT_PLATFORM=linux/amd64</code></pre>
<p>다시 시도해보면 정상적으로 테스트가 진행되는 것을 확인할 수 있었다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[python] 문자열 아스키코드(ASCII) 변환]]></title>
            <link>https://velog.io/@code_j/python-%EB%AC%B8%EC%9E%90%EC%97%B4-%EC%95%84%EC%8A%A4%ED%82%A4%EC%BD%94%EB%93%9CASCII-%EB%B3%80%ED%99%98</link>
            <guid>https://velog.io/@code_j/python-%EB%AC%B8%EC%9E%90%EC%97%B4-%EC%95%84%EC%8A%A4%ED%82%A4%EC%BD%94%EB%93%9CASCII-%EB%B3%80%ED%99%98</guid>
            <pubDate>Thu, 22 Sep 2022 06:51:50 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>문자열을 간단하게 아스키코드로 변환하는 방법을 찾다가 알게되어 작성하게됨</p>
</blockquote>
<h2 id="ord-함수">ord 함수</h2>
<p>하나의 유니코드 문자를 나타내는 문자열이 주어지면 해당 문자의 유니코드 코드 포인트를 나타내는 정수를 돌려준다. 예를 들어, ord(&#39;a&#39;)는 정수 97을 반환하고 ord(&#39;€&#39;)(유로 기호)는 8364를 반환한다. 이 함수는 chr()의 반대이다.</p>
<pre><code class="language-bash">&gt; A
65</code></pre>
<h2 id="chr-함수">chr 함수</h2>
<p>유니코드 코드 포인트가 정수 i 인 문자를 나타내는 문자열을 돌려준다. 예를 들어, chr(97)은 문자열 &#39;a&#39;를 돌려주고, chr(8364)는 문자열 &#39;€&#39;를 돌려준다. 이 것은 ord()의 반대다.</p>
<p>인자의 유효 범위는 0에서 1,114,111(16진수로 0x10FFFF)까지다. i가 이 범위 밖에 있을 때 ValueError가 발생한다.</p>
<pre><code class="language-bash">&gt; 65
A</code></pre>
<h3 id="참조">참조</h3>
<p><a href="https://docs.python.org/ko/3/library/functions.html?highlight=ord#ord">python 공식문서 - ord</a>
<a href="https://docs.python.org/ko/3/library/functions.html?highlight=chr#chr">python 공식문서 - chr</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[git] push 한 commit 삭제하는 방법]]></title>
            <link>https://velog.io/@code_j/push-%ED%95%9C-commit-%EC%82%AD%EC%A0%9C%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95</link>
            <guid>https://velog.io/@code_j/push-%ED%95%9C-commit-%EC%82%AD%EC%A0%9C%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95</guid>
            <pubDate>Tue, 20 Sep 2022 08:16:38 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>로컬에서 개발하면서 push한 commit을 지우고 싶은 경우가 있다.</p>
</blockquote>
<h3 id="git-log-확인">git log 확인</h3>
<pre><code class="language-bash">&gt; git log 

commit cfd7956eeaacbab8adc5e4085633a11705e557f1 (HEAD -&gt; master, origin/master, origin/HEAD)
Author: author (author@mail)
Date:   Tue Sep 20 16:06:43 2022 +0900

    message...

&gt; git log --oneline

cfd7956 message...
7ab76e0 message...

&gt; git reflog   

cfd7956 (HEAD -&gt; master, origin/master, origin/HEAD) HEAD@{0}: message...
7b640f1 HEAD@{1}: message...
bff0af3 HEAD@{2}: message...
</code></pre>
<h3 id="마지막-commit을-삭제하고-싶은-경우">마지막 commit을 삭제하고 싶은 경우</h3>
<pre><code class="language-bash">- 가장 마지막에 push한 commit을 지우기 위해 해당 명령어를 입력한다.
&gt; git reset HEAD^

- 다시 push해서 commit 삭제 상태를 적용한다. (-f는 force로 강제를 의미한다.)
&gt; git push -f origin master</code></pre>
<h3 id="특정-commit을-삭제하고-싶은-경우">특정 commit을 삭제하고 싶은 경우</h3>
<p>위에서 git log 보는 법에서 나온 것 처럼 git commit에 해당한 ID와 HEAD를 지칭하는 값으로 돌릴 수 있다.</p>
<pre><code class="language-bash">- 되돌리고 싶은 위치를 지정해준다.
&gt; git reset --hard 7ab76e0 (또는 HEAD@{1})

- 반영해주면 끝난다.
&gt; git push -f origin master
</code></pre>
<h3 id="마무리">마무리</h3>
<p>Git에 관해서는 공부가 많이 필요한 것 같다. reset 옵션에 대한 정리도 필요할 것 같다. 🙂</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[일상] Tistory에서 Velog로 바꾼 이유]]></title>
            <link>https://velog.io/@code_j/Tistory%EC%97%90%EC%84%9C-Velog%EB%A1%9C-%EB%B0%94%EA%BE%BC-%EC%9D%B4%EC%9C%A0</link>
            <guid>https://velog.io/@code_j/Tistory%EC%97%90%EC%84%9C-Velog%EB%A1%9C-%EB%B0%94%EA%BE%BC-%EC%9D%B4%EC%9C%A0</guid>
            <pubDate>Tue, 20 Sep 2022 05:47:19 GMT</pubDate>
            <description><![CDATA[<h2 id="편리한-사용법">편리한 사용법</h2>
<blockquote>
<p>난 그냥 쉽게 글을 쓰고 싶었다고 한다 :)</p>
</blockquote>
<p> Tistory를 사용한지는 얼마 되지 않았지만 블로그를 시작하자는 생각을 하면서 간단하게 사용을 해봤다. 간단하게 경험해본 바로는 Velog가 사용하기 더 쉽고 직관적이다.</p>
<p> HTML, CSS 등 수정하면서 커스텀하기에는 Tistory가 좋은것 같지만 뭐 더 사용해봐야 알겠지만 Velog도 여러 기능을 지원하지 않을까 싶다.</p>
<p> 지극히 개인적으로는 Velog가 더 편하다는 생각이 글을 작성하면서 바로 들었다. 글을 작성하면 우측에 바로 미리보기를 보여주기 때문이지 않을까 생각해본다.</p>
<h2 id="꾸미기-자신-없어">꾸미기 자신 없어...</h2>
<blockquote>
<p>어릴 때는 그래도 미술을 어느 정도 잘했던 거 같은데... 아니면 말고</p>
</blockquote>
<p>개인적으로 Tistory를 시작하면서 느낀 것은 뭔가 꾸며야 할 것 같다는 것이다. 남들에게 보여주기 글을 작성하는 것은 아니지만 뭔가 모를 압박이 있었다. <del>(너만 그래)</del> 아무튼 테마 자체도 Velog가 더 마음에 들었다고 해야 할까 깔끔하다. 어두운 계열을 좋아해서 그런지 그냥 좋았다. 물론 밝은 테마도 가능하지만... ㅎㅎ</p>
<p>그리고 마크다운 형식이기 때문에 노션을 사용하는 나로서는 더 쉽게 접근할 수 있었다. 결론은 그냥 쓰던 거 쓰고 싶고 복잡하지 않고 간단한 게 좋다는 의미이다.</p>
<h2 id="이동하기-최적의-조건">이동하기 최적의 조건</h2>
<p>아무래도 Tistroy에 글을 쓰기 시작한 것도 얼마 되지 않았기 때문에 글을 이동하는 데에는 큰 어려움이 없을 거라 생각이 들었다. 지금 사용하면서도 음... 옮기길 잘한 거 같다는 생각이다. 나의 일상이나 공부한 내용에 대한 기록을 하나씩 채워가자는 나와 약속을 하며 첫 번째 글을 마무리하겠다.</p>
]]></description>
        </item>
    </channel>
</rss>