<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>_0.307.log</title>
        <link>https://velog.io/</link>
        <description></description>
        <lastBuildDate>Wed, 14 Aug 2024 01:47:26 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>_0.307.log</title>
            <url>https://velog.velcdn.com/images/cojeong_37/profile/a566522d-27b3-4968-9bf0-3fbb26b66abc/image.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. _0.307.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/cojeong_37" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[스프링 부트 - Annotation]]></title>
            <link>https://velog.io/@cojeong_37/%EC%8A%A4%ED%94%84%EB%A7%81-%EB%B6%80%ED%8A%B8-Annotation</link>
            <guid>https://velog.io/@cojeong_37/%EC%8A%A4%ED%94%84%EB%A7%81-%EB%B6%80%ED%8A%B8-Annotation</guid>
            <pubDate>Wed, 14 Aug 2024 01:47:26 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/cojeong_37/post/1850ae80-8454-402e-8da4-eefc3dfb643b/image.png" alt=""></p>
<p>메인 클래스에 붙어있는 @SpringBootApplication은 @EnableAutoConfiguration, @ComponentScan, @SpringBootCoinfiguration 어노테이션을 포함한다.</p>
<p>@EnableAutoConfiguration </p>
<ul>
<li>애플리케이션 클래스패스에 있는 JAR 파일을 바탕으로 애플리케이션을 자동으로 구성해주는 스프링 부트 자동 구성 기능을 활성화한다.</li>
</ul>
<p>@ComponentScan </p>
<ul>
<li>애플리케이션에 있는 스프링 컴포넌트를 탐색해서 찾아낸다
스프링 컴포넌트는 @Component, @Bean 등이 붙어 있는 자바 빈으로서 스프링으로 관리한다. 
Annotation 에서 지정한 디렉토리와 그 하위 디렉터리를 모두 탐색해서 스프링 컴포넌트를 찾아내고, 라이프사이클을 관리한다.<strong>@ComponentScan 은 루트 패키지에서 시작해서 모든 하위 패키지까지 탐색한다는 것!</strong></li>
</ul>
<p>@SpringBootConfiguration </p>
<ul>
<li>스프링 부트 애플리케이션 설정을 담당하는 클래스에 이 어노테이션을 붙인다. 
내부적으로 @Configuration을 포함하고 있기 때문에 이 설정 클래스는 스프링 부트 컴포넌트 탐색으로 발견되며, 
이 클래스 안에서 정의된 빈도 스프링으로 발견해 로딩된다. 
결과적으로 이러한 빈을 통해 애플리케이션 설정 과정에 참여한다. </li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[스프링 부트 - 컴포넌트 ]]></title>
            <link>https://velog.io/@cojeong_37/%EC%8A%A4%ED%94%84%EB%A7%81-%EB%B6%80%ED%8A%B8-%EC%BB%B4%ED%8F%AC%EB%84%8C%ED%8A%B8</link>
            <guid>https://velog.io/@cojeong_37/%EC%8A%A4%ED%94%84%EB%A7%81-%EB%B6%80%ED%8A%B8-%EC%BB%B4%ED%8F%AC%EB%84%8C%ED%8A%B8</guid>
            <pubDate>Wed, 14 Aug 2024 01:16:32 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/cojeong_37/post/11c2dc87-d725-44e2-9c92-ff1407e32dcc/image.png" alt=""></p>
