<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>jeli.log</title>
        <link>https://velog.io/</link>
        <description>웹개발 성장 일기</description>
        <lastBuildDate>Thu, 07 Mar 2024 12:27:52 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <copyright>Copyright (C) 2019. jeli.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/essssk___" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[애자일 방법론]]></title>
            <link>https://velog.io/@essssk___/%EC%95%A0%EC%9E%90%EC%9D%BC-%EB%B0%A9%EB%B2%95%EB%A1%A0</link>
            <guid>https://velog.io/@essssk___/%EC%95%A0%EC%9E%90%EC%9D%BC-%EB%B0%A9%EB%B2%95%EB%A1%A0</guid>
            <pubDate>Thu, 07 Mar 2024 12:27:52 GMT</pubDate>
            <description><![CDATA[<p>정처기 필기를 준비하면서 접했던 애자일 방법론에 대해 포스팅해보려고 한다.
<del>어느날 클린코드책 표지를 봤는데 거기에도 애자일 단어가 있더라. 전혀 몰랐다.</del> 하여튼 생각보다 자주 보이는 애자일 방법론에 대해 알아보자. </p>
<h2 id="애자일-방법론의-등장-배경">애자일 방법론의 등장 배경</h2>
<h4 id="변화하는-요구사항에-대한-대응-부족">변화하는 요구사항에 대한 대응 부족</h4>
<p>소프트웨어 개발 프로젝트는 오랜 기간에 걸쳐 진행되는 경우가 많으며, 이 과정에서 시장의 요구사항이나 기술의 변화로 인해 초기 요구사항이 변경될 수 있다. 폭포수 모델과 같은 전통적 방법론은 이러한 중간 변경사항을 수용하는 데 한계가 있었다.</p>
<h4 id="고객과의-소통-부족">고객과의 소통 부족</h4>
<p>전통적인 방법론에서는 개발 초기 단계에서만 고객의 요구사항을 집중적으로 수집하고, 그 이후에는 고객과의 소통이 상대적으로 줄어들었다. 따라서 최종 제품이 고객의 현재 요구사항을 반영하지 못하는 경우가 많았다.</p>
<h4 id="프로젝트의-비효율성">프로젝트의 비효율성</h4>
<p>폭포수 모델에서는 각 단계가 선형적으로 진행되며, 이전 단계가 완전히 끝나야만 다음 단계로 넘어갈 수 있었다. 기존의 방식에서는 소프트웨어 개발의 유연성을 제한하고, 시간과 자원의 낭비를 초래할 수 있는 문제점이 있었다.</p>
<h4 id="팀워크와-협업의-중요성-간과">팀워크와 협업의 중요성 간과</h4>
<p>전통적인 방법론들은 문서 작성과 프로세스 준수에 중점을 두며, 이는 팀의 창의성과 문제 해결 능력을 제한하는 결과를 낳았다.</p>
<p>2001년, 소프트웨어 개발에 관련된 17명의 전문가들이 모여 &quot;애자일 소프트웨어 개발 선언문&quot;을 발표했다. 이 선언문은 소프트웨어 개발 과정에서 가장 중요하게 여겨야 할 네 가지 핵심 가치를 제시하며, 소프트웨어 개발의 새로운 패러다임으로서 애자일 방법론을 정립했다. </p>
<h2 id="애자일-방법론의-핵심-가치">애자일 방법론의 핵심 가치</h2>
<ol>
<li>개인과 상호 작용을 프로세스와 도구보다 중요하게 여긴다.</li>
<li>작동하는 소프트웨어를 포괄적인 문서보다 중요하게 여긴다.</li>
<li>고객과의 협력을 계약 협상보다 중요하게 여긴다.</li>
<li>계획을 따르기보다 변화에 대응하는 것을 중요하게 여긴다.</li>
</ol>
<p>애자일 방법론은 개발 프로세스를 더 유연하고, 고객 중심적이며, 팀 협업에 초점을 맞춘 방식으로 전환하려는 목표를 가지고 있다.</p>
<h2 id="애자일-방법론의-주요-기법">애자일 방법론의 주요 기법</h2>
<ol>
<li><p>스크럼 (Scrum)
스크럼은 소규모 팀이 짧은 사이클(일반적으로 2-4주)인 스프린트를 통해 특정 제품 기능을 개발하는 반복적인 방식이다. 스크럼 프로세스는 일일 스크럼 회의, 스프린트 계획 회의, 스프린트 리뷰 및 스프린트 회고 등의 활동으로 구성되며, 빠른 피드백 반영과 변화에 유연한 대응을 가능하게 한다.</p>
</li>
<li><p>익스트림 프로그래밍 (Extreme Programming, XP)
XP는 고객의 만족을 최우선으로 하는 소프트웨어 개발 방법론으로, 페어 프로그래밍, 지속적인 통합, 테스트 주도 개발(TDD), 리팩토링 및 고객 피드백의 지속적인 통합 등을 강조한다. 이를 통해 소프트웨어 품질을 향상시키고, 개발 과정에서 발생할 수 있는 리스크를 줄인다.</p>
</li>
<li><p>칸반 (Kanban)
칸반은 작업 항목의 시각적 관리를 통해 생산성을 향상시키는 방법론으로, &quot;할 일&quot;, &quot;진행 중&quot;, &quot;완료&quot; 등의 칼럼을 포함하는 칸반 보드를 사용하여 작업의 흐름을 관리한다. 칸반은 작업의 우선순위 설정, 작업 흐름의 시각화, 진행 중인 작업의 양 제한 등을 통해 효율적인 작업 진행을 돕는다.</p>
</li>
<li><p>린 소프트웨어 개발 (Lean Software Development)
린 소프트웨어 개발은 낭비를 최소화하고 가치 창출을 극대화하는 것에 중점을 둔다. 원가 절감, 시간 단축, 고객 가치 증대를 목표로 하며, 가치 흐름 매핑, 불필요한 기능 제거, 지속적인 개선 등의 원칙을 따른다.</p>
</li>
<li><p>피처 드리븐 개발 (Feature Driven Development, FDD)
FDD는 프로젝트를 구성하는 작은 기능(피처) 단위로 개발을 진행하는 방법론이다. 개발 과정은 모델링, 기능 목록 작성, 기능별 계획 및 구축, 그리고 정기적인 빌드 및 통합으로 이루어진다. FDD는 각 피처의 설계와 구현에 초점을 맞추며, 팀의 협업과 역할 분담을 강조하는 특징이 있다.</p>
</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[클린코드의 필요성....]]></title>
            <link>https://velog.io/@essssk___/%ED%81%B4%EB%A6%B0%EC%BD%94%EB%93%9C%EC%9D%98-%ED%95%84%EC%9A%94%EC%84%B1</link>
            <guid>https://velog.io/@essssk___/%ED%81%B4%EB%A6%B0%EC%BD%94%EB%93%9C%EC%9D%98-%ED%95%84%EC%9A%94%EC%84%B1</guid>
            <pubDate>Sun, 25 Feb 2024 06:46:44 GMT</pubDate>
            <description><![CDATA[<p>기존 개발해놨던 페이지에 추가 기능과 함께 기존 기능을 조금 변경하게 되었다. 기존 기능을 별도의 모드로 변경하고 기본 모드를 추가하는 내용인데, 요구사항이 어려운 게 아니라고 생각했는데도 적용중에 기존 기능이 꼬여서 시간 대비 성과가 없던 것 같다.</p>
<p>바쁘다는 핑계로 외면하고 지냈던 클린코드의 개념을 정리하는 시간을 가져보자.</p>
<h2 id="클린-코드clean-code">클린 코드(Clean Code)</h2>
<p>클린코드(Clean Code)는 읽기 쉽고 이해하기 쉬운 코드를 작성하는 것을 의미한다. 궁극적인 목표는 유지보수 시간의 단축이다. 코드를 이해하고 수정하는데 걸리는 시간이 줄어드는 만큼 새로운 기능 구현 및 배포가 유리하다. 개발한 사람 뿐만 아니라 프로젝트 참여자와의 협업에도 필수적인 이유다.</p>
<h3 id="클린코드-주요-원칙">클린코드 주요 원칙</h3>
<h4 id="1-의미-있는-변수와-함수명">1. 의미 있는 변수와 함수명</h4>
<p>변수와 함수의 이름이 명확하고 의미있는 경우 코드를 읽는 사람은 해당 변수나 함수의 역할과 의도를 더 쉽게 파악할 수 있다. 코드를 읽는 사람에게 추가적인 설명을 할 필요가 없게된다. </p>
<p><strong>좋은 함수를 만드려면?</strong></p>
<ul>
<li>함수이름은 동사로 구성되는 것이 좋다. 예를 들어, &#39;userInfo&#39;보다는 &#39;GetUserInfo&#39;가 좋은 함수 이름이다.</li>
<li>함수의 전달할 인수 개수는 최소한으로, 가능한 3개 이하로 유지하는 것이 좋다. 너무 많은 인수를 사용하면 코드의 복잡성이 증가하여 유지보수가 어렵기 때문이다. 전달할 인수가 많다면, 특정 인수를 그룹화하여 객체로 전달하는 방식을 사용하는 것이 좋다.</li>
<li>함수는 한 가지 일만 잘 수행할 수 있도록 한다.</li>
</ul>
<pre><code>// Bad
int x = 10; // x가 의미하는 바를 정확히 이해하기 어려움

// Good
int userAge = 20; // 사용자 나이를 뜻함을 명확하게 보여줌

// Bad
function calc(a, b) { 
    return a * b; // 무엇을 계산하는 것인지 명확히 알기 어려움
}

// Good
function calculateArea(length, width) {
    return length * width; // 넓이 계산
}
</code></pre><h4 id="2-가독성-좋은-코드">2. 가독성 좋은 코드</h4>
<p>적절한 들여쓰기와 줄바꿈이 있는게 코드 읽기에 훨씬 수월하다. </p>
<pre><code>// bad
const calculate=(a,b)=&gt;{let result=0;if(a&gt;10){result=a*b;}return result;}

// good
const calculateResult = (a, b) =&gt; {
    let result = 0;
    if (a &gt; 10) {
        result = a * b;
    }
    return result;
};</code></pre><h4 id="3-주석은-필요한-때만">3. 주석은 필요한 때만</h4>
<p>변수명과 함수명 및 코드에 내용이 명확하게 설명되어 있다면 너무 좋겠지만, 부득이하게 코드 자체만으로는 이해하기 난해하거나 동작이 명확하지 않을 경우 추가 주석을 써주는 것이 좋다. 코드의 의도와 동작방식을 적절히 써주는 것이 좋다. </p>
<h4 id="4-간결한-코드-유지">4. 간결한 코드 유지</h4>
<p>복잡한 조건문이나 반복문이 단순하고 직관적인 로직으로 수정할 수 있다면 활용하는 것이 좋다. 함수는 한 가지의 기능을 수행하도록 하는 것이 좋은데, 재사용성을 고려해서 함수선언을 해야한다.</p>
<pre><code>function isAdult(age) {
    if (age &gt;= 18) {
        return true;
    } else {
        return false;
    }
}

function isAdult(age) {
    return age &gt;= 18;
}

const isAdult = (age) =&gt; age &gt;= 18;</code></pre><h4 id="5-모듈화">5. 모듈화</h4>
<p>모듈화는 소프트웨어를 작은 단위로 분할하여 각각의 모듈이 독립적으로 동작하고 재사용될 수 있도록 하는 것을 의미한다. 모듈간의 의존성이 작아 변경이 발생했을 때 유지보수가 수월해지는 장점이 있다.</p>
<p>전체 소프트웨어가 유저 관리 시스템으로 구성되어 있다고 가정할 경우, 이 시스템은 회원가입, 로그인, 프로필 수정 등의 기능을 포함한다고 할 때 아래와 같이 모듈화할 수 있다.</p>
<p>회원가입 모듈: 사용자의 정보를 입력받고 회원가입을 처리하는 모듈
(이메일 중복 검사, 비밀번호 유효성 검사 등의 기능을 포함)</p>
<p>로그인 모듈: 사용자의 인증을 처리하는 모듈
(이메일과 비밀번호를 검사하여 로그인을 허용하거나 거부)</p>
<p>프로필 수정 모듈: 사용자의 프로필 정보를 수정하는 모듈
(사용자의 프로필 사진 업로드, 닉네임 변경 등의 기능을 제공)</p>
<h4 id="6-리팩토링을-통한-코드-개선">6. 리팩토링을 통한 코드 개선</h4>
<p>일반적으로 코드를 짤 때, 처음부터 깨끗하게 짜려고 하면 맘처럼 잘 되지 않는다. 처음부터 깨끗하게 짜려고 할 필요 없이 동작할 수 있는 코드를 먼저 구현하고, 마지막에 코드를 정리하는 방식으로 하도록 하자.</p>
<h4 id="참고링크">참고링크</h4>
<p><a href="https://yozm.wishket.com/magazine/detail/2415/">https://yozm.wishket.com/magazine/detail/2415/</a>
<a href="https://medium.com/naver-cloud-platform/%EB%84%A4%EC%9D%B4%EB%B2%84%ED%81%B4%EB%9D%BC%EC%9A%B0%EB%93%9C-%EA%B0%9C%EB%B0%9C%EC%9E%90-%EC%8A%A4%ED%86%A0%EB%A6%AC-%EC%A2%8B%EC%9D%80-%EC%BD%94%EB%93%9C%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%BC%EA%B9%8C-%ED%81%B4%EB%A6%B0%EC%BD%94%EB%93%9C-%EC%9D%B4%EC%95%BC%EA%B8%B0-c7811f73a46b">https://medium.com/naver-cloud-platform/%EB%84%A4%EC%9D%B4%EB%B2%84%ED%81%B4%EB%9D%BC%EC%9A%B0%EB%93%9C-%EA%B0%9C%EB%B0%9C%EC%9E%90-%EC%8A%A4%ED%86%A0%EB%A6%AC-%EC%A2%8B%EC%9D%80-%EC%BD%94%EB%93%9C%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%BC%EA%B9%8C-%ED%81%B4%EB%A6%B0%EC%BD%94%EB%93%9C-%EC%9D%B4%EC%95%BC%EA%B8%B0-c7811f73a46b</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[정처기 필기 오답 정리하기]]></title>
            <link>https://velog.io/@essssk___/%EC%A0%95%EC%B2%98%EA%B8%B0-%ED%95%84%EA%B8%B0</link>
            <guid>https://velog.io/@essssk___/%EC%A0%95%EC%B2%98%EA%B8%B0-%ED%95%84%EA%B8%B0</guid>
            <pubDate>Thu, 15 Feb 2024 23:13:40 GMT</pubDate>
            <description><![CDATA[<p>정보처리기사 합격은 올해 목표중에 하나다.
지난 1월말 접수 때만 해도 2월 21일? 충분하지 했는데 준비된 것이 없는데 일주일도 남지 않았다. <del>진짜 말도안된다..ㅠㅠ</del></p>
<p>부랴부랴 문제를 풀어보고 있는데, 자주 틀리는 문제 위주로 간단하게 내용정리를 해보고자 한다.</p>
<h2 id="ddl-dcl-dml">DDL, DCL, DML</h2>
<h3 id="ddl-데이터-정의어data-define-language">DDL: 데이터 정의어(Data Define Language)</h3>
<ul>
<li>스키마, 도메인, 테이블, 뷰, 인덱스를 정의(create)하거나 변경(alter), 삭제(drop)할 때 사용하는 언어</li>
</ul>
<h3 id="dml-데이터-조작어data-manipulation-language">DML: 데이터 조작어(Data Manipulation Language)</h3>
<ul>
<li>select, insert, delete, update</li>
</ul>
<h3 id="dcl-데이터-제어어data-control-language">DCL: 데이터 제어어(Data Control Language)</h3>
<ul>
<li>데이터 사용권한 관리에 사용하는 언어</li>
<li>COMMIT(저장), ROLLBACK(복구), GRANT(사용권간 부여), REVOKE(사용권한 취소)</li>
</ul>
<h2 id="degree-tuple-domain">Degree, Tuple, Domain</h2>
<h3 id="degree">Degree</h3>
<ul>
<li>속성, 차수, 데이터 필드</li>
<li>데이터베이스를 구성하는 가장 작은 논리적 단위</li>
<li>개체의 특성 기술</li>
</ul>
<h3 id="tuple">Tuple</h3>
<ul>
<li>레코드, 카디널리티(Cardinality), 기수</li>
<li>속성의 모임</li>
<li>한 릴레이션에 포함된 튜플 사이에는 순서가 있다(X)</li>
</ul>
<h3 id="domain">Domain</h3>
<ul>
<li>하나의 속성이 가질 수 있는 같은 타입의 원자(Atomic)값들의 집합</li>
<li>속성이 가질 수 있는 값 종류(학년이라면 1,2,3,4 .. )</li>
</ul>
<p>릴레이션 R의 차수가 4 카디널리티 5, 릴레이션 S의 차수가 6 카디널리티 7일때 두개의 릴레이션 카디션 프로덕트(두 테이블 관계에서의 모든 경우의 수)한 결과의 새로운 릴레이션 차수와 카디널리티? -&gt; 차수(속성, 필드)는 4+6=10, 카디널리티는 5*7 = 35</p>
<h2 id="개체-관계-다이어그램erd-entity-relationship-diagram">개체 관계 다이어그램(ERD; Entity-Relationship Diagram)</h2>
<p>: 피터 첸 표기법(기본적,E-R 모델), 정보 공학 표기법, 바커 표기법</p>
<ul>
<li>사각형(개체), 마름모(관계), 이중타원(다중 속성), 타원(속성), 밑줄타원(기본키) </li>
<li>삼각형 X, 오각형 X</li>
</ul>
<h2 id="로킹locking">로킹(Locking)</h2>
<ul>
<li>트랜잭션(transaction)이 접근하고자 하는 데이터를 잠가(lock) 다른 트랜잭션이 접근하지 못하도록 하는 병행 제어 기법</li>
<li>로킹 단위(한번에 로킹할 수 있는 객체의 크기): 필드, 레코드, 테이블, 파일, DB 모두 로킹 단위</li>
<li>로킹 단위가 커지면 로크는 작고 병행은 단순(수준 낮음), 오버헤드 감소, DB 공유도 감소 </li>
</ul>
<h2 id="정규화normalization">정규화(Normalization)</h2>
<p>: 일관성, 정확성, 단순성, 비중복성, 안정성
: 데이터 중복을 배제하여 이상(Anomaly)의 발생 방지 및 자료 저장 공간의 최소화
: 반정규화 - 정규화된 엔티티, 속성, 관계를 시스템의 성능 향상과 개발 운영의 단순화를 위해 중복, 통합, 분리 등을 수행하는 데이터 모델링 기법</p>
<h3 id="정규화-과정도부이결다조">정규화 과정(도부이결다조)</h3>
<ul>
<li>1정규형: 도메인이 원자 값</li>
<li>2정규형: 부분적 함수 종속 제거(부분적 함수 종속 제거)</li>
<li>3정규형: 이행적 함수 종속(A-&gt;B이고 B-&gt;C 일 때 A-&gt;C 만족) 제거</li>
<li>BCNF(보이스 코드): 결정자이면서 후보키 아닌 것 제거</li>
<li>4정규형: 다치 종속</li>
<li>5정규형: 조인 종족성 이용</li>
</ul>
<h3 id="이상anomaly">이상(Anomaly)</h3>
<ul>
<li>삽입 이상: 의도와는 상관없는 값들도 함께 삽입</li>
<li>삭제 이상: 의도와는 상관없는 값들이 삭제</li>
<li>갱신 이상: 일부 튜플의 정보만 갱신되면 정보에 모순</li>
</ul>
<h2 id="ipv6">IPv6</h2>
<p>IPv4가 가지고 있는 주소 고갈, 보안성, 이동성 지원 등의 문제점을 해결하기 위해서 개발된 128bit 주소체계를 갖는 차세대 인터넷 프로토콜</p>
<h3 id="ipv6-특징">IPv6 특징</h3>
<ul>
<li>IP 주소의 확장</li>
<li>이동성</li>
<li>인증 및 보안기능</li>
<li>개선된 QoS 지원</li>
<li>Plug&amp;Plus 지원</li>
<li>Ad-hoc 네트워크 지원</li>
<li>단순 헤더 적용</li>
<li>실시간 패킷 추적 가능</li>
</ul>
<h3 id="ipv6-헤더header-구조">IPv6 헤더(Header) 구조</h3>
<p>Version / Traffic Class / Flow Label / Payload Length / Next Header / Hop Limit / Source / Address / Destination / Address</p>
<h2 id="응용-계층7계층-프로토콜">응용 계층(7계층) 프로토콜</h2>
<h3 id="httphypertetx-transfer-protocol">HTTP(HyperTetx Transfer Protocol)</h3>
<p>: 텍스트 기반의 통신 규약</p>
<h3 id="ftptransfer-protocol">FTP(Transfer Protocol)</h3>
<p>: TCP/IP 프로토콜을 가지고 서버와 클라이언트 사이의 파일을 전송하기 위한 프로토콜</p>
<h3 id="smtpsimple-mail-transfer-protocol">SMTP(Simple Mail Transfer Protocol)</h3>
<p>: 인터넷에서 TCP 포트번호 25번을 사용하여 이메일을 보내기 위해 이용되는 프로토콜</p>
<h3 id="pop3post-office-protocol-version-3">POP3(Post Office Protocol Version 3)</h3>
<p>: 응용 계층 인터넷 프로토콜 중 하나로, 원격 서버로부터 TCP/IP 연결을 통해 이메일을 가져오는 데 사용하는 프로토콜</p>
<h3 id="imapinternet-messaging-access-protocol">IMAP(Internet Messaging Access Protocol)</h3>
<p>: 원격 서버로부터 TCP/IP 연결을 통해 이케일을 가져오는데 사용하는 프로토콜</p>
<h3 id="telnet">Telnet</h3>
<p>: 인터넷이나 로컬 영역에서 네트워크 연결에 사용되는 네트워크 프로토콜</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JS]  Function() 생성자, 화살표 함수]]></title>
            <link>https://velog.io/@essssk___/JS-Function-%EC%83%9D%EC%84%B1%EC%9E%90-%ED%99%94%EC%82%B4%ED%91%9C-%ED%95%A8%EC%88%98</link>
            <guid>https://velog.io/@essssk___/JS-Function-%EC%83%9D%EC%84%B1%EC%9E%90-%ED%99%94%EC%82%B4%ED%91%9C-%ED%95%A8%EC%88%98</guid>
            <pubDate>Thu, 01 Feb 2024 22:26:06 GMT</pubDate>
            <description><![CDATA[<p>지난주에 자바스크립트 함수에 대하여 공부했는데, 내용이 많아서 이번주에 보충공부를 했다.</p>
<h2 id="function-생성자">Function() 생성자</h2>
<p>함수는 Function() 생성자 통해서도 만들 수 있다. 변수에 생성자를 호출하여 익명함수의 형태이며 생성자 호출 시 함수 몸체를 분석(parse)하여 새로운 함수 객체를 생성한다. 
Function() 생성자가 가진 가장 큰 특징은 동적으로 자바스크립트 함수를 생성할 수 있다는 점이다. 런타임에 동적으로 함수의 내용이 생성되어야 할 때를 제외하고는 일반적으로 사용하는 방법은 아니고, 보통은 함수 선언문 또는 함수 표현식을 많이 사용한다. </p>
<pre><code>let sc = &quot;outer&quot;;
function constructFunc() {
    let sc = &quot;inner&quot;;
    return new Function(&quot;return sc&quot;);
}
constructFunc()(); // outer</code></pre><h2 id="화살표-함수">화살표 함수</h2>
<p>화살표 함수는 함수 표현식을 더 간결하게 작성할 수 있어서 가독성이 좋다. 특히 한 줄짜리 콜백 함수를 사용할 때, 화살표 함수는 코드의 길이를 꽤 많이 줄여준다.</p>
<pre><code>const normalAdd2 = function(x) {return x+2}
const arrowAdd2 = x =&gt; x+2

normalAdd2(2) // 4
arrowAdd2(2) // 4

// 매개변수가 있을 때 괄호 생략 가능
// return 생략 가능
</code></pre><p>객체의 메서드로 화살표 함수를 사용하면 메서드 내에서 일반적인 this와 달리 this를 일관되게 사용할 수 있다.</p>
<pre><code>const ThisTest = {
    name: &quot;other&quot;,
    inner: function() {
        const innerFunc = {
            name: &quot;inner&quot;,
            innerNormal: function() {console.log(&quot;inner normal:&quot;,this.name);},
            innerArrow: ()=&gt; {console.log(&quot;inner arrow:&quot;,this.name);}
        }
        return innerFunc.innerNormal(), innerFunc.innerArrow();
    },
    otherNormal: function() {console.log(&quot;other normal:&quot;,this.name)},
    //== otherNormal() {console.log(&quot;other normal:&quot;,this.name)},
    otherArrow: ()=&gt; {console.log(&quot;other arrow:&quot;,this.name);}
}

ThisTest.inner(); // inner normal: inner, inner arrow: other
ThisTest.otherNormal(); // other normal: other
ThisTest.otherArrow(); // other arrow: 
</code></pre><h2 id="함수선언문과-화살표-함수-차이점">함수선언문과 화살표 함수 차이점</h2>
<p>함수 선언문은 자신의 this를 가리키지만, 화살표 함수는 자신을 둘러싼 스코프의 this를 상속받는다.</p>
<pre><code>// 함수 선언문
function regularFunction() {
    console.log(this);
}

// 화살표 함수
const arrowFunction = () =&gt; {
    console.log(this);
}

regularFunction(); // window 객체를 가리킴
arrowFunction(); // 상위 스코프의 this를 상속받음</code></pre><p>함수 선언문에서는 arguments 객체를 사용할 수 있지만, 화살표 함수에서는 사용할 수 없다. 화살표 함수에서는 명시적으로 파라미터를 정의해야 한다.</p>
<pre><code>function regularFunction() {
    console.log(arguments);
}

const arrowFunction = () =&gt; {
    console.log(arguments); // 에러 발생: arguments는 화살표 함수 내에서 사용할 수 없음
}

regularFunction(1, 2, 3); // 출력: [1, 2, 3]
arrowFunction(1, 2, 3); // TypeError: arguments is not defined</code></pre><p>함수 선언문은 호이스팅에 의해 스크립트가 실행되기 전에 이미 생성되어 어디서든 호출이 가능하다. 화살표 함수는 런타임에 정의된다. 따라서 정의된 이후에만 호출할 수 있다.</p>
<pre><code>regularFunction(); // 정상 실행
arrowFunction(); // TypeError: arrowFunction is not a function

function regularFunction() {
    console.log(&#39;Regular function&#39;);
}

const arrowFunction = () =&gt; {
    console.log(&#39;Arrow function&#39;);
}</code></pre><p>함수 선언문으로 생성된 함수는 prototype 속성을 가지며, 이를 통해 새로운 객체의 프로토타입으로 사용할 수 있다. 화살표 함수는 prototype 속성을 가지지 않는다.</p>
<pre><code>unction regularFunction() {}
const arrowFunction = () =&gt; {}

console.log(regularFunction.prototype); // RegularFunction {}
console.log(arrowFunction.prototype); // undefined</code></pre><p>함수 선언문은 생성자로 사용할 수 있지만, 화살표 함수는 생성자로 사용이 불가능하다.</p>
<pre><code>function RegularConstructor() {}
const ArrowConstructor = () =&gt; {};

const regularInstance = new RegularConstructor(); // RegularConstructor 인스턴스 생성
const arrowInstance = new ArrowConstructor(); // TypeError: ArrowConstructor is not a constructor</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[JS] 함수 선언, 함수 표현, 객체의 메서드]]></title>
            <link>https://velog.io/@essssk___/JS-%ED%95%A8%EC%88%98%EB%A5%BC-%EC%A1%B0%EA%B8%88-%EB%8D%94-%EC%9E%90%EC%84%B8%ED%9E%88-%EC%95%8C%EC%95%84%EB%B3%B4%EC%9E%90.-1-%ED%95%A8%EC%88%98-%EC%84%A0%EC%96%B8%EC%8B%9D</link>
            <guid>https://velog.io/@essssk___/JS-%ED%95%A8%EC%88%98%EB%A5%BC-%EC%A1%B0%EA%B8%88-%EB%8D%94-%EC%9E%90%EC%84%B8%ED%9E%88-%EC%95%8C%EC%95%84%EB%B3%B4%EC%9E%90.-1-%ED%95%A8%EC%88%98-%EC%84%A0%EC%96%B8%EC%8B%9D</guid>
            <pubDate>Thu, 25 Jan 2024 14:53:11 GMT</pubDate>
            <description><![CDATA[<p>프로젝트 소스를 보다보면 함수 형태가 다양해서 차이점을 좀 더 자세히 알아보기로 했다.</p>
<h2 id="함수-꼭-써야하나">함수, 꼭 써야하나?</h2>
<p>함수를 사용하는 이유중에 하나는 재사용성이 좋기 때문이다. 같은 일을 맡아 진행하는데 여러번 코드를 적을 필요가 없어진다. 그 코드가 수정할 일이 생길 때 그 함수만 수정하면 되기 때문이다. 
<del>필자는 사실 초반에 필요성을 못느끼고 귀찮다는 이유로 코드를 복붙하는 경우가 많았는데, 시간이 얼마 지나지 않아 과거의 나를 무척이나 원망했다^^..</del></p>
<h2 id="함수선언">함수선언</h2>
<p>함수 선언, 함수 정의, 기명함수이라고도 한다.</p>
<pre><code>// 선언
function multiply(x, y) {
  return x * y;
} // No need for semicolon here</code></pre><p>multiply는 함수 이름,
(x, y)안의 x,y는 매개변수(매개변수는 함수 내의 지역변수처럼 취급된다.),
{}안에는 정의할 내용,
return은 함수가 반환하는 값을 지정한다. return값이 없으면 undefined가 리턴된다.
함수는 정의했다고 실행되지 않는다. 호출해야만 실행된다.(중요)</p>
<h3 id="매개변수">매개변수</h3>
<p>함수의 매개변수는 재할당해도 외부의 변수값에는 영향을 미치지 않지만, 객체의 속성값에는 영향을 미친다.</p>
<pre><code>function chgCover(_book) { //_book이 매개변수
  _book.cover = &quot;딸기 생크림 케이크 사진&quot;;
  _book = null;
}

const book = {
  cover: &quot;소금이 뿌려진 식빵 사진&quot;,
  contents: [&quot;식빵 굽기&quot;, &quot;케이크 만들기&quot;, &quot;쿠키 굽기&quot;],
  title: &quot;베이킹을 시작해볼까&quot;,
};

console.log(book.cover); // 소금이 뿌려진 식빵 사진

// 함수 호출
chgCover(book);
console.log(book); 
console.log(book.cover); // 딸기 생크림 케이크 사진</code></pre><p>매개변수가 배열이라면, 배열의 각 index의 값을 바꾸는 것도 가능하다.</p>
<pre><code>const arr = [1,2,3,4,5];
function chgArr(_arr) {
    _arr[0] = 10; 
}
chgArr(arr);
console.log(arr); // [10, 2, 3, 4, 5]
</code></pre><p>만약 함수의 매개변수가 정의된 것보다 적게 들어간다면, 나머지의 매개변수는 undefined 형태다.</p>
<ul>
<li>arguments 객체 활용
: 함수 내부에서 arguments 객체를 활용할 수 있다. 배열처럼 length를 확인할 수 있고, arguments[0]처럼 직접적으로 매개변수에 접근할 수도 있다.</li>
</ul>
<h3 id="호이스팅">호이스팅</h3>
<pre><code>console.log(sum(5,5)); // 10

function sum(x,y) {
    return x+y;
}</code></pre><p>함수가 콘솔을 찍기전에 선언이 되어있어도 에러가 발생하지 않는다. 
JavaScript 인터프리터가 전체 함수 선언을 현재 스코프의 최상단으로 끌어올리기 때문(호이스팅)이다. (변수에 담는 함수 선언식은 호이스팅되지 않는다.)</p>
<h2 id="함수-표현">함수 표현</h2>
<p>함수표현식은 익명함수라고도 하는데, 함수가 이름을 가질 필요는 없음을 의미한다. 변수에 함수를 할당하는 방식이다.</p>
<h3 id="함수-표현식-왜-쓰는걸까">함수 표현식, 왜 쓰는걸까?</h3>
<p>함수표현식은 보통 새로 다른 함수의 일부로 이용될 때 유리하다. 다른 함수에 대한 할당이나 호출 시 보통 사용한다. 보통 한번만 호출되는 함수에 특히 적합하다. </p>
<h3 id="변수에-할당되기-전까지는-못쓴다">변수에 할당되기 전까지는 못쓴다.</h3>
<p>따라서 표현식을 사용하려면 변수가 먼저 선언된 후에 사용해야한다.</p>
<pre><code>// 함수표현식
const sum1 = function (x, y) {
  return x + y;
};
// 함수표현식에 함수 이름을 부여할 수도 있다.
const sum2 = function fnSum(x, y) {
  return x + y;
};</code></pre><p>표현식에 경우 고유한 이름을 가져도, 호출 시 변수명으로 호출해야 한다.
함수표현식에 고유명은 함수 내부에서만 참조 가능하다. (재귀호출)</p>
<h2 id="객체의-메서드">객체의 메서드</h2>
<pre><code>const calc = {
  sum(a, b) {
      this.s_result = a+b;
  },
  minus: function(a, b) {
      this.m_result = a-b;
  }
};</code></pre><p>메서드는 객체의 속성으로 저장된 함수이며, 객체이기 때문에 this를 통해 calc자체를 참조할 수 있다.</p>
<pre><code>// 접근 방식 1. .활용
calc.sum(1,2);

// 접근 방식 2. [] 활용
calc[&quot;sum&quot;](1,2);</code></pre><h3 id="함수안에-함수중첩함수">함수안에 함수(중첩함수)</h3>
<p>함수는 사실 객체다.</p>
<pre><code>function outer() {
    const outerScope = &quot;밖&quot;;
    inner();
    function inner() {
        const innerScope = &quot;안&quot;;
        console.log(&quot;in&quot;, outerScope);
        console.log(&quot;in&quot;, innerScope);
    }
    console.log(&quot;in&quot;, innerScope);
}</code></pre><p>자바스크립트의 함수는 중첩이 가능하다. 
여기서 inner함수는 outer함수의 변수에 접근이 가능한데, outer함수가 inner함수의 변수에 접근은 불가능하다.</p>
<h3 id="클로저">클로저</h3>
<p>함수 객체와 함수의 변수가 해석되는 유효범위를 클로저라고 한다. 
함수는 호출시점에서의 변수 유효범위가 아닌, 함수가 정의된 시점의 변수 유효범위를 사용한다.</p>
<pre><code>function outer() {
    let scope = &quot;local&quot;;
    function inner() {
        return scope;
    }
    return inner;
}
outer()(); // &quot;local&quot;</code></pre><p>아래의 경우에는 호출 때마다 리턴 값이 다르다. 전역변수 대신 많이 사용하는 방법이다.</p>
<pre><code>let call = function() {
    let now = &quot;a&quot;;
    return function() {
        now = now == &quot;a&quot; ? &quot;b&quot; : &quot;a&quot;; 
        return now;
    }
}();

console.log(call()); // b
console.log(call()); // a</code></pre><h2 id="정리하며">정리하며</h2>
<p>나는 함수를 알고 있다고 생각했는데, 내가 안다고 말하는 것은 결코 아는 것이 아니었음을, 표면에 지나지 않음을 많이 느낀다.
시작은 분명 그랬으나, 찾아보면 찾아볼수록 함수 자체는 어마어마한 양을 담고 있구나를 많이 느꼈다.
다음에 작업할 때는 무조건 기명함수를 사용할게 아니라, 일회성에 의한 부분은 익명함수를 활용해보도록 해야겠다. 
기존에 전역변수를 활용한 방법만 이용했는데, 클로저 특성을 활용한 기능구현을다좀 더 구체적으로 알아봐도 좋을 것 같다.
본래는 생성자함수와 화살표함수 관련해서도 같이 기록하려고 했으나, 클로저를 이해하는데 있어 많은 어려움을 겪었다....<del>지금도 완벽하게 이해한게 맞나..?싶기도 하다.</del>그래서 생성자함수와 화살표함수는 (다음기회에) 포스팅 해야겠다. </p>
<h2 id="참고자료">참고자료</h2>
<p>자바스크립트 완벽가이드(저자: 데이비드 플래너건)
<a href="https://poiemaweb.com/js-closure">https://poiemaweb.com/js-closure</a>
<a href="https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Functions">https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Functions</a>
<a href="https://likedev.tistory.com/entry/javascript-%EC%9D%B5%EB%AA%85%ED%95%A8%EC%88%98">https://likedev.tistory.com/entry/javascript-%EC%9D%B5%EB%AA%85%ED%95%A8%EC%88%98</a>
<a href="https://dev-note-97.tistory.com/273">https://dev-note-97.tistory.com/273</a>
<a href="https://hhyemi.github.io/2021/06/09/arrow.html">https://hhyemi.github.io/2021/06/09/arrow.html</a>
<a href="https://chaeyoung2.tistory.com/76#google_vignette">https://chaeyoung2.tistory.com/76#google_vignette</a>
<a href="https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Function">https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Function</a>
<a href="https://developer.mozilla.org/ko/docs/Web/JavaScript/Guide/Functions#function_hoisting">https://developer.mozilla.org/ko/docs/Web/JavaScript/Guide/Functions#function_hoisting</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Gradle & Maven 알기]]></title>
            <link>https://velog.io/@essssk___/Gradle-Maven-%EC%95%8C%EA%B8%B0</link>
            <guid>https://velog.io/@essssk___/Gradle-Maven-%EC%95%8C%EA%B8%B0</guid>
            <pubDate>Thu, 11 Jan 2024 12:22:34 GMT</pubDate>
            <description><![CDATA[<p>스프링 부트를 처음 시작하게 되면 <a href="https://start.spring.io/">https://start.spring.io/</a> 사이트를 들어가서 프로젝트를 생성하게 된다. 나같은 초보는 시작부터 물음표가 생기는데 
<img src="https://velog.velcdn.com/images/essssk___/post/e0d367a3-2bcc-4e4e-a92a-f6d468bc6046/image.png" alt=""></p>
<p>예전에 입문 강의를 보면서 저 사이트를 통해 gradle project를 만들어보긴 했었다. 어치피 회사에서 주로 사용하는게 maven project라 잊고 지냈는데 이번에 사용해보게 되었으니 <del>(더 늦기 전에 간단하게라도)</del> 정리하는 시간을 갖기로 했다.</p>
<p>기존에 알고있던 maven과 gradle 차이는 설정파일 형태가 다르다는 점이다.
maven은 pom.xml을 활용해서 의존성 관리를 하고, gradle은 build.gradle을 사용한다. maven이 먼저고 gradle이 나중에 나온 것으로 알고 있다.</p>
<h3 id="maven">Maven</h3>
<p>Maven은 Apache Software Foundation에서 개발한 자바 프로젝트의 빌드, 의존성 관리 등을 자동화하기 위한 도구이다. 기존에는 Ant를 주로 사용했는데, Maven과 동일하게 xml 기반의 설정파일을 사용하지만, 프로젝트가 복잡해질 경우 빌드 과정을 이해하기 어려운 점 등의 단점을 가지고 있었다.</p>
<p>Maven은 프로젝트의 라이프사이클을 정의하고 이를 실행하는 방식이다. 플러그인 기반의 아키텍처로, 미리 정의된 플러그인을 사용할 수 있고 사용자 정의 플러그인을 작성하여 빌드 과정 확장도 가능하다.</p>
<h4 id="pomproject-object-model">POM(Project Object Model)</h4>
<p>pom.xml은 프로젝트의 구조와 빌드 설정을 정의하는 파일이다.
프로젝트의 정보(프로젝트 이름, 라이센스 등)와 빌드 설정(소스, 리소스, 플러그인 등 빌드와 관련된 설정), 빌드 환경 등의 정보를 담고 있다.</p>
<h4 id="maven-라이프사이클">Maven 라이프사이클</h4>
<p>Maven은 미리 정의된 라이프사이클을 가지고 있다.</p>
<ul>
<li>clean: 프로젝트를 초기 상태로 되돌리기 위한 단계, 이전 빌드에서 생성된 파일들을 제거</li>
<li>build: 소스 코드 컴파일, 테스트, 패키징 및 배포에 필요한 작업을 수행</li>
<li>site: 문서 관련 작업(프로젝트 문서를 생성하고 웹 사이트를 생성) ...</li>
</ul>
<p>이 외에도 더 많은 종류의 라이프 사이클이 존재한다. 각각 라이프사이클마다 순서를 갖는 단계(Phase), 단계별 실행되는 플러그인 골(Goal)이 지정되어 있다.</p>
<h4 id="프로젝트-구조">프로젝트 구조</h4>
<ul>
<li>소스 코드: src/main/java</li>
<li>테스트 코드: src/test/java</li>
<li>리소스 파일: src/main/resources, src/test/resources</li>
</ul>
<p>Maven이 제공하는 표준 구조로, 표준 구조를 따르지 않으면 기능이 제대로 동작하지 않을 수 있다. (강제성을 띈다.)</p>
<h3 id="gradle">Gradle</h3>
<p>이전 세대 빌드 도구(ant, maven 등)의 단점을 보완하고 장점을 취합하여 만든 오픈소스 빌드 도구로, Groovy 또는 Kotlin 기반의 DSL(Domain Specific Language)을 사용한다.
Gradle도 maven처럼 라이프사이클을 가지고 있다. 
프로젝트 구조는 Maven과 유사하지만, 자유롭게 변경이 가능하다.
DSL(Domain Specific Language)을 사용하여 빌드 스크립트를 작성한다.
Java뿐만 아니라 C/C++, Python 등을 지원한다.
멀티 프로젝트를 위해 설계된 빌드 관리 도구.</p>
<h4 id="gradle의-라이프사이클">Gradle의 라이프사이클</h4>
<ul>
<li>Initialization: Gradle이 빌드를 초기화하고 프로젝트 설정을 읽음</li>
<li>Configuration: 프로젝트와 모든 하위 프로젝트의 설정이 구성, 의존성 해결 및 빌드 스크립트 실행</li>
<li>Execution: 빌드 스크립트에서 정의한 작업들이 실행(compileJava, assemble, 커스텀된 작업)</li>
<li>Finalization: 빌드 완료, 결과물 정리</li>
</ul>
<p>Gradle은 Maven의 플러그인 컨셉과는 다르게 태스크(task)중심으로 구성되어있고, 사용자는 태스크를 조합하여 원하는 빌드흐름을 만들 수 있다. </p>
<h3 id="결론-이래서-gradle">결론: 이래서 Gradle</h3>
<p>Gradle은 DSL을 이용해서  XML 기반의 Maven POM 파일보다 훨씬 가독성이 뛰어나고 간결해서 작성이 유리하다. 특히 빌드 속도가 Maven에 비해 최대 100배 빠르다. 캐시를 사용하기 때문에 테스트를 반복할수록 더 빨라진다.
직접 설치를 하지 않아도 gradle wrapper를 이용하여 사용할 수도 있고, 설정 주입 방식으로 재사용에도 유리하다. </p>
<p>회사에서 주로 사용하는 프로젝트가 maven이라 그나마 눈에 익숙하긴 했는데, 이번에 좀 더 깊이있게 공부하게 된 것 같다. 왜 사람들이 다들 gradle 사용하는지 이번 기회에 많이 공부하게 됬다. 처음 gradle을 사용하면서 pom.xml보다가 build.gradle보면 확실히 좀 더 눈에 더 잘 들어오는 것 같다.    </p>
<h3 id="참고링크">참고링크</h3>
<p><a href="https://hyojun123.github.io/2019/04/18/gradleAndMaven/">https://hyojun123.github.io/2019/04/18/gradleAndMaven/</a>
<a href="https://velog.io/@leesomyoung/Maven%EA%B3%BC-Gradle%EC%9D%98-%EC%B0%A8%EC%9D%B4-%EB%B0%8F-%EB%B9%84%EA%B5%90">https://velog.io/@leesomyoung/Maven%EA%B3%BC-Gradle%EC%9D%98-%EC%B0%A8%EC%9D%B4-%EB%B0%8F-%EB%B9%84%EA%B5%90</a>
<a href="https://gradle.org/gradle-vs-maven-performance/">https://gradle.org/gradle-vs-maven-performance/</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Spring과 Spring Boot 차이]]></title>
            <link>https://velog.io/@essssk___/Spring%EA%B3%BC-Spring-Boot-%EC%B0%A8%EC%9D%B4</link>
            <guid>https://velog.io/@essssk___/Spring%EA%B3%BC-Spring-Boot-%EC%B0%A8%EC%9D%B4</guid>
            <pubDate>Thu, 04 Jan 2024 22:49:15 GMT</pubDate>
            <description><![CDATA[<p>2023년 5월, 유지보수가 아닌 처음으로 직접 개발에 참여하게 되었다.
회사에서 개발한 프로그램의 기본 환경은 Spring인데, 5월에 참여했던 프로젝트에서는 Spring boot를 활용했다.</p>
<h2 id="왜-spring-boot를-사용했는가">왜 Spring Boot를 사용했는가?</h2>
<p>우리회사에서는 웹프로젝트를 스프링으로 사용하지만, 타 회사나 프로젝트 등에서는 스프링 부트를 많이 활용한다고 들었다.<del>(그렇다고 우리회사에서 스프링부트를 전혀 사용하지 않는 것은 아니다...)</del> 스프링부트가 주는 장점이 있다고 생각했기 때문에 이번 프로젝트를 기회로 발판삼아 활용해보기로 했다.</p>
<p>스프링에 대한 개념은 김영한 님의 강의를 참고하여 정리했다.
<del>(언제나 좋은 강의 감사합니다..❤️)</del></p>
<h2 id="spring">Spring?</h2>
<blockquote>
</blockquote>
<p>객체 지향언어인 자바의 특징을 잘 살려낸 프레임워크
좋은 객체 지향 애플리케이션을 개발할 수 있게 도와주는 프레임워크</p>
<blockquote>
<p>스프링이라는 단어는 문맥에 따라 다르게 사용한다. </p>
</blockquote>
<ul>
<li>스프링 DI 컨테이너 기술</li>
<li>스프링 프레임 워크</li>
<li>스프링 부트, 스프링 프레임워크 등을 모두 포함한 스프링 생태계</li>
</ul>
<blockquote>
</blockquote>
<p>핵심 기술: 스프링 DI컨테이너, AOP, 이벤트, 기타
웹 기술: 스프링 MVC, 스프링 WebFlux</p>
<p>스프링 프레임워크를 사용하면 자바 기반의 어플리케이션 제작, 개발자들은 비즈니스 로직에 집중할 수 있다.</p>
<p>이후 스프링 프레임워크의 다양한 기능들, 다양한 오픈 소스 등 외부 라이브러리를 함께 사용할 일이 많아졌다. 결국 스프링으로 개발을 시작할 때 직접 해야하는 설정이 너무 많아지고 복잡해져 진입장벽이 높다.</p>
<h2 id="spring-boot-등장">Spring boot 등장</h2>
<p>스프링 부트를 사용하면 스프링 기반의 어플리케이션을 쉽게 만들 수 있다.</p>
<h3 id="spring-spring-boot-차이">Spring, Spring boot 차이</h3>
<ul>
<li>내장서버</li>
<li>편리한 의존성 &amp; 권장 버전 관리</li>
<li>자동 설정</li>
</ul>
<h3 id="어떻게-편리한걸까">어떻게 편리한걸까?</h3>
<p>스프링으로 만든 웹 애플리케이션을 배포하기위해서는 
**</p>
<ol>
<li>WAS 설치</li>
<li>코드를 War로 빌드</li>
<li>빌드한 War파일을 WAS 하위 폴더로 이동</li>
<li>WAS 실행</li>
</ol>
<p>**
하는 과정을 거쳐야 한다.</p>
<h4 id="1-was설치">1. WAS설치</h4>
<p>스프링 부트는 서버가 내장되어있기 때문에 따로 Tomcat을 설치하거나 매번 버전을 관리해 주어야 하는 수고로움을 덜어준다.(Embed Tomcat)</p>
<h4 id="2-편리한-의존성">2. 편리한 의존성</h4>
<p>기존에 스프링은 전체적으로 의존성 관리에 어려움이 있었다. 
라이브러리들이 서로 영향을 미치기 때문에 호환하는 버전을 하나하나 맞춰야했기 때문이다. 혹여나 버전을 올려야 한다면 개발이 아닌 세팅에도 시간을 많이 써야한다.
하지만 스프링부트는 starter라는 기본 라이브러리 묶음을 제공한다. 호환 버전을 일일히 맞추지 않아도 호환되는 라이브러리 묶음을 의존하면 되는 것이다.</p>
<blockquote>
</blockquote>
<p>핵심 기술: 스프링 DI컨테이너, AOP, 이벤트, 기타
웹 기술: 스프링 MVC, 스프링 WebFlux
데이터 접근 기술: 트랜잭션, JDBC, ORM 지원, XML 지원
기술 통합: 캐시, 이메일, 원격접근, 스케줄링
테스트: 스프링 기반 테스트 지원
언어: 코틀린, 그루비
-&gt; 최근에는 스프링 부트를 통해 스프링 프레임워크의 기술들을 편리하게 사용</p>
<p>기술적 부분은 추후에 하나씩 정리해나갈 예정.</p>
<h3 id="스프링-부트의-장점">스프링 부트의 장점</h3>
<ol>
<li>단독으로 실행 가능한 스프링 애플리케이션을 쉽게 만들 수 있기 때문에 최근에는 기본으로 사용하는 경우가 많다.</li>
<li>손쉬운 빌드 구성을 위한 starter 종속성을 제공한다.</li>
<li>별도의 웹서버를 설치하지 않아도 된다.(내장 웹 서버를 지원한다.)</li>
</ol>
<h3 id="설정파일을-직접-확인해보면">설정파일을 직접 확인해보면?</h3>
<p>프로젝트에는 spring boot 2.7.11(maven) 버전을 사용했다.
pom.xml에 <dependencies>를 살펴보면 스타터 의존성을 확인할 수 있다.</p>
<pre><code>&lt;dependency&gt;
    &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
    &lt;artifactId&gt;spring-boot-starter&lt;/artifactId&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
    &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
    &lt;artifactId&gt;spring-boot-starter-test&lt;/artifactId&gt;
    &lt;scope&gt;test&lt;/scope&gt;
&lt;/dependency&gt;</code></pre><p>위는 <a href="https://start.spring.io/%EC%97%90%EC%84%9C">https://start.spring.io/에서</a> 기본으로 설정되는 
의존성이다.</p>
<pre><code>&lt;dependency&gt;
    &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
    &lt;artifactId&gt;spring-boot-starter-web&lt;/artifactId&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
    &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
    &lt;artifactId&gt;spring-boot-starter-tomcat&lt;/artifactId&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
    &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
    &lt;artifactId&gt;spring-boot-starter&lt;/artifactId&gt;
    &lt;exclusions&gt;
        &lt;exclusion&gt;
            &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
            &lt;artifactId&gt;spring-boot-starter-logging&lt;/artifactId&gt;
        &lt;/exclusion&gt;
        &lt;exclusion&gt;
            &lt;groupId&gt;ch.qos.logback&lt;/groupId&gt;
            &lt;artifactId&gt;logback-classic&lt;/artifactId&gt;
        &lt;/exclusion&gt;
    &lt;/exclusions&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
    &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
    &lt;artifactId&gt;spring-boot-starter-data-jpa&lt;/artifactId&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
    &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
    &lt;artifactId&gt;spring-boot-starter-jdbc&lt;/artifactId&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
    &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
    &lt;artifactId&gt;spring-boot-starter-websocket&lt;/artifactId&gt;
    &lt;version&gt;3.1.1&lt;/version&gt;
&lt;/dependency&gt;</code></pre><p>... 이하 생략.
그리고 기본적인 스타터 외에 필요한 의존성을 추가했다.
(web, log, jpa, websorket ... 등등)</p>
<h3 id="마무리하며">마무리하며</h3>
<p>스프링 부트는 스프링 프레임워크와 별도로 사용하는 것이 아니며, 부트가 스프링프레임워크를 기본적으로 당겨오고 그 외에 필요한 기능들을 편리하게 사용할 수 있도록 중간역할을 한다고 한다.</p>
<p>해당 프로젝트의 세팅은 직접 진행한게 아니기때문에 따로 직접 환경세팅을 해서 적용하는 시간을 가져봐야한다.</p>
<p>스프링프레임워크와 스프링 부트와의 차이점 기준으로 간략하게 특징위주로 정리했는데, 스프링만 하더라도 알아야할 내용들이 어마어마하게 많다. 세부적인 내용들도 추후에 차근차근 알아봐야겠다.  </p>
]]></description>
        </item>
    </channel>
</rss>