<ol>
<li>spring-boot</li>
</ol>
<ul>
<li>스프링 부트의 기본 컴포넌트로서 다른 컴포넌트를 사용할 수 있도록 지원하는 컴포넌트</li>
</ul>
<ol start="2">
<li>spring-boot-autoconfigure </li>
</ol>
<ul>
<li>스프링 부트 애플리케이션 자동 구성 기능을 담당하는 컴포넌트로, 클래스 패스와 설정 파일의 프로퍼티에 지정된 의존 관계를 바탕으로 스프링 빈을 추론해서 알맞은 빈을 생성한다. </li>
</ul>
<ol start="3">
<li>spring-boot-starters</li>
</ol>
<ul>
<li>미리 패키징된 의존관계 기술서 모음. </li>
</ul>
<ol start="4">
<li>spring-boot-CLI </li>
</ol>
<ul>
<li>Groovy 코드를 컴파일하고 실행할 수 있는 개발자 친화적 명령행 도구. 파일 내용 변경을 감지하는 기능이 있어, 애플리케이션에 수정 사항이 발생할 때마다 직접 재부팅을 할 필요가 없다. </li>
</ul>
<ol start="5">
<li>spring-boot-actuator </li>
</ol>
<ul>
<li>스프링 부트 애플리케이션을 모니터링하고 감지할 수 있는 actuator endpoint 를 제공. 
원하는 기능이 미리 정의된 actuator endpoint 에 포함되어 있지 않을경우, 직접 커스텀 actuator endpoint 를 만들어서 추가할 수도 있으며, 인가되지 않은 접근으로부터 endpoint 를 보호할 수도 있다. </li>
</ul>
<ol start="6">
<li>spring-boot-test </li>
</ol>
<ul>
<li>스프링 부트 애플리케이션 테스트 케이스 작성에 필요한 Annotation 과 메서드가 포함되어 있다.</li>
</ul>
<ol start="7">
<li>spring-boot-test-autoconfigure </li>
</ol>
<ul>
<li>애플리케이션 테스트 케이스에 필요한 의존 관계를 자동으로 구성해준다.</li>
</ul>
<ol start="8">
<li>spring-boot-loader </li>
</ol>
<ul>
<li>스프링 부트 애플리케이션을 실행 가능한 하나의 JAR 파일로 패키징 하는 데 필요한 모든 의존 관계와 독립 실행형으로 실행할 수 있는 내장 웹 서버를 포함하고 있다. 이 컴포넌트는 독립적으로 사용하지 않고 메이븐이나 그레이들 플러그인과 함께 사용한다.</li>
</ul>
<ol start="9">
<li>spring-boot-devtools </li>
</ol>
<ul>
<li>스프링 부트 애플리케이션 개발을 도와주는 여러 가지 개발자 도구가 들어있다. 애플리케이션 코드 변경 자동 감지 기능, HTML 변경 사항이 있을 때 자동으로 브라우저 새로 고침을 실행해주는 LiveReload 서버 기능등이 포함되어 있다. </li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[SpringBoot - 핵심 기능]]></title>
            <link>https://velog.io/@cojeong_37/SpringBoot-%ED%95%B5%EC%8B%AC-%EA%B8%B0%EB%8A%A5</link>
            <guid>https://velog.io/@cojeong_37/SpringBoot-%ED%95%B5%EC%8B%AC-%EA%B8%B0%EB%8A%A5</guid>
            <pubDate>Wed, 14 Aug 2024 01:05:54 GMT</pubDate>
            <description><![CDATA[<h3 id="a-스프링부트">A. 스프링부트</h3>
<ul>
<li>스프링 프레임워크와 개발자 사이에 존재하는 계층으로서 설정을 단순화해주는 역할. </li>
</ul>
<h3 id="b-스프링-부트-핵심-기능">B. 스프링 부트 핵심 기능</h3>
<blockquote>
<p><strong>1. 빠른 시동</strong> </p>
</blockquote>
<ul>
<li>스프링 부트의 주요 목표 중 하나는 스프링 애플리케이션 개발을 빨리 시작할 수 있게 만드는 것.
전통적인 스프링만으로 웹 애플리케이션을 개발한다면 아래와 같은 과정을 먼저 수행해야 함.
a. 스프링 MVC 의존 관계를 추가하고 메이븐이나 그레이들 프로젝트를 설정
b. 스프링 MVC DispatcherServlet 설정
c. 애플리케이션 컴포넌트를 WAR 파일로 패키징
d. WAR 파일을 Apache Tomcat 같은 서블릿 컨테이너에 배포</li>
<li>스프링 부트를 사용하면 개발자는 애플리케이션에 필요한 의존 관계를 명시하기만 하면 되고, 나머지는 스프링 부트가 알아서 해준다</li>
</ul>
<blockquote>
<p><strong>2. 자동 구성</strong></p>
</blockquote>
<ul>
<li>스프링 부트는 클래스패스에 있는 JAR 파일이나 여러 가지 설정 파일에 지정된 프로퍼티 정보를 바탕으로 스프링 애플리케이션에 필요한 최소한의 컴포넌트를 알아서 자동으로 구성해준다. 
예를 들어 클래스패스에 H2 인메모리 데이터베이스 드라이버 JAR 파일이 있으면 스프링 부트는 H2 데이터베이스 연결에 필요한 데이터 소스를 자동으로 구성해준다.</li>
</ul>
<blockquote>
<p>*<em>3. 미리 정의된 방식 *</em></p>
</blockquote>
<ul>
<li>스프링 부트는 미리 정의된 방식을 따른다. 그래서 스프링 애플리케이션을 실행할 때 필요한 몇 가지 컴포넌트를 스타터 의존 관계를 기준으로 자동으로 구성한다.
스타터 의존 관계는 애플리케이션 개발의 특정 영역을 대상으로 관련된 의존 관계를 포함하고 있다.</li>
</ul>
<blockquote>
<p>*<em>4. 독립 실행형 *</em></p>
</blockquote>
<ul>
<li>스프링 부트 애플리케이션은 웹 서버를 내장하고 있어서 외부 웹 서버나 애플리케이션 서버 없이도 독립적으로 설치되어 실행할 수 있다.
스프링 부트 애플리케이션은 실행 가능한 JAR 파일로 패키징 되어 java -jar 명령으로 간단하게 실행할 수 있다. 
덕분에 스프링 부트 애플리케이션은 쉽게 컨테이너화 될 수 있고 클라우드 네이티브 애플리케이션 개발에도 적합하다.</li>
</ul>
<blockquote>
<p><strong>5. 실제 서비스 환경에 사용 가능</strong></p>
</blockquote>
<ul>
<li>스프링 부트에는 헬스체크, 스레드 덤프를 수행하고 기타 유용한 측정지표를 보여주는 기능이 포함돼 있어서, 실제 서비스 환경에 배포된 애플리케이션 모니터링이나 유지 관리를 손쉽게 수행할 수 있다. </li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Java Script]]></title>
            <link>https://velog.io/@cojeong_37/Java-Script-c8jm36fr</link>
            <guid>https://velog.io/@cojeong_37/Java-Script-c8jm36fr</guid>
            <pubDate>Mon, 12 Aug 2024 22:50:40 GMT</pubDate>
            <description><![CDATA[<p>20240703 WED, 비동기 처리 - async-await 통신방식</p>
<ol start="3">
<li>promise 방식을 해결한 비동기 처리 방식 -&gt; async - await 방식<pre><code class="language-java">async function whatsYourFavorite() {
let fav = &quot;JavaScript&quot;;
return new Promise((resolve, reject) =&gt; resolve(fav));
}
</code></pre>
</li>
</ol>
<p>async function displaySubject(subject) {
  return new Promise((resolve, reject) =&gt; resolve(<code>hello ${subject}</code>));
}</p>
<p>whatsYourFavorite().then(displaySubject).then(console.log);</p>
<p>// async function 은 Promise 객체를 반환한다는 것을 알 수 있다
// 따라서 async 와 함께 await 를 사용할 수 있음을 생각할 수 있다. </p>
<p>async function whatsYourFavorite_async() {
  let fav = &quot;JavaScript&quot;;
  return fav;
}</p>
<p>async function displaySubject_async(subject) {
  return <code>Hello, ${subject}</code>;
}</p>
<p>// Promise 메소드 체이닝의 단점을 보완.
async function init() {
  /*  await 
    -  whatsYourFavorite_async() 함수의 실행이 끝날 때 까지 
    기다린 후 결과값을 response 에 저장한다.  */
  const response = await whatsYourFavorite_async();</p>
<p>  /* displaySubject_async() 함수의 실행이 끝날 때 까지 
     기다린 후 결과값을 result 에 저장한다.
     단, response 결과를 받을 때 까지 처리하지 말고 기다려야 한다. */
  const result = await displaySubject_async(response);</p>
<p>  console.log(result);
}
init();
```</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[React - (Custom) Hook]]></title>
            <link>https://velog.io/@cojeong_37/React-Custom-Hook</link>
            <guid>https://velog.io/@cojeong_37/React-Custom-Hook</guid>
            <pubDate>Mon, 12 Aug 2024 22:50:24 GMT</pubDate>
            <description><![CDATA[<h2 id="react-hooks">React Hooks</h2>
<h3 id="--함수-컴포넌트에서도-클래스처럼-컴포넌트의-기능을-낚아-채듯이-가져와서-사용할-수-있게-해주는-기능">- 함수 컴포넌트에서도 클래스처럼 컴포넌트의 기능을 낚아 채듯이 가져와서 사용할 수 있게 해주는 기능.</h3>
<h4 id="usestate-useref-와-같은-리액트의-내장함수는-모두-react-hooks">useState, useRef 와 같은 리액트의 내장함수는 모두 React Hooks.</h4>
<h3 id="react-hooks-특징">React Hooks 특징.</h3>
<h4 id="a-조건문-반복문-내부에서는-호출-불가능">a. 조건문, 반복문 내부에서는 호출 불가능.</h4>
<h4 id="b-custom-hook-을-직접-만들어서-사용-가능">b. custom hook 을 직접 만들어서 사용 가능.</h4>
<h3 id="hook-과-관련된-3가지-사항">Hook 과 관련된 3가지 사항</h3>
<blockquote>
<ol>
<li>hook 은 반드시 함수 컴포넌트이거나 custom hook 내부에서만 호출 가능하다.</li>
<li>조건부에서는 사용될 수 없다.</li>
<li>custom book 을 직접 만들어서 사용 가능하다</li>
</ol>
<p>*<em>-&gt; 작성 방법) 함수 작성 시 반드시 함수명 앞에 접두어 use 를 붙여야 한다. *</em></p>
</blockquote>
<h3 id="hook-활용법">Hook 활용법</h3>
<blockquote>
<ul>
<li>custom hook 을 통해 컴포넌트 내부에서 반복되는 부분을 hook 을 통해 사용될 수 있도록 분리하기.</li>
</ul>
</blockquote>
<ul>
<li>custom hook 은 별도의 Directory 에 hooks 이름의 폴더를 만들어서 관리하는 것이 일반적이다.  </li>
</ul>
<h2 id="custom-hook">Custom Hook</h2>
<p>A. 컴포넌트간 로직 공유하기 </p>
<pre><code>ex) 네트워크에 크게 의존하는 앱을 개발중, 만약 유저가 앱을 사용하는 동안 네트워크가 갑자기 사라지게 된다면
유저에게 보낼 경고를 만들어야 하는 상황</code></pre><p>필요한 요소. (아래 두가지의 요소는 컴포넌트가 네트워크 상태와 동기화 되도록 해야 한다.)</p>
<ol>
<li>네트워크가 온라인 상태인지 아닌지 추적하는 하나의 <em><strong>state</strong></em></li>
<li>전역 online, offline 이벤트를 구독하고, 이에 맞춰 state 를 업데이트 하는 Effect</li>
</ol>
<p>Q! 렌더링 중에 호출되는 모든 함수는 항상 use 접두사로 시작해야 되는가 ?
A. Nope. Hook 을 호출하지 않는 함수는 Hook 일 필요가 없다.
   함수가 어떤 Hook도 호출하지 않는다면, use를 이름앞에 적는 행위는 피해야한다.</p>
<blockquote>
<p>   Hook 을 사용하지 않는 Hook, 또는 일반함수는 use 대신 get 을 사용하는 것이 바람직 </p>
</blockquote>
<pre><code class="language-java">// 1. 안좋은 예시 : Hook 을 사용하고 있지 않은 Hook
function useSorted(items) {
    return items.slice().sort();
}

// 2. 좋은 예시 : Hook 을 사용하지 않는 일반 함수 
function getSorted(items) {
    return items.slice().sort();
}</code></pre>
<p><strong>Custom Hook 장점</strong></p>
<blockquote>
<p>custom hook 을 추출한다는 것은 데이터의 흐름을 명확하게 해준다. </p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[React - Life Cycle & useEffect ]]></title>
            <link>https://velog.io/@cojeong_37/React-Life-Cycle-useEffect</link>
            <guid>https://velog.io/@cojeong_37/React-Life-Cycle-useEffect</guid>
            <pubDate>Mon, 12 Aug 2024 22:49:47 GMT</pubDate>
            <description><![CDATA[<p><a href="https://ko.legacy.reactjs.org/docs/hooks-effect.html">https://ko.legacy.reactjs.org/docs/hooks-effect.html</a></p>
<h2 id="life-cycle">Life Cycle</h2>
<h3 id="react-component-life-cycle">react component Life Cycle</h3>
<h4 id="a-mount">a. Mount</h4>
<ul>
<li><strong>컴포넌트의 생성, 최초 렌더링되는 순간임</strong><blockquote>
<p>A 컴포넌트가 Mount 되었다 = A 컴포넌트가 처음 렌더링 되었다 
활용) 컴포넌트에서 초기화 작업을 수행,
   서버에서 데이터를 요청 및 화면 출력 작업
   서버와 통신이 불가능한 경우 =&gt; exception 컴포넌트로 이동
   react router 활용. </p>
</blockquote>
</li>
</ul>
<h4 id="b-update">b. Update</h4>
<ul>
<li><strong>컴포넌트가 다시 렌더링 되는 순간, 즉 리렌더링 되는 순간임</strong><blockquote>
<p>A 컴포넌트가 업데이트 되었다 = A 컴포넌트가 리렌더링 되었다. 
활용) 상태 변수의 변화에 따른 처리를 수행할 때 사용. </p>
</blockquote>
</li>
</ul>
<pre><code class="language-java">// Update - 리렌더링, 상태변수 변경하기 
const isMount = useRef(false);
  useEffect(() =&gt; {
    if (!isMount.current) {
      isMount.current = true;
      return;
    } else {
      console.log(&quot;&quot;);
    }</code></pre>
<ul>
<li>deps(의존관계 배열) 이 존재하지 않음.
life cycle 의 update 를 기준을 개발자가 별도로 정의해서 사용 가능함.
어떠한 이벤트가 클릭 되었을 때만 life cycle 의 update 로 인정하겠다는 것.
두번째 매개변수인 의존관계 배열을 매개변수로 전달하지 않았음을 확인할 것!</li>
</ul>
<h4 id="c-unmount">c. UnMount</h4>
<ul>
<li><strong>컴포넌트가 화면에서 사라지는 순간, 렌더링에서 제외되는 순간임</strong><blockquote>
<p>A 컴포넌트가 UnMount 되었다 = A 컴포넌트가 화면에서 사라졌다. 
활용) 컴포넌트가 사용했던 메모리를 정리 (Clean Up) </p>
</blockquote>
<pre><code class="language-java">const (이름) = () =&gt; {
  useEffect( () =&gt; {
      return () =&gt; { 실행할 문장 };
  }, [])
};</code></pre>
</li>
</ul>
<h4 id="life-cycle-순서">Life Cycle 순서</h4>
<p>Mount (컴포넌트 생성) -&gt; Update (컴포넌트의 상태 변화) -&gt; UnMount(컴포넌트 소멸) </p>
<h3 id="useeffect">useEffect()</h3>
<h4 id="렌더링-자체에-의해-발생하는-부수-효과를-특정하는-것으로-특정-이벤트가-아닌-렌더링에-의해-직접-발생한다">렌더링 자체에 의해 발생하는 부수 효과를 특정하는 것으로, 특정 이벤트가 아닌 렌더링에 의해 직접 발생한다.</h4>
<h4 id="1-useeffect-선언하기">1. useEffect 선언하기</h4>
<pre><code class="language-java">useEffect(() =&gt; { 실행할 문장 }, []) </code></pre>
<p>첫 번째 매개변수 : callback 함수,
두 번째 매개변수 : 배열 (option임. 넣어도 되고 안넣어도 됨.) </p>
<h4 id="2-useeffect-의-동작">2. useEffect 의 동작</h4>
<ul>
<li>deps (Dependency Array), 의존성 배열.
deps 에는 여러 개의 의존값이 올 수 있음. </li>
<li>컴포넌트 내에서 원하는 상태 변수의 값이 변경되었을 때 까지만 callback 함수가 실행됨. 
callback 함수는 count 상태 변수에 의존하고 있는 상황임. </li>
</ul>
<h4 id="3-useeffect-실행과-관련된-이해">3. useEffect() 실행과 관련된 이해</h4>
<p>Q. count 를 의존하고 있으므로 useEffect의 callback 함수를 사용하지 않고도, event handler (setCount) 에서 상태변경 함수를 호출한 후에, 변경된 상태값(count) 를 사용하면 되지 않나용 ? 
A. 개소리하지 마십셩 . 안됨니다. 
setCount 는 비동기 함수이기 때문에 useEffect() hook 을 사용해야 함.
정리하면 React 에서 state (상태) 는 비동기로 동작하기 때문에, 변경된 값에 따라서 부가적인 작업을 할 경우에는 반드시 useEffect Hook 을 사용해야 함. </p>
<p>(코드를 보아라 )</p>
<pre><code class="language-java">useEffect(() =&gt; {
    console.log(`count: ${count}`);
  }, [count]);

// event handler 만들기 (버튼클릭 되었을 때 실행되는 함수. )
  const onClickButton = (value) =&gt; {
    // 상태 변경 함수.(setCount) 호출은 되었으나, 완료가 되가 전에
    // consol.log()가 호출된 것
    // 순차처리가 되지 않았으므로 비동기 처리임.
    setCount(count + value);
    console.log(&quot;event handler : &quot; + count);
  };
</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[JAVA - JVM ]]></title>
            <link>https://velog.io/@cojeong_37/JAVA-JVM</link>
            <guid>https://velog.io/@cojeong_37/JAVA-JVM</guid>
            <pubDate>Mon, 12 Aug 2024 22:49:11 GMT</pubDate>
            <description><![CDATA[<h3 id="jvm-의-메모리-구조">JVM 의 메모리 구조</h3>
<p><img src="https://velog.velcdn.com/images/cojeong_37/post/1c127503-2f06-4bd4-af01-353282098499/image.png" alt=""></p>
<p><em><strong>1. method area (메서드 영역)</strong></em></p>
<blockquote>
<ul>
<li>프로그램 실행 중 어떤 클래스가 사용되면, JVM 은 해당 클래스의 클래스 파일을 읽어서 분석하여 클래스에 대한 정보(클래스 데이터) 를 메서드 영역에 저장한다. 이때 그 클래스의 클래스변수도 이 영역에 함께 생성된다. </li>
</ul>
</blockquote>
<p><em>*<em>2. heap (힙) *</em></em></p>
<blockquote>
<ul>
<li>인스턴스가 생성되는 공간. 프로그램 실행 중 생성되는 인스턴스는 모두 힙 영역에 생성된다. 즉 인스턴스 변수들이 생성되는 공간. </li>
</ul>
</blockquote>
<p><em><strong>3. call stack &amp; execution stack (호출 스택)</strong></em></p>
<blockquote>
<ul>
<li>호출 스택은 메서드의 작업에 필요한 메모리 공간을 제공. 
메서드가 호출되면 호출스택에 호출된 메서드를 위한 메모리가 할당되며, 
이 메모리는 메서드가 작업을 수행하는 동안 지역변수들과 연산의 중간 결과 등을 저장하는데 사용된다. 그리고 메서드가 작업ㅇ르 마치면 할당되었던 메모리 공간은 반환된 후에 비워진다. </li>
</ul>
</blockquote>
<hr>
<pre><code>각 메서드를 위한 메모리상의 작업공간은 서로 구별된다. 
첫번째로 호출된 메서드를 위치한 작업공간이 호출 스택의 맨 밑에 마련되고, 
첫 번째 메서드 수행 중에 다른 메서드를 호출하면, 
첫 번째 메서드의 바로 위에 두 번째로 호출된 메서드를 위한 공간이 마련된다.

첫 번째 메서드는 수행을 멈추고, 두 번째 메서드가 수행되기 시작한다. 
두 번째로 호출된 메서드가 수행을 마치게 되면, 
두 번째 메서드를 위해 제공되었던 호출스택의 메모리 공간이 반환되며, 
첫 번째 메서드는 다시 수행을 계속하게 된다.</code></pre><hr>
<blockquote>
<ul>
<li>메서드가 호출되면 수행에 필요한 만큼의 메모리를 스택에 할당 받는다.</li>
</ul>
</blockquote>
<ul>
<li>메서드가 수행을 마치고나면 사용했던 메모리를 반환하고 스택에서 제거된다.</li>
<li>호출스택의 제일 위에 있는 메서드가 현재 실행 중인 메서드이다.</li>
<li>아래에 있는 메서드는 바로 위의 메서드를 호출한 메서드가 된다. </li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[OSI 7Layer , TCP/IP Layer]]></title>
            <link>https://velog.io/@cojeong_37/OSI-7Layer-TCPIP-Layer</link>
            <guid>https://velog.io/@cojeong_37/OSI-7Layer-TCPIP-Layer</guid>
            <pubDate>Sun, 11 Aug 2024 05:47:39 GMT</pubDate>
            <description><![CDATA[<h2 id="osi-7-layer-tcpip-layer">OSI 7 Layer, TCP/IP Layer</h2>
<p><img src="https://velog.velcdn.com/images/cojeong_37/post/6677655a-3578-4760-9eb0-cdebe384e00d/image.png" alt=""></p>
<p><strong>L1. 물리 계층</strong></p>
<ul>
<li>전기적, 기계적, 기능적인 특성을 이용해 데이터를 전송</li>
<li>데이터는 0과 1로 비트열, 즉 On,Off 의 전기적 신호 상태로 이루어져, 해당 계층은 단지 데이터를 전달. </li>
<li>단지 데이터 전달의 역할 뿐만 아니라, 알고리즘, 오류제어 기능이 없음</li>
<li>장비로는 케이블, 리피터, 허브 존재 </li>
</ul>
<p><strong>L2. 데이터 링크 계층</strong></p>
<ul>
<li>물리적인 연결을 통하여 인접한 두 장치 간의 신뢰성 있는 정보 전송을 담당 (Point-To-Point 전송)</li>
<li>안전한 정보의 전달이라는 것은 오류나 재전송하는 기능이 존재. </li>
<li>MAC 주소를 통해서 통신 </li>
<li>데이터 링크 계층에서 데이터 단위는 프레임 </li>
<li>주요 장비: 브리지, 스위치가 있음. </li>
</ul>
<p><strong>L3. 네트워크 계층</strong></p>
<ul>
<li>중계 노드를 통하여 전송하는 경우 어떻게 중계할 것인가를 규정</li>
<li>라우팅 기능을 맡고 있는 계층으로 목적지까지 가장 안전하고 빠르게 데이터를 보내는 기능을 가지고 있음. 
(최적의 경로를 설정 가능) </li>
<li>네트워크 계층에서 데이터 단위는 패킷.</li>
<li>주요 장비 : 라우터, L3 스위치 </li>
</ul>
<p><strong>L4. 전송 계층</strong></p>
<ul>
<li>종단간의 신뢰성 있고 정확한 데이터 전송을 담당.</li>
<li>송신자와 수신자 간의 신뢰성있고, 효율적인 데이터를 전송하기 위하여 오류 검출 및 복구, 흐름제어와 중복검사 등을 수행. </li>
<li>데이터 전송을 위해서 Port 번호를 사용. (대표적인 프로토콜로 TCP, UDP 존재)</li>
<li>전송 계층에서의 데이터 단위는 세그먼트. </li>
</ul>
<p><strong>L5. 세션 계층</strong></p>
<ul>
<li>통신 장치 간의 상호작용 및 동기화를 제공.</li>
<li>연결 세션에서 데이터 교환과 에러 발생 시의 복구를 관리</li>
</ul>
<p><strong>L6. 표현 계층</strong></p>
<ul>
<li>데이터를 어떻게 표현할지 역할을 정하는 계층</li>
<li>주요 3가지 기능</li>
</ul>
<ol>
<li>송신자에서 온 데이터를 해석하기 위한 응용계층 데이터 부호화, 변화 </li>
<li>수신자에서 데이터의 압축을 풀 수 있는 방식으로 된 데이터 압축</li>
<li>데이터의 암호화와 복호화</li>
</ol>
<p>*<em>L7. 응용 계층 *</em></p>
<ul>
<li>사용자와 가장 밀접한 계층으로 인터페이스 역할 </li>
<li>응용 프로세스 간의 정보 교환을 담당 </li>
</ul>
<hr>
<h2 id="tcpip-layer">TCP/IP Layer</h2>
<blockquote>
<p>*<em>네트워크 인터페이스 계층 (L1, L2) *</em></p>
</blockquote>
<ul>
<li>유선 LAN 이나 무선 LAN 어댑터가 처리할 수 있는 형태로 데이터를 변환하고 
이 데이터를 먼 목적지 (광 케이블) 까지 전달하는 것 
전기적 : 네트워크 카드 (NIC)</li>
<li>대표적인 프로토콜 
```</li>
<li>이더넷 : 일반 금속 케이즐이나 광 케이블을 통해 데이터를 전달.</li>
<li>PPP : 사용자 인증 후에 원격지의 장비와 통신.<pre><code></code></pre></li>
</ul>
<blockquote>
<p><strong>인터넷 계층 (L3)</strong> </p>
</blockquote>
<ul>
<li>데이터 어드레스 주소 정보를 덧붙여 목적지까지 전달하는 것,</li>
<li>네트워크 간의 전송</li>
<li>네트워크의 대표적인 장비 : 라우터, L3 스위치 </li>
<li>라우팅 </li>
<li>데이터의 패킷이 출발지에서 목적지로 가는 가장 좋은 경로를 찾는 과정 </li>
<li>라우터의 목적 : 최단 경로를 찾아주는것 (손실 없도록) </li>
<li>L3 스위치, 네트워크 계층</li>
<li>트래픽 모니터링, 라우팅 설정, L2 스위치의 기능도 일부 가지고 있음.
L2 스위치 (데이터 링크 계층) 스위치 경우, MAC 주소를 알고 데이터를 전달하였다면, 
L3 스위치는 IP 주소를 알고 데이터를 전달하는 장비 </li>
<li>대표적인 프로토콜 
```</li>
<li>IP : 패킷을 목적지까지 전달.</li>
<li>ICMP : IP 통신의 오류를 전달.</li>
<li>IPSec : 패킷을 암호화하여 전달.</li>
<li>ARP : 네트워크 장비의 MAC 어드레스를 알아냄.</li>
<li>IP : 가상, DHCP(중복)<pre><code> 고정 IP
 Dynamic IP =&gt; 현재 강의실에서 사용됨.
 MAC 주소 : 물리적(유일)
 해당 MAC 주소를 사용중인 Host 를 알 수 있게 됨.</code></pre><pre><code>
</code></pre></li>
</ul>
<blockquote>
<p><strong>전송 계층 (L4)</strong> </p>
</blockquote>
<ul>
<li>애플리케이션 계층의 프로그램에서 전달받은 데이터를 목적지 애플리케이션의 계층의 프로그램까지 전달하는 것. 
전달의 신뢰성을 위한 기능 : 재전송 기능 </li>
<li>대표적인 프로토콜 
```
A. TCP</li>
<li>애플리케이션의 데이터를 송수신 하되, 정확한 전달을 중시함.
송수신의 데이터의 처리과정의 신뢰성을 보장. 
B. UDP </li>
<li>애플리케이션의 데이터를 송수신하되, 정확한 전달을 중시함.
송수신 데이터의 신뢰성을 보장하지 않음. 
```</li>
<li>L4 스위치, 네트워크 계층
기능
<em>*<em>로드 밸런싱 (부하 분산) *</em></em></li>
<li>외부에서 들어오는 모든 요청을 받은 뒤, 서버들에게 적절하게 요청을 나누어 주는 것.</li>
<li>최악의 경우 서버가 다운되는 경우를 방지
장점 </li>
</ul>
<ol>
<li>가용성 향상 : 다운된 서버를 대신 수행하여 서비스 중단을 최소화</li>
<li>확장성 : 서비스의 사용량이 증가하더라도 새로운 서버를 추가하여 시스템의 성능을 유연하게 확장
사례: 공유기의 기능 (NAT, DHCP, 포트포워드)</li>
</ol>
<blockquote>
<p>*<em>애플리케이션 계층 (L5, L6, L7) *</em></p>
</blockquote>
<ul>
<li>사용자를 위한 서비스를 제공 (웹 브라우저) </li>
<li>대표적인 프로토콜 
```</li>
<li>HTTP : 웹 페이지 데이터를 송수신할 때 사용</li>
<li>HTTPS : 보안을 위해 웨 페이지를 주고 받을 때</li>
<li>POP3 : 서버에 보관된 메일을 꺼내올 때</li>
<li>SMTP : 메일 송신</li>
<li>FTP : 파일 전송</li>
<li>Telnet : 컴퓨터를 원격에서 제어</li>
<li>SSH : 보안을 위해 컴퓨터를 원격에서 제어하는 과정을 암호화.</li>
<li>SMB : 윈도우 컴퓨터와 파일을 공유</li>
<li>DHCP : 컴퓨터에 프라이빗 IP를 동적으로 할당</li>
<li>DNS : 도메인 이름(<a href="http://www.naver.com)%EA%B3%BC">www.naver.com)과</a> IP 어드레스를 서로 변환함.</li>
<li>SSL : 보안을 위해 통신 과정에서 주고받은 데이터를 암호화.
```
L7 스위치
기능</li>
<li>네트워크 트래픽을 분석하고, 처리하여 응용프로토콜 수준에서 동작</li>
<li>웹 애플리케이션의 배포와 부하 분산을 위해서 사용
특징</li>
<li>하위 L2, L3, L4 스위치의 기능을 모두 보유 </li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[OS - 운영체제의 모든 것. ]]></title>
            <link>https://velog.io/@cojeong_37/OS-%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C%EC%9D%98-%EB%AA%A8%EB%93%A0-%EA%B2%83</link>
            <guid>https://velog.io/@cojeong_37/OS-%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C%EC%9D%98-%EB%AA%A8%EB%93%A0-%EA%B2%83</guid>
            <pubDate>Fri, 09 Aug 2024 12:46:53 GMT</pubDate>
            <description><![CDATA[<ol>
<li>운영체제의 정의 . 
모든 프로그램은 하드웨어를 필요로 한다. 
이때 프로그램 실행에 마땅히 필요한 요소들을 가리켜 -&gt; 시스템 자원,
혹은 줄여서 자원이라고 함. 
운영체제란?
실행할 프로그램에 필요한 자원을 할당하고, 프로그램이 올바르게 실행되도록 돕는 특별한 프로그램. </li>
</ol>
<p>운영체제는 매우 특별한 프로그램이기 때문에 항상
언제나 컴퓨터가 부팅될 때 메모리 내에 커널영역이라는 공간에 따로 적재가 되어서 실행이 됨. </p>
<p>커널영역을 제외한 나머지 영억, 사용자가 이용하는 응용프로그램이 적재되는 영역을 사용자 영역 이라고 함. </p>
<p>운영체제가 필요한 이유?
운영체제는 하드웨어를 조작하고, 관리하는 기능들을 제공하기 때문에 개발자는 하드웨어를 조작하는 코드를
직접 작성할 필요가 없이, 운영체제의 도움을 받아서 간편한 개발이 가능함. </p>
<p>Q 빈칸에 알맞은 단어는 ? 이것 = 자원 
운영체제는 실행할 프로그램에 이것을 할당하고, 프로그램이 올바르게 실행되도록 돕는 프로그램</p>
<p>Q. 운영체제에 대한 설명으로 옳지 않은 것은 ?</p>
<ol>
<li>운영체제를 이해하면 하드웨어와 프로그램을 더 깊이 이해할 수 잇다.</li>
<li>운영체제는 사용자 영역에 적재된다. (커널영역) </li>
<li>운영체제는 시스템 자원을 관리하는 프로그램.</li>
<li>운영체제는 사용자가 실행하는 프로그램이 올바르게 실행되도록 돕는다. </li>
</ol>
<p>커널 - 운영체제의 핵심 서비스를 담당하는 부분
커널영역 , 사용자 영역으로 나뉨.
사용자 영역에서는 
커널에 접근하기 위해서는 syscall 사용할 것. 
UI, GUI, CLI -&gt; 운영체제가 제공하는 서비스 중 포함되지 않는 서비스</p>
<ol>
<li><p>이것은 운영체제의 핵심 기능을 담당하는 부분. (커널)</p>
</li>
<li><p>이중 모드와 시스템 호출에 대해 옳지 않은 것? (4)</p>
</li>
<li><p>운영체제의 핵심 서비스는 커널 모드로 실행된다.</p>
</li>
<li><p>시스템 호출을 통해 사용자 모드에서 커널 모드로 전환할 수 있다.</p>
</li>
<li><p>일반적인 응용프로그램은 사용자 모드로 실행된다.</p>
</li>
<li><p>시스템 호출은 인터럽트와 아무런 연관이 없다. </p>
</li>
<li><p>운영체제의 핵심 서비스를 모두 고르시오 (중복 선택) - 1,2,4</p>
</li>
<li><p>프로세스 관리</p>
</li>
<li><p>자원 접근 및 할당</p>
</li>
<li><p>사용자 인터페이스 제공</p>
</li>
<li><p>파일 시스템 관리 </p>
</li>
</ol>
<p>프로세스 우선순위 
우선순위가 높은 프로세스는 빨리 처리해야되는 프로세스.
우선순위가 높은 프로세스에는 대표적으로 입출력 작업이 많은 프로세스가 있음. 
입출력 집중 프로세스 - 입출력 많은 프로세스
CPU 집중 프로세스 -그래픽 처리 작업을 담당하는 프로세스와 같이 CPU 작업이 많은 프로세스 </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[OS]]></title>
            <link>https://velog.io/@cojeong_37/OS</link>
            <guid>https://velog.io/@cojeong_37/OS</guid>
            <pubDate>Thu, 08 Aug 2024 14:58:37 GMT</pubDate>
            <description><![CDATA[<p>운영체제 : 실행할 프로그램에 필요한 자원을 할당하고, 프로그램이 올바르게 실행되도록 돕는 프로그램. </p>
<ol>
<li>프로세스</li>
</ol>
<ul>
<li>프로세스는 실행되기 전까지는 그저 보조기억장치에 있는 데이터 덩어리 일 분이지만, 
보조 기억 장치에 저장된 프로그램을 메모리에 적재하고, 실행하는 순간 그 프로그램은 프로세스가 된다 </li>
<li><blockquote>
<p>현재 실행중인 프로그램. !! </p>
</blockquote>
</li>
</ul>
<p>포그라운드 프로세스 -&gt; 사용자 보는 앞에서 실행되는 프로세스
백그라운드 프로세스 -&gt; 사용자가 보지 못하는 뒤에서 실행중인 프로세스
-&gt; 데몬 프로세스 (유닉스 운영체제에서 사용하는 말 ! ) !! </p>
<p>PCB </p>
<ol>
<li>모든 프로세스는 실행을 위해 CPU 를 필요로 하지만, CPU 자원은 한정되어 있다.
즉 모든 프로세스가 CPU를 동시에 사용할 수는 없다!</li>
</ol>
<p>프로세스들은 차례대로 돌아가면서 한정된 시간 만큼간 CPU 를 사용한다.</p>
<p>자신의 차례가 되면 정해진 시간만큼 CPU를 사용을하고, 시간이 끝났으면 이를 알리는 
! 인터럽트 (타이머 인터럽트) 가 발생한다. !
자신의 차례를 양보를 하고, 다음차례가 올때까지 또 기다림. </p>
<p>운영체제는 빠르게 번갈아 수행되는 프로세스의 실행순서를 관리하고, 프로세스에 CPU를 비롯한 자원들을 분배함 </p>
<p>-&gt; 프로세스와 관련된 정보를 저장하는 자료구조 
PCB의 생성 위치 : 커널영역 
PCB의 생성 시기 : 프로세스 생성 시에 생성, 그리고 실행이 끝나면 폐기가 됨,
새로운 프로세스가 생성되었음 = PCB 가 생성이 되었음.</p>
<p>PCB 에 담긴 정보</p>
<ol>
<li>프로세스 아이디 PID</li>
<li>레지스터 값 
(레지스터 
프로세서에 위치한 고속 메모리로 극히 소량의 데이터나 처리 중인 중간 결과와도 같은 프로세서가 바로 사용할 수 있는 데이터를 담고 있는 영역) </li>
</ol>
<p>-&gt; 프로세스는 자신의 실행 순서가 종료되면 이전까지 사용했던 레지스터의 중간값들을 모두 복원함. 
그래야만 이전까지 진행했던 작업들을 그대로 이어 실행할 수 있기 때문에!! 
=&gt; 해당 프로세스가 실행을하면서 자신이 사용했던 프로그램을 비롯해 레지스터 값들이 포함됨. </p>
<ol start="3">
<li>프로세스의 상태</li>
<li>CPU 스케줄링의 정보</li>
<li>메모리 관리 정보</li>
<li>사용한 파일과 입출력장치의 목록 </li>
</ol>
<p>Context switching (문맥 교환) </p>
<ul>
<li><p>기존 프로세스의 문맥을 PCB 에 백업하고, 새로운 프로세스를 실행하기 위해 문맥을 PCB 로 부터 복구하여 새로운 프로세스를 실행하는 것 </p>
<ul>
<li>정적할당 영역 (코드 + 데이터 영역) 
프로세스의 메모리 영역
코드 영역</li>
</ul>
</li>
<li><blockquote>
<p>텍스트 영역 : 실행할 수 있는 코드 , 기계어로 이루어진 명령어가 저장이 됨.
CPU가 실행할 명령어가 담겨 있기 때문. 읽기 전용 공간</p>
</blockquote>
</li>
</ul>
<p>데이터 영역</p>
<ul>
<li><p>전역 변수가 저장되는 영역.</p>
</li>
<li><p>프로그램이 실행되는 동안 유지할 데이터가 저장됨. </p>
</li>
<li><blockquote>
<p>프로그램이 실행되는 동안 유지가 되며, 프로그램 전체에서 접근할 수 있는 변수가 저장되는 영역 </p>
</blockquote>
</li>
<li><p>동적 할당 영역 
힙 영역</p>
</li>
<li><p>프로그램을 만드는 사용자, 프로그래머가 직접적으로 할당할 수 있는 저장공간 
메모리 누수 - 할당한 영역을 다시 반환해 주지 않을 경우 생기는 메모리상의 문제 </p>
</li>
</ul>
<p>스택 영역 </p>
<ul>
<li>스택 영역은 데이터를 일시적으로 저장하는 공간. 
매개변수 + 지역변수가 대표적 -&gt; 일시적으로 사용할 데이터 정도로 생각해도 무방데스 </li>
</ul>
<p>힙영역 -&gt; 메모리의 낮은 주소 -&gt; 높은 주소 할당
스택 영역 -&gt; 메모리의 높은 주소 -&gt; 낮은 주소 할당 </p>
<p>Q. 프로세스와 관련한 설명 중 옳지 않은 것은? 4</p>
<ol>
<li>실행되는 프로그램을 프로세스라 한다.</li>
<li>프로세스가 생성되면 커널 영역에 PCB 가 생성된다.</li>
<li>프로세스들으 문맥 교환을 통해 번갈아 가면서 수행된다.</li>
<li>프로세스는 반드시 사용자와 상호작용을 할 수 있어야 한다. </li>
</ol>
<p>Q. 문맥 교환과 관련한 설명 중 옳지 않은 것? 1. </p>
<ol>
<li>문맥 교환은 빠르게 실행될 수록 좋다 </li>
</ol>
<p>-&gt; 문맥 교환이 지나치게 빠르게 반복이 되면 문맥 교환에 드는 오버헤드로 인해 좋지않음
2. 문맥 교환 과정에서 직전에 수행되던 프로세스의 문맥이 백업된다.
3. 문맥 교환 과정에서 다음에 수행할 프로세스의 문맥이 복구된다.
4. 문맥은 프로세스 제어 블록에 기록된다. </p>
<p>프로세스 상태와 계층 구조 
프로세스의 상태</p>
<ol>
<li>생성(new)</li>
</ol>
<p>-&gt; 프로세스를 생성중인 상태 
-&gt; 이제 막 메모리에 적재되서 PCB 를 할당받은 상태 </p>
<ol start="2">
<li>준비 (Ready) </li>
</ol>
<p>-&gt; 아직 자신의 차례가 아니기 때문에 기다리고 있는 상태</p>
<ol start="3">
<li>실행 상태 (run)</li>
</ol>
<p>-&gt; CPU 를 할당 받아서 실행 중인 상태 
-&gt; 실행 상태인 프로세는 할당된 일정 시간동안만 CPU를 사용할 수 있다. 
이때 프로세스가 할당된 시간을 모두 사용한다면 -&gt; 타이머 인터럽트가 발생 
다시 준비상태로 돌아감.</p>
<p>실행 도중에 입출력 장치를 사용해서 입출력 작업이 끝날때까지 기다려야 하는 경우 
=&gt; 대기 상태로 감. </p>
<ol start="4">
<li>대기 (wait)</li>
</ol>
<p>-&gt; 프로세스는 실행 도중 입출력 장치를 사용하는 경우가 종종 있다. 
입출력 작업은 CPU 에 비해 처리 속도가 느리다. 그래서 입출력 작업을 요청한 프로세스는 입출력 장치가 입출력을 끝낼 때 까지 (입출력 완료 인터럽트) 기다려야 한다. 
입출력 작업이 완료되면 해당 프로세스는 다시 준비상태로 가서 CPU 할당을 기다린다. </p>
<ol start="5">
<li>종료 (terminate) </li>
</ol>
<p>-&gt; 프로세스가 종료된 상태 </p>
<p><img src="https://velog.velcdn.com/images/cojeong_37/post/b6d0a88f-125c-4ae0-985f-f6fef2f6aafc/image.png" alt=""></p>
<p>프로세스 계층 구조 
부모 PID
    - PPID </p>
<p>프로세스 생성 기법 - fork(), exec() 
fork () - 자식 프로세스를 복제하는 syscall </p>
<ul>
<li>자신 프로세스의 복사본을 만드는 syscall. 
만들어진 복사본 (자식 프로세스) 는 exec() syscall 을 통해 자신의 메모리 공간을 다른 프로그램으로 교체함. </li>
</ul>
<p>부모가 자식 프로세스를 실행하면서 프로세스 계층구조는 fork exec 가 반복되는 과정이라 볼 수 있음. </p>
<p>스레드 : 프로세스를 구성하는 가장 작은 실행 단위 ! 
스레드는 실행이 단위,
프로세스를 구성하는 실행의 흐름단위. </p>
<p>하나의 프로세스는 여러가지의 스레드를 가질 수 있음. 
하나의 프로세스에서 여러 부분을 동시적으로 실행할 수 있음. </p>
<p>프로세스와 스레드~
단일 스레드 프로세스 : 한번에 하나의 부분만 실행되는 프로세스 </p>
<p>멀티 프로세스와 멀티 스레드
멀티 프로세스  : 여러 프로세스를 동시에 실행하는 것. 
멀티 스레드 ; 여러 스레드로 프로세스를 동시에 실행하는 것. </p>
<p>-&gt; 프로세스끼리는 기본적으로 자원을 공유하지 않지만, 프로세스 내의 스레드는 같은 프로세스 내의 자원을 공유한다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[React - useState]]></title>
            <link>https://velog.io/@cojeong_37/React-useState</link>
            <guid>https://velog.io/@cojeong_37/React-useState</guid>
            <pubDate>Thu, 08 Aug 2024 12:57:35 GMT</pubDate>
            <description><![CDATA[<h3 id="usestate---컴포넌트의-형재-상태를-생성보관하는-함수">useState - 컴포넌트의 형재 상태를 생성,보관하는 함수</h3>
<h4 id="1-usestate-사용하기">1. useState 사용하기</h4>
<blockquote>
<p>const[state, setState] = useState(초기값);
state : 현재 상태 정보
setState : 현재 상태 정보를 변경해주고 싶을 때 사용 
최초로 렌더링을 하는 동안 반환된 state는 첫번째로 전달된 인자 (initialState) 의 값과 동일. </p>
</blockquote>
<blockquote>
<pre><code class="language-java">import { useState } from &quot;react&quot;;
function App() {
  const [time, setTime] = useState(1);
  const handleClick = () =&gt; {
    let newTime;
    if (time &gt;= 12) {
      newTime = 1;
    } else {
      newTime = time + 1;
    }
    setTime(newTime);
  };
  return (
    &lt;div&gt;
      &lt;span&gt;현재 시각 : {time} 시&lt;/span&gt;
      &lt;button onClick={handleClick}&gt;update&lt;/button&gt;
    &lt;/div&gt;
  );
}
export default App;</code></pre>
</blockquote>
<pre><code></code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[JPA - Criteria]]></title>
            <link>https://velog.io/@cojeong_37/JPA-Criteria</link>
            <guid>https://velog.io/@cojeong_37/JPA-Criteria</guid>
            <pubDate>Tue, 06 Aug 2024 23:12:16 GMT</pubDate>
            <description><![CDATA[<h3 id="criteria-쿼리">Criteria 쿼리</h3>
<ul>
<li>JPQL 을 자바 코드로 작성하도록 도와주는 빌더 클래스 API 임. </li>
</ul>
<p>장점 </p>
<blockquote>
<p>문자가 아닌 코드로 JQPL을 작성하므로 문법 오류를 컴파일 단계에서 잡을 수 있고
문자 기반의 JPQL 보다 동적 쿼리를 안전하게 생성할 수 있다.</p>
</blockquote>
<p>단점</p>
<blockquote>
<p>코드가 복잡하고 장황해서 직관적으로 이해가 힘들다는 단점도 존재함. </p>
</blockquote>
<pre><code class="language-java">// JPQL 의 문법
select m from Member m 

CriteriaBuilder cb = em.getCriteriaBuilder(); // cireteria 쿼리 빌더 

//Criteria 생성, 반환타입 지정
CriteriaQuery&lt;Member&gt; cq = cb.createQuery(Member.class);

Root&lt;Member&gt; m = cq.from(Member.class);
cq.select(m);

TypedQuery&lt;Member&gt; query = em.creteQuery(cq);
List&lt;Member&gt; members = query.getResultList();</code></pre>
<p>-&gt; Criteria 쿼리를 생성하려면 먼저 Criteria 빌더를 얻어야 한다. Criteria 빌더는 Entity Manager 나 Entity Manager Factory 에서 얻을 수 있다.
-&gt; Criteria 쿼리 빌더에서 Criteria 쿼리를 생성한다. 이때 반환 타입을 지정할 수 있다. 
-&gt; From 절을 생성한다. 반환된 값 m 은 Criteria 에서 사용하는 특별한 별칭으로, m을 조회의 시작점이라는 의미로 쿼리 루트 (Root) 라 한다.
-&gt; Select 절을 생성한다. </p>
<p><del>대충햇다고 반박하면 물어버린다</del></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[React - useReducer ]]></title>
            <link>https://velog.io/@cojeong_37/React-useReducer</link>
            <guid>https://velog.io/@cojeong_37/React-useReducer</guid>
            <pubDate>Tue, 06 Aug 2024 14:27:43 GMT</pubDate>
            <description><![CDATA[<h2 id="📍-usereducer-📍">📍 useReducer 📍</h2>
<h3 id="컴포넌트에서-상태-변화-코드를-쉽게-분리할-수-있는-reack-hook">컴포넌트에서 상태 변화 코드를 쉽게 분리할 수 있는 Reack Hook</h3>
<hr>
<h4 id="usereducer">useReducer</h4>
<blockquote>
<ul>
<li>useState와 더불어 리액트 컴포넌트에서 State 를 관리하는 리액트 훅. </li>
</ul>
</blockquote>
<ul>
<li>State 관리를 컴포넌트의 내부가 아닌 외부에서 할 수 있게 만든다 . </li>
<li>useState 와는 달리 State를 관리하는 상태 변화 코드를 컴포넌트와 분리할 수 있다.</li>
<li><blockquote>
<p>파일로도 분리가 가능하기 때문에 컴포넌트 내부가 훨씬 간결해진다. </p>
</blockquote>
<pre><code>상태변화 코드를 컴포넌트 내부에서 분리한다는 것 
= 컴포넌트 내부에 작성했던 상태 변화 코드를 외부에 작성한다는 것.
useState 를 사용해서 state 생성하면 컴포넌트 내에서 선언했기 때문에 
상태변화 코드를 분리할 수 없다. </code></pre></li>
<li><em>상태변화 코드를 분리하는 이유 *</em></li>
<li><blockquote>
<p><em>하나의 컴포넌트 내에 너무 많은 상태 변화 코드가 존재하면 가독성을 해쳐 유지보수를 어렵게 만들기 때문</em></p>
</blockquote>
</li>
<li><ul>
<li>✨ 결론 : useReducer 를 호출해 useState 처럼 State를 만들 수 있다. ✨ **</li>
</ul>
</li>
</ul>
<p><strong>useReducer 사용법</strong></p>
<blockquote>
<p>const[count, dispatch] = useReducer (reducer, 0); </p>
</blockquote>
<p>*<em>매개변수의 정보 *</em></p>
<p><code>reducer</code></p>
<blockquote>
<p>state가 어떻게 업데이트 되는지 지정하는 리듀서 함수. 리듀서 함수는 반드시 순수 함수여야 하며, state와 action을 인수로 받아야 하고, 다음 state를 반환해야 합니다. state와 action에는 모든 데이터 타입이 할당될 수 있습니다.</p>
</blockquote>
<hr>
<p><code>initialArg</code></p>
<blockquote>
<p>초기 state가 계산되는 값임. 모든 데이터 타입이 할당될 수 있으며, 초기 state가 어떻게 계산되는지는 다음 init 인수에 따라 달라진다. </p>
</blockquote>
<hr>
<p><code>선택사항 init</code> </p>
<blockquote>
<p>초기 state를 반환하는 초기화 함수입니다. 이 함수가 인수에 할당되지 않으면 초기 state는 initialArg로 설정됩니다. 할당되었다면 초기 state는 init(initialArg)를 호출한 결과가 할당됩니다.</p>
</blockquote>
<hr>
<p>** ✨ 반환값 정보 ✨ **
useReducer는 2개의 엘리먼트로 구성된 배열을 반환한다. </p>
<p>현재 state. 첫번째 렌더링에서의 state는 init(initialArg) 또는 initialArg로 설정됨. (init이 없을 경우 initialArg로 설정된다).</p>
<p><code>dispatch 함수</code> 
dispatch는 state를 새로운 값으로 업데이트하고 리렌더링을 일으키는 함수</p>
<hr>
<pre><code class="language-java">import { useReducer } from &#39;react&#39;;

function reducer(state, action) {
  if (action.type === &#39;incremented_age&#39;) {
    return {
      age: state.age + 1
    };
  }
  throw Error(&#39;Unknown action.&#39;);
}

export default function Counter() {
  const [state, dispatch] = useReducer(reducer, { age: 42 });

  return (
    &lt;&gt;
      &lt;button onClick={() =&gt; {
        dispatch({ type: &#39;incremented_age&#39; })
      }}&gt;
        Increment age
      &lt;/button&gt;
      &lt;p&gt;Hello! You are {state.age}.&lt;/p&gt;
    &lt;/&gt;
  );
}
</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[React - useEffect]]></title>
            <link>https://velog.io/@cojeong_37/React-useEffect</link>
            <guid>https://velog.io/@cojeong_37/React-useEffect</guid>
            <pubDate>Tue, 06 Aug 2024 14:04:35 GMT</pubDate>
            <description><![CDATA[<h2 id="📍-useeffect-📍">📍 useEffect 📍</h2>
<h3 id="어떠한-값이-변경-될-때-마다-특정-코드를-실행하는-react-hook">어떠한 값이 변경 될 때 마다 특정 코드를 실행하는 React Hook.</h3>
<blockquote>
<h3 id="🌟-react-life-cycle-🌟">🌟 React Life Cycle 🌟</h3>
<p>   <em><strong>1.Mount</strong></em></p>
</blockquote>
<ul>
<li>컴포넌트가 페이지에 처음 렌더링 될 때</li>
</ul>
<hr>
<blockquote>
<p><em><strong>2.Update</strong></em></p>
</blockquote>
<ul>
<li>State 나 Props의 값이 바뀌거나, 부모 컴포넌트가 리렌더링 되어, 자신도 리렌더링 될 때 </li>
</ul>
<hr>
<blockquote>
<p><em><strong>3.UnMount</strong></em></p>
</blockquote>
<ul>
<li>더 이상 페이지에 컴포넌트가 렌더링 되지 않을 때</li>
</ul>
<hr>
<h3 id="2📍-useeffect-의-사용법-📍">2.📍 useEffect 의 사용법 📍</h3>
<blockquote>
<p>useEffect (callback, [ deps ]) 
첫번째 매개변수 : 콜백함수
두번째 매개변수 : 의존성 배열 (deps) </p>
</blockquote>
<blockquote>
<ul>
<li>useEffect 는 의존성 배열의 값이 변경되면 첫 번째 인수로 전달한 콜백 함수를 실행한다. </li>
</ul>
</blockquote>
<ul>
<li>의존성 배열에 아무것도 전달하지 않으면 useEffect 는 컴포넌트를 렌더링할 때 마다 콜백함수를 실행한다.</li>
<li>useEffect 는 컴포넌트가 외부 시스템과 동기화를 유지할 수 있도록 하고, 
외부 시스템은 React 에 의해 컨트롤 되지 않은 모든 코드를 의미한다. <pre><code class="language-java">setInterval()에 의해 관리되는 타이머 또는 clearInterval().
window.addEventListener()을 이용한 이벤트 구독 또는 window.removeEventListener().
animation.start()와 같은 서드 파티 애니메이션 라이브러리 API 또는 animation.reset().</code></pre>
</li>
</ul>
<blockquote>
<h3 id="-cleanup">+ cleanup</h3>
<p>리액트 컴포넌트의 언마운트 시점을 제어하기 위해 사용된다.
프로그래밍에서 이 개념은 특정 함수가 시랳오디고 종료된 후에, 미처 정리하지 못한 사항을 처리하는 일. </p>
</blockquote>
<p>code ) </p>
<pre><code class="language-java">import { useState, useEffect } from &quot;react&quot;;

function App() {
  const [count, setCount] = useState(1);
  const [name, setName] = useState;
  const handleCountUpdate = () =&gt; {
    setCount(count + 1);
  };
  const handleInputChange = (e) =&gt; {
    setName(e.target.value);
  };
  // 마운트 될때, 
  useEffect(() =&gt; {
    console.log(&quot;useEffect&quot;);
  }, [count]);

  useEffect (() =&gt; {

  }, [])
  return (
    &lt;div&gt;
      &lt;button onClick={handleCountUpdate}&gt;Update&lt;/button&gt;
      &lt;span&gt; count : {count}&lt;/span&gt;
      &lt;input type=&quot;text&quot; value={name} onChange={handleInputChange} /&gt;
      &lt;span&gt; name : {name} &lt;/span&gt;
    &lt;/div&gt;
  );
}

export default App;</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[JPQL , Persistence Context]]></title>
            <link>https://velog.io/@cojeong_37/JPQL-Persistence-Context</link>
            <guid>https://velog.io/@cojeong_37/JPQL-Persistence-Context</guid>
            <pubDate>Thu, 01 Aug 2024 11:16:44 GMT</pubDate>
            <description><![CDATA[<h3 id="📍-영속성-컨텍스트와-jpql-📍">📍 영속성 컨텍스트와 JPQL 📍</h3>
<p><em>*<em>1. 쿼리 후 영속 상태인 것과 영속 상태가 아닌 것. *</em></em></p>
<blockquote>
<p>JPQL 의 조회 대상은 엔터티, 임베디드 타입, 값 타입 같이 다양한 종류가 존재한다.
JPQL 로 엔터티를 조회하면 영속성 컨텍스트에서 관리되지만 엔터티가 아니면 영속성 컨텍스트에서 관리되지 않는다. </p>
</blockquote>
<p><em>*<em>2. JPQL 로 조회한 엔터티와 영속성 컨텍스트 *</em></em></p>
<blockquote>
<p>JPQL 로 데이터베이스에서 조회한 엔터티가 영속성 컨텍스트에 이미 존재할 경우, 
JPQL 로 데이터베이스에서 조회한 결과를 버리고 대신에 영속성 컨텍스트에 있던 엔터티를 반환한다.
이때는 식별자 값을 사용해서 비교한다. </p>
<blockquote>
<ul>
<li>JPQL 로 조회한 엔터티는 영속 상태이다.</li>
</ul>
</blockquote>
</blockquote>
<ul>
<li><em>*<em>영속성 컨텍스트에 이미 존재하는 엔터티가 있으면 기존 엔터티를 반환한다. *</em></em>
❗️데이터베이스에서 새로 조회한 엔터티를 버리고 영속성 컨텍스트에 있는 기존 엔터티를 반환하는 이유
❗️ JPQL 로 조회한 새로운 엔터티를 영속성 컨텍스트에 하나 더 추가하거나,<pre><code> 기존 엔터티를 새로 검색한 엔터티로 대체하면 발생하는 문제 ? ?</code></pre>👉🏻 <strong>영속성 컨텍스트는 기본 키 값을 기준으로 엔터티를 관리한다. 따라서 같은 기본 키 값을 가진 엔터티는 등록할 수 없다. **
_</strong> ❗️ 영속성 컨텍스트는 영속 상태인 엔터티의 동일성을 보장한다 ❗️ **_ 는 것을 기억할 것. </li>
</ul>
<p><em>*<em>3. find() vs JPQL *</em></em></p>
<blockquote>
<p><code>em.find()</code> 메소드는 <strong><em>엔터티를 영속성 컨텍스트에서 먼저 찾고 없으면 데이터베이스에서 찾는다.</em></strong>
따라서 해당 엔터티가 영속성 컨텍스트에 있으면 메모리에서 바로 찾으므로 성능상 이점이 있다 
 (1차 캐시라 부르는 이유) </p>
</blockquote>
<hr>
<blockquote>
<blockquote>
<p>JPQL 은 항상 데이터베이스에 SQL 을 실행해서 결과를 조회한다.
<code>em.find()</code> 메소드는 영속성 컨텍스트에서 엔터티를 먼저 찾고 없으면 데이터베이스에서 조회하지만, 
_<strong>JPQL 을 사용하면 데이터베이스를 먼저 조회</strong>_한다. </p>
</blockquote>
</blockquote>
<hr>
<blockquote>
<blockquote>
<p>JPQL 을 호출하면 데이터베이스에서 회원 엔터티를 조회하고 영속성 컨텍스트에 등록한다.
두번째 JPQL 을 호출하면 데이터베이스에서 같은 회원 엔터티를 조회한다. </p>
</blockquote>
</blockquote>
<hr>
<p><em><strong>JPQL 의 특징</strong></em></p>
<blockquote>
<ol>
<li>JPQL 은 항상 데이터베이스를 조회한다.</li>
<li>JPQL 로 조회한 엔터티는 영속 상태이다.</li>
<li>영속성 컨텍스트에 이미 존재하는 엔터티가 있으면 기존 엔터티를 반환한다. 
⭐️ JPQL 은 SQL 을 추상화해서 특정 데이터 베이스 기술에 의존하지 않는다. ⭐️</li>
</ol>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[JPQL - 조인, 서브쿼리]]></title>
            <link>https://velog.io/@cojeong_37/JPQL-%EC%A1%B0%EC%9D%B8-%EC%84%9C%EB%B8%8C%EC%BF%BC%EB%A6%AC</link>
            <guid>https://velog.io/@cojeong_37/JPQL-%EC%A1%B0%EC%9D%B8-%EC%84%9C%EB%B8%8C%EC%BF%BC%EB%A6%AC</guid>
            <pubDate>Thu, 01 Aug 2024 10:49:43 GMT</pubDate>
            <description><![CDATA[<h4 id="🌟-jpql-은-결과-반환-시에-연관관계-까지-고려하지-않는다-단지-select-절에-지정한-엔터티만-조회한다🌟">🌟 JPQL 은 결과 반환 시에 연관관계 까지 고려하지 않는다. 단지 SELECT 절에 지정한 엔터티만 조회한다.🌟</h4>
<hr>
<h3 id="📍-1-내부-조인-📍">📍 1. 내부 조인 📍</h3>
<blockquote>
<p>내부 조인 사용시에는 <code>INNER JOIN</code> 을 사용하고, INNER 는 생략이 가능하다.  </p>
</blockquote>
<pre><code class="language-sql">Stirng teamName = &quot;팀A&quot;;
Stirng query = &quot;SELECT m FROM Member m INNER JOIN m.team t &quot; + 
&quot;WHERE t.name = &quot;teamName&quot;;</code></pre>
<ul>
<li>JPQL 가장 큰 특징은 연관 필드를 사용한다는 것 (m.team) </li>
</ul>
<hr>
<h3 id="📍-2-외부-조인-📍">📍 2. 외부 조인 📍</h3>
<blockquote>
<pre><code class="language-sql">SELECT m 
FROM Member m LIST [OUTER] JOIN m.team t;</code></pre>
</blockquote>
<pre><code>- Outer 는 생략이 가능해서 보통 LEFT JOIN 으로 많이 사용하한다. 

### 📍 3. 컬렉션 조인 📍
&gt; - 일대다 관계, 다대다 관계 처럼 컬렉션을 사용하는 곳에 조인하는 것을 컬렉션 조인이라 한다. </code></pre><p>[회원 -&gt; 팀] 으로의 조인: 다대일 조인이면서 단일 값 연관 필드 (m.team) 을 사용한다 
[팀 -&gt; 회원] 으로의 조인: 일대다 조인이면서 컬렉션 값 연관 필드 (m.members) 를 사용한다. </p>
<pre><code>CODE) 
``` sql 
SELECT t, m FROM Team t LEFT JOIN t.members m</code></pre><ul>
<li>여기서 t LEFT JOIN t.members 는 팀과 팀이 보유한 회원목록을 컬렉션 값 연관 필드로 외부 조인했다. </li>
</ul>
<hr>
<h3 id="📍-4-페치-조인-📍">📍 4. 페치 조인 📍</h3>
<blockquote>
<p>JPQL 에서 성능 최적화를 위해 제공하는 기능
 <strong>연관된 엔터티나 컬렉션을 한 번에 같이 조회하는 기능</strong> <code>join fetch</code> 사용 </p>
<blockquote>
<ul>
<li>엔티티 페치 조인
-&gt; 페치 조인을 사용해서 회원 엔티티를 조회하면서 연관된 팀 엔터티도 함께 조회하는 JPQL</li>
</ul>
</blockquote>
</blockquote>
<pre><code class="language-sql"> select m FROM Member m join fetch m.team</code></pre>
<ul>
<li>join fetch 를 사용하면 연관된 엔터티나, 컬렉션을 함께 조회한다.
(회원 (m) 과 팀(m.team) 을 함께 조회한다. 페치 조인은 별칭을 사용할 수 없다. </li>
</ul>
<hr>
<blockquote>
<blockquote>
<p>** 페치 조인의 특징과 한계 **
     1. 페치 조인을 사용하면 SQL 한번으로 연관된 엔터티들을 함께 조회할 수 있어서 SQL 호출 횟수를 줄여 성능 최적화가 가능하다. </p>
</blockquote>
</blockquote>
<pre><code>  글로벌 로딩 전략 - 엔터티에 직접 적용하는 로딩 전략  
  최적화를 위해 글로벌 로딩 전략을 즉시 로딩으로 설정하면 애플리케이션 전체에서 항상 즉시 로딩이 일어난다.
  물론 일부는 빠를 수 있으나, 전체적으로 봤을때 사용하지 않는 엔터티를 자주 로딩하므로 오히려 성능면으로는 좋지 않은 편.
  따라서 글로벌 로딩 전략 사용시에는 지연 로딩을 사용하고, 최적화가 필요할 경우에는 페치 조인을 적용하는 것이 효과적. </code></pre><pre><code>  2. 페치 조인 대상에는 별칭을 줄 수 없다. 
3. 둘 이상의 컬렉션을 페치할 수 없다.
4. 컬렉션을 페치 조인할 경우 페이징 API 를 사용할 수 없다.
5. 페치 조인은 SQL 한번으로 연관된 여러 엔터티를 조회할 수 있기 때문에 성능 최적화에 상당히 유용함. </code></pre><hr>
<h3 id="📍-서브쿼리--📍">📍 서브쿼리  📍</h3>
<blockquote>
<p>서브쿼리 함수 </p>
<ul>
<li>[NOT] EXISTS (subquery) 
-&gt; 서브쿼리에 결과가 존재하면 참. NOT 은 반대 </li>
</ul>
</blockquote>
<ul>
<li>{ALL | ANY | SOME } (subquery) </li>
<li><blockquote>
<p>비교 연산자와 같이 사용</p>
<pre><code>   - ALL : 조건을 모두 만족하면 참
  - ANY &amp; SOME : 조건을 하나라도 만족하면 참. </code></pre></blockquote>
</li>
<li>[NOT] IN (subqeury) </li>
<li><blockquote>
<p>서브쿼리의 결과 중 하나라도 같은 것이 있으면 참. </p>
</blockquote>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[JPQL]]></title>
            <link>https://velog.io/@cojeong_37/JPQL</link>
            <guid>https://velog.io/@cojeong_37/JPQL</guid>
            <pubDate>Wed, 31 Jul 2024 23:54:19 GMT</pubDate>
            <description><![CDATA[<h3 id="📍-jpql-java-persistence-query-language-📍">📍 JPQL (Java Persistence Query Language) 📍</h3>
<blockquote>
<p>*<em>JPQL 의 특징 *</em></p>
</blockquote>
<ol>
<li>테이블이 아닌 객체를 대상으로 검색하는 객체지향 쿼리.</li>
<li>SQL 을 추상화해서 특정 데이터베이스 SQL 에 의존하지 않는다. </li>
<li>SQL 보다 간결하다. 
엔터티 직접 조회, 묵시적 조인, 다형성 지원으로 SQL 보다 코드가 간결하다. <blockquote>
<blockquote>
<p>A. 결과 조회</p>
</blockquote>
</blockquote>
</li>
</ol>
<ul>
<li>실제 쿼리를 실행해서 데이터베이스를 조회한다.</li>
</ul>
<ol>
<li><code>query.getResultList()</code> : 결과를 예제로 반환한다.
만약 결과가 없으면 빈 컬렉션을 반환한다.</li>
<li><code>query.getSingleResult()</code> : 결과가 정확히 하나일 때 사용한다.</li>
</ol>
<hr>
<blockquote>
<blockquote>
<p>B. 파라미터 바인딩 
<strong>1. 이름 기준 파라미터</strong> : 파라미터를 이름으로 구분하는 방법  [ : ]사용 </p>
</blockquote>
</blockquote>
<pre><code class="language-java">String usernameParm = &quot;User1&quot;;
TypedQuery&lt;Member&gt; query = 
    em.createQuery(&quot;SELECT m FROM Member m where m.username = :username&quot;,
                                            Member.class);
query.setParameter (&quot;username&quot;, usernameParam)l
List&lt;Member&gt; resultList = query.getResultList();</code></pre>
<p><strong>2. 위치 기준 파라미터</strong> : 파라미터를 위치로 구분하는 방법 [ ? ] 사용</p>
<pre><code class="language-java">List&lt;Member&gt; members = 
        em.createQuery(&quot;SELECT m FROM Member where m.username 
            = ?1&quot;, Member.class).setParameter(1, usernameParam)
            .getResultList();</code></pre>
<hr>
<p><strong>3. 페이징 API</strong></p>
<ol>
<li><code>setFirstResult (int startPosition)</code> : 조회 시작 위치</li>
<li><code>setMaxResults (int maxResult)</code> : 조회할 데이터의 수<pre><code class="language-sql">TypedQuery&lt;Member&gt; query = em.createQuery (&quot;select m from Member m 
ORDER BY m.username DESC&quot;, Member.class);
query.setFristResult(10); // 10 번부터 ~
query.setMaxResult(20); // 20 개의 데이터를 조회 - 11 ~ 30 번 까지 조회됨.
query.getResultList();</code></pre>
</li>
</ol>
<hr>
<p>*<em>4. 집합과 정렬 *</em></p>
<ul>
<li>집합은 집합함수와 함께 통계 정보를 구할 때 사용.
<code>COUNT</code> : 결과 수를 구한다 (Long)
<code>MAX, MIN</code> : 최대, 최소 값을 구한다. 문자, 숫자, 날짜 등에 사용한다
<code>AVG</code> : 평균값을 구한다 . (Double) 
<code>SUM</code> : 합을 구한다. 숫자 타입만 사용할 수 있다.<pre><code>집합 함수 사용시 고려사항
  1. Null 값은 무시하므로 통계에 잡히지 않는다 (DISTINCT 가 정의되어 있어도 무시한다. )
  2. 만약 값이 없는데 SUM, AVG, MAX, MIN 함수를 사용하면 NULL 값이 된다. 
                                                      단 COUNT 는 0이 된다.
  3. DISTINCT 를 집합 함수 안에 사용해서 중복된 값을 제거하고 나서 집합을 구할 수 있다. 
  4. DISTINCT 를 COUNT 에서 사용할 때 임베디드 타입은 지원하지 않는다. </code></pre></li>
<li>정렬 
오름차순 : ASC
내림 차순 : DESC</li>
</ul>
<hr>
]]></description>
        </item>
        <item>
            <title><![CDATA[JPA - 즉시 & 지연 로딩, 영속성 전이와 고아객체]]></title>
            <link>https://velog.io/@cojeong_37/JPA-CH08</link>
            <guid>https://velog.io/@cojeong_37/JPA-CH08</guid>
            <pubDate>Wed, 31 Jul 2024 23:13:58 GMT</pubDate>
            <description><![CDATA[<h3 id="📍-1-즉시-로딩-지연-로딩-📍">📍 1. 즉시 로딩, 지연 로딩 📍</h3>
<blockquote>
<blockquote>
<p><strong>즉시로딩 : 엔터티를 조회할 때 연관된 엔터티도 함께 조회</strong>
<code>@ManyToOne (fetch = FetchType.EAGER)</code></p>
</blockquote>
</blockquote>
<ul>
<li>연관된 엔터티를 즉시 조회한다. 
하이버네이트는 가능하면 SQL 조인을 사용해서 한번에 조인한다. </li>
<li>객체 조회시, 연관된 객체를 즉시 로딩하는 방법. </li>
</ul>
<hr>
<blockquote>
<blockquote>
<p>*<em>지연 로딩 : 연관된 엔터티를 실제로 사용할 때 조회한다. *</em>
<code>@ManyToOne (fetch = FetchType.LAZY)</code></p>
</blockquote>
</blockquote>
<ul>
<li>연관된 엔터티를 프록시로 조회한다. 
프록시를 실제로 사용할 때 초기화하면서 데이터 베이스를 조회한다. </li>
<li>객체 조회시, 연관된 객체를 지연해서 로딩하는 방법.</li>
</ul>
<hr>
<h3 id="📍-2-영속성-전이와-고아-객체-📍">📍 2. 영속성 전이와 고아 객체 📍</h3>
<blockquote>
<p><strong>영속성 전이</strong> <code>CASCADE</code></p>
</blockquote>
<ul>
<li>객체를 저장하거나 삭제할 때, 연관된 객체도 함께 저장하거나 삭제할 수 있는 것. </li>
<li>특정 엔터티를 영속 상태로 만들 때, 
연관된 엔터티도 함께 영속 상태로 만들고 싶은 경우에 사용하는 기능.<blockquote>
<ul>
<li>CASCADE 옵션으로 영속성 전이를 제공한다. 
영속성 전이를 사용하면 부모 엔터티를 저장할 때 자식 엔터티도 함께 저장할 수 있다. </li>
</ul>
</blockquote>
<ul>
<li>JPA 에서 엔터티를 저장할 때 연관된 모든 엔터티는 영속 상태이어야 한다. </li>
</ul>
</li>
</ul>
<hr>
<blockquote>
<p><strong>영속성 전이 - 저장.</strong>
<code>@OneToMany (mappedBy = &quot;parent&quot;, cascade = CascadeType.PERSIST)</code> </p>
</blockquote>
<ul>
<li>부모만 영속화하면 CascadeType.PERSIST 로 설정한 자식 엔터티까지 함께 영속화 해서 저장한다. </li>
</ul>
<hr>
<blockquote>
<p>*<em>영속성 전이 - 삭제 *</em>
<code>@OneToMany (mappedBy = &quot;parent&quot;, cascade = CascadeType.REMOVE)</code> 
cascade 의 타입을 REMOVE 로 설정하고, 부모 엔터티만 삭제하면 자식 엔터티도 함께 삭제된다. </p>
<blockquote>
<p>CASCADE 의 종류 </p>
</blockquote>
</blockquote>
<pre><code class="language-java">public enum CascadeType {
    ALL,     // 모두 적용
    PERSIST, // 영속
    MERGE,   // 병합
    REMOVE,  // 삭제 
    REFRESH, // REFRESH
    DETACH     // DETACH
}</code></pre>
<hr>
<blockquote>
<blockquote>
<blockquote>
<p><strong>고아 객체 -  ORPHAN</strong></p>
</blockquote>
</blockquote>
</blockquote>
<ul>
<li>부모 엔터티가 없는 객체.<br>고아객체 제거 : 부모 엔터티와 연관관계가 끊어진 자식 엔터티를 자동으로 삭제하는 기능,
참조가 제거된 엔터티는 다른 곳에서 참조하지 않는 고아 객체로 보고 삭제하는 기능이다. 
고아객체 제거시에는 <em>*<em>부모 엔터티의 컬렉션에서 자식 엔터티의 참조만 제거하도록 하면 된다. *</em></em>
사용 - <code>@OneToMany(mappedBy = &quot;parent&quot;, orphanRemoval = true</code></li>
<li>고아 객체의 제거 기능은 영속성 컨텍스트를 플러시할때 적용되므로, 플러시 시점에 DELETE SQL 이 실행된다. </li>
<li>부모 엔터티와 연관관계가 끊어진 자식 엔터티를 자동으로 삭제할 때 사용하는 기능. </li>
</ul>
<hr>
]]></description>
        </item>
        <item>
            <title><![CDATA[JPA - 식별 & 비식별 관계]]></title>
            <link>https://velog.io/@cojeong_37/JPA-%EC%8B%9D%EB%B3%84-%EB%B9%84%EC%8B%9D%EB%B3%84-%EA%B4%80%EA%B3%84</link>
            <guid>https://velog.io/@cojeong_37/JPA-%EC%8B%9D%EB%B3%84-%EB%B9%84%EC%8B%9D%EB%B3%84-%EA%B4%80%EA%B3%84</guid>
            <pubDate>Wed, 31 Jul 2024 14:50:12 GMT</pubDate>
            <description><![CDATA[<h3 id="식별--비식별-관계">식별 &amp; 비식별 관계</h3>
<h4 id="데이터베이스-테이블-사이의-관계는-외래-키가-기본-키에-포함되는지의-여부에-따라-식별-관계와-비식별-관계로-구분한다">데이터베이스 테이블 사이의 관계는 외래 키가 기본 키에 포함되는지의 여부에 따라 식별 관계와 비식별 관계로 구분한다.</h4>
<h3 id="📍-1-식별-관계-📍">📍 1. 식별 관계 📍</h3>
<ul>
<li>*<em>부모 테이블의 기본 키를 내려받아서 자식 테이블의 기본 키 + 외래 키로 사용하는 관계 *</em><blockquote>
<p><img src="https://velog.velcdn.com/images/cojeong_37/post/3e144b3c-0ddc-4ac3-ada0-679c85042b9a/image.png" alt="">  -&gt; PARENT 테이블의 <strong>기본 키 PARENT_ID</strong> 를 받아서,</p>
</blockquote>
</li>
<li><em>CHILD 테이블의 기본 키 (PK) + 외래 키 (FK) 로 사용*</em> 한다. </li>
</ul>
<hr>
<h3 id="📍-2-비식별-관계-📍">📍 2. 비식별 관계 📍</h3>
<ul>
<li>*<em>부모 테이블의 기본 키를 받아서 자식 테이블의 외래 키로만 사용하는 관계 *</em></li>
</ul>
<blockquote>
<blockquote>
<p>2-A. *<em>필수적 비식별 관계 *</em>
<img src="https://velog.velcdn.com/images/cojeong_37/post/8a0a8b25-7a6a-477d-b0f6-df9190750e30/image.png" alt=""> </p>
</blockquote>
</blockquote>
<ul>
<li>외래 키에 NULL 을 허용하지 않는다. 연관관계를 필수로 맺어야 한다.  </li>
</ul>
<hr>
<blockquote>
<blockquote>
<p>2-B. *<em>선택적 비식별 관계 *</em>
<img src="https://velog.velcdn.com/images/cojeong_37/post/d00ce0ba-ecab-40f4-87ed-0d230ba0a188/image.png" alt=""></p>
</blockquote>
</blockquote>
<ul>
<li>외래 키에 NULL 을 허용한다. 연관관계를 선택적으로 맺을 수 있다. </li>
</ul>
<hr>
<h3 id="📍-3-복합-키---비식별-관계-매핑-📍">📍 3. 복합 키 - 비식별 관계 매핑 📍</h3>
<blockquote>
<ul>
<li>JPA 에서 식별자를 둘 이상 사용하려면 별도의 식별자 클래스를 만들어야 한다.
JPA 가 복합키를 지원하는 2가지 방법</li>
</ul>
</blockquote>
<ul>
<li>JPA 는 영속성 컨텍스트에 엔터티를 보관할 때 엔터티의 식별자를 키로 사용한다. 그리고 식별자를 구분하기 위해 equals 와 hashCode 를 사용해서 동등성을 비교한다. </li>
</ul>
<ol>
<li><code>@IdClass</code>  : 관계형 데이터베이스에 가까운 방법<pre><code>@IdClass 사용시 만족해야 할 조건
 1. 식별자 클래스의 속성명과 엔터티에서 사용하는 식별자의 속성명은 같아야 한다.
 2. Serializable 인터페이스를 구현해야 한다
 3. equals, hashCode 를 구현해야 한다.
 4. 기본 생성자가 있어야 한다.
 5. 식별자 클래스는 public 이어야 한다.</code></pre></li>
<li><code>@2EmbeddedId</code> : 객체 지향에 가까운 방법
<code>@2EmbeddedId</code> 를 적용한 식별자 클래스는 식별자 클래스에 기본 키를 직접 매핑한다. </li>
</ol>
<hr>
<h3 id="📍-4-식별관계--비식별-관계의-장단점-📍">📍 4. 식별관계 , 비식별 관계의 장단점 📍</h3>
<blockquote>
<p><strong>식별 관계</strong> </p>
</blockquote>
<ul>
<li>부모 테이블의 기본 키를 자식 테이블로 전파하면서 자식 테이블의 기본 키 컬럼이 점점 늘어난다. </li>
<li><blockquote>
<p>조인할때 SQL 이 복잡해지고 기본 키 인덱스가 불필요하게 커질 수 있다.</p>
</blockquote>
</li>
<li>식별 관계는 2개 이상의 컬럼을 합해서 복합 기본 키를 만들어야 하는 경우가 많다.</li>
<li>식별 관계를 사용할 때 기본 키로 비즈니스 의미가 있는 자연 키 컬럼을 조합하는 경우가 많다.</li>
<li>식별 관계의 자연 키 컬럼들이 자식에 손자까지 전파되면 변경하기 힘들다. </li>
<li>식별 관계는 부모 테이블의 기본 키를 자식 테이블의 기본 키로 사용하므로 비식별 관계보다 테이블 구조가 유연하지 못하다. </li>
</ul>
<hr>
<blockquote>
<p>** 비식별 관계**</p>
</blockquote>
<ul>
<li>비식별 관계의 기본 키는 비즈니스와 전혀 관계없는 대리 키를 주로 사용한다. </li>
<li>비식별 관계의 기본 키는 주로 대리 키를 사용하는데 JPA 는 <code>@GenerateValue</code> 처럼 대리 키를 생성하기 위한 편리한 방법을 제공한다. </li>
</ul>
<hr>
]]></description>
        </item>
        <item>
            <title><![CDATA[JPA 연관관계 매핑 - 상속관계 매핑]]></title>
            <link>https://velog.io/@cojeong_37/JPA-%EC%97%B0%EA%B4%80%EA%B4%80%EA%B3%84-%EB%A7%A4%ED%95%91-%EC%A1%B0%EC%9D%B8-%ED%85%8C%EC%9D%B4%EB%B8%94-%EC%A0%84%EB%9E%B5</link>
            <guid>https://velog.io/@cojeong_37/JPA-%EC%97%B0%EA%B4%80%EA%B4%80%EA%B3%84-%EB%A7%A4%ED%95%91-%EC%A1%B0%EC%9D%B8-%ED%85%8C%EC%9D%B4%EB%B8%94-%EC%A0%84%EB%9E%B5</guid>
            <pubDate>Tue, 30 Jul 2024 14:37:45 GMT</pubDate>
            <description><![CDATA[<h3 id="상속관계-매핑---조인-전략">상속관계 매핑 - 조인 전략</h3>
<p>관계형 데이터베이스 에서의 상속은 <code>슈퍼 - 서브 타입 관계</code> 라는 모델링 기법을 사용한다.</p>
<h3 id="📍-1-조인-전략-📍">📍 1. 조인 전략 📍</h3>
<blockquote>
<ul>
<li><em>*<em>엔티티 각각을 모두 테이블로 만들고 자식 테이블이 부모 테이블의 기본 키를 받아서 
기본키 + 외래 키 로 사용하는 전략 *</em></em></li>
</ul>
</blockquote>
<hr>
<blockquote>
<blockquote>
<p><strong>조인 전략 사용시 주의할 *<em>점
    - 객체는 타입으로 구분이 가능하지만, 테이블은 타입의 개념이 없다. 따라서 타입을 구분하는 컬럼을 추가해야 한다. 
    --------------------------------------------------------------------------
*</em>   조인 전략의 장점</strong>
    1. 테이블이 정규화가 된다
    2. 외래 키 참조 무결성 제약 조건을 활용할 수 있다.
    3. 저장공간을 효율적으로 사용한다
    --------------------------------------------------------------------------
**    조인 전략의 단점**
    1. 조회할 때 조인이 많이 사용되므로 성능이 저하될 수도 있다.
    2. 조회 쿼리가 복잡하다
    3. 데이터를 등록할 INSERT SQL 을 두번 실행한다. </p>
</blockquote>
</blockquote>
<hr>
<h3 id="📍-2-단일-테이블-전략-📍">📍 2. 단일 테이블 전략 📍</h3>
<blockquote>
<ul>
<li>테이블을 하나만 사용하고, 구분 컬럼으로 어떤 자식 데이터가 저장되었는지 구분하는 전략. 
<em><strong>조회할때 조인을 사용하지 않는다</strong></em> 는 것이 특징. <blockquote>
<p><strong>단일 테이블 전략 장점</strong></p>
</blockquote>
<ol>
<li>조인이 필요 없으므로 일반적으로 조회 성능이 빠르다</li>
<li><h2 id="조회-쿼리가-단순하다">조회 쿼리가 단순하다 </h2>
<blockquote>
<p>*<em>단일 테이블 전략 단점 *</em></p>
</blockquote>
</li>
<li>자식 엔티티가 매핑한 컬럼은 모두 null 을 허용해야 한다.</li>
<li>단일 테이블에 모든 것을 저장하므로 테이블이 커질 수 있다. </li>
</ol>
  -&gt; 상황에 따라서는 성능이 저하될 수 있음. <pre><code>  --------------------------------------------------------------------------</code></pre><blockquote>
<p><strong>단일 테이블 전략 특징</strong></p>
</blockquote>
<ol>
<li>구분 컬럼을 꼭 사용해야 한다</li>
</ol>
  -&gt; <code>@DiscriminatorColumn</code> 을 꼭 설정해야 한다.<ol start="2">
<li><code>@DiscriminatorValue</code> 를 지정하지 않으면 기본적으로 엔터티 이름을 사용한다. </li>
</ol>
</li>
</ul>
</blockquote>
<p><del>그냥 그렇다고 이거 배웠나 기억이 안나네.. ㅋㅋ</del></p>
]]></description>
        </item>
    </channel>
</rss>