<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>코코코딩 글리버</title>
        <link>https://velog.io/</link>
        <description>제가 한 번 해보겠습니다.</description>
        <lastBuildDate>Tue, 07 May 2024 07:56:48 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>코코코딩 글리버</title>
            <url>https://velog.velcdn.com/images/songmin_tech/profile/50e89b28-c517-4bda-81b6-781c36391b0a/image.jpg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. 코코코딩 글리버. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/songmin_tech" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[리액트 - spring과 연동하여 사용하기 (Post 방식)]]></title>
            <link>https://velog.io/@songmin_tech/%EB%A6%AC%EC%95%A1%ED%8A%B8-spring%EA%B3%BC-%EC%97%B0%EB%8F%99%ED%95%98%EC%97%AC-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0-Post-%EB%B0%A9%EC%8B%9D</link>
            <guid>https://velog.io/@songmin_tech/%EB%A6%AC%EC%95%A1%ED%8A%B8-spring%EA%B3%BC-%EC%97%B0%EB%8F%99%ED%95%98%EC%97%AC-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0-Post-%EB%B0%A9%EC%8B%9D</guid>
            <pubDate>Tue, 07 May 2024 07:56:48 GMT</pubDate>
            <description><![CDATA[<h1 id="post-방식으로-데이터-전송하기">post 방식으로 데이터 전송하기</h1>
<ul>
<li>리액트 에서 spring으로 비동기 (axios) 방식으로 전송 한다.</li>
</ul>
<h2 id="get-post-어노테이션-차이">get? post? 어노테이션 차이</h2>
<ul>
<li>get : @RequestParam</li>
<li>post : @RequestBody</li>
</ul>
<hr>
<br>

<h2 id="spring">spring</h2>
<p>ReactSpringController.java</p>
<ul>
<li><p>하나의 데이터 처리하는 경우</p>
<pre><code class="language-java">@RestController // JSON, XML 등과 같은 데이터 반환 목적
@CrossOrigin(origins = &quot;*&quot;) // 서버 XMLHttpRequest 해결용
@RequestMapping(&quot;/react&quot;)
public class ReactSpringController {

  // http://localhost:8081/react/login

  @PostMapping(&quot;loginpost&quot;)
  public String loginpost(@RequestBody String id, String pw){
      System.out.println(&quot;id : &quot; + id);
      System.out.println(&quot;pw : &quot; + pw);
      return &quot;Test&quot;;
  }

  // 또는 HashMap &lt;String, Object&gt; 이용

</code></pre>
</li>
</ul>
<pre><code>@PostMapping(&quot;loginpost&quot;)
// @RequestBody -&gt; 클라이언트(React)에서 보낸 body에 data를 꺼내겠습니다.
public String loginpost(@RequestBody HashMap&lt;String, Object&gt; data){
    // HashMap&lt;String, Object&gt; -&gt; key, value
    Map&lt;String, Object&gt; map = data;

    System.out.println(&quot;id : &quot; + map.get(&quot;id&quot;));
    System.out.println(&quot;pw : &quot; + map.get(&quot;pw&quot;));
    return &quot;Test&quot;;
}


// 배열형식의 데이터의 경우</code></pre><p> }</p>
<pre><code>
- 다수 list 형태의 데이터를 처리하는 경우
```java
</code></pre><br>

<ul>
<li><h2 id="리액트">리액트</h2>
<ul>
<li>let url의 변수로 rest api 반응할 주소 작성하기
(spring 컨트롤러에서 mapping으로 받아들임)<pre><code class="language-js">import React, { useRef } from &quot;react&quot;;
import axios from &quot;axios&quot;;
import { useNavigate } from &quot;react-router-dom&quot;;
</code></pre>
</li>
</ul>
</li>
</ul>
<p>const Login = () =&gt; {
  const nav = useNavigate();
  const id = useRef();
  const pw = useRef();</p>
<p>  function tryLogin() {
    // 사용자가 적은 ID, PW 값을 가져와서
    // SpringBoot 서버로 전송하겠습니다 ! --&gt; 비동기 통신방식 (axios)
    let inputId = id.current.value;
    let inputPw = pw.current.value;
    let url = &quot;<a href="http://localhost:8081/myweb/react/loginpost&quot;">http://localhost:8081/myweb/react/loginpost&quot;</a>;</p>
<pre><code>// post 방식 통신에 있어서 요청 데이터는 body 영역에 담긴다.
axios
  .post(url, {
    id: inputId,
    pw: inputPw,
  })
  .then((res) =&gt; console.log(res));
  }</code></pre><pre><code>
&lt;br&gt;

- ## spring entity 폴더에 WebToon 이름의 클래스 생성
```java
package org.example.entity;

import lombok.AllArgsConstructor;
import lombok.Data;

@AllArgsConstructor
@Data
public class WebToon {
    String openDay;
    String name;

}
</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[리액트 - spring과 연동하여 사용하기 (Get 방식)
]]></title>
            <link>https://velog.io/@songmin_tech/%EB%A6%AC%EC%95%A1%ED%8A%B8-spring%EA%B3%BC-%EC%97%B0%EB%8F%99%ED%95%98%EC%97%AC-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@songmin_tech/%EB%A6%AC%EC%95%A1%ED%8A%B8-spring%EA%B3%BC-%EC%97%B0%EB%8F%99%ED%95%98%EC%97%AC-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0</guid>
            <pubDate>Wed, 01 May 2024 00:12:54 GMT</pubDate>
            <description><![CDATA[<h1 id="금일-교육-목표">금일 교육 목표</h1>
<ul>
<li>로그인에서 아이디 비번 입력 후 로그인 버튼 클릭</li>
<li>아래 이미지와 같이 데이터 전송 (json)</li>
<li>응답 (res)의 결과로 출력됨</li>
</ul>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/4d72ad36-4aca-4252-b2e0-76aaae3e9768/image.png" alt=""></p>
<h2 id="1-백과-프론트-연동">1. 백과 프론트 연동</h2>
<ul>
<li>json 데이터 주고 받기</li>
</ul>
<h2 id="2-다른-ide-사용">2. 다른 IDE 사용</h2>
<ul>
<li>vscode(리액트) 와 InteliJ(spring boot) 로그인 결과 주고 받기</li>
</ul>
<h2 id="3-rest-api-의-axios-프로젝트-설치">3. Rest API 의 axios 프로젝트 설치</h2>
<blockquote>
<p>npm install axios</p>
</blockquote>
<hr>
<ul>
<li>ReactSpringController.java<pre><code class="language-java">package com.example.springboot.controller;
</code></pre>
</li>
</ul>
<p>import org.springframework.web.bind.annotation.*;</p>
<p>@RestController // JSON, XML 등과 같은 데이터 반환 목적
@CrossOrigin(origins = &quot;*&quot;) // 서버 XMLHttpRequest 해결용
@RequestMapping(&quot;/react&quot;)
public class ReactSpringController {</p>
<pre><code>// http://localhost:8081/react/login
@GetMapping(&quot;login&quot;)</code></pre><p>// @RequestParam --&gt; 쿼이스트링 데이터 출력
    public String login(@RequestParam String id, String pw){
        System.out.println(&quot;접근완료&quot;);</p>
<pre><code>    System.out.println(&quot;ID : &quot;+id);
    System.out.println(&quot;PW : &quot;+pw);

    // smhrd, 456
    String result=&quot;&quot;;
    if(id.equals(&quot;smhrd&quot;) &amp;&amp; pw.equals(&quot;456&quot;)){
        result=&quot;smhrdNick&quot;;

    } else {
        result =&quot;로그인 실패&quot;;
    }
    return  &quot;result&quot;;
}</code></pre><p>}</p>
<pre><code>
- Login.jsx

```js
import React, { useRef } from &quot;react&quot;;
import axios from &quot;axios&quot;;
import { useNavigate } from &quot;react-router-dom&quot;;

const Login = () =&gt; {
  const nav = useNavigate();
  const id = useRef();
  const pw = useRef();

  function tryLogin() {
    // 사용자가 적은 ID, PW 값을 가져와서
    // SpringBoot 서버로 전송하겠습니다 ! --&gt; 비동기 통신방식 (axios)
    let inputId = id.current.value;
    let inputPw = pw.current.value;

    axios
      .get(`http://localhost:8081/react/login?id=${inputId}&amp;pw=${inputPw}`)
      .then((res) =&gt; {
        // 로그인 성공 -&gt; Main
        // 로그인 실패 -&gt; 로그인 실패 알림
        console.log(res);
        if (res.data == &quot;smhrdNick&quot;) {
          window.localStorage.setItem(&quot;nick&quot;, res.data);
          nav(&quot;/&quot;);
        } else {
          alert(&quot;로그인 실패&quot;);
        }
      });

    // 로그인 성공시 Nick 값 -&gt; Main
  }

  return (
    &lt;div&gt;
      {/* 
            submit : 데이터 요청을 보내고 페이지를 새로고침하겠씁니다. (동기)
            React에서는 사용을 지양함
        */}
      &lt;h1&gt;로그인 페이지 입니다&lt;/h1&gt;
      ID : &lt;input ref={id}&gt;&lt;/input&gt;
      &lt;br&gt;&lt;/br&gt;
      PW : &lt;input ref={pw}&gt;&lt;/input&gt;
      &lt;br&gt;&lt;/br&gt;
      &lt;button onClick={tryLogin}&gt;로그인 시도&lt;/button&gt;
    &lt;/div&gt;
  );
};

export default Login;
</code></pre><hr>
<h1 id="에러--network-error-cors-error">에러 : Network Error (CORS error)</h1>
<br>

<ul>
<li>다른 ide 사용시 서로 localhost 주소가 다름으로 언제든 만나볼 수 있는 에러....
(3000 과 8081 로컬 전송시 에러발생)</li>
</ul>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/aaed1fa4-d437-4c63-9931-08d4edc9d999/image.png" alt=""></p>
<br>

<ul>
<li>리액트 환경의 package.json 파일에 해당 내용 추가하기</li>
</ul>
<blockquote>
<p>,&quot;proxy&quot;: &quot;<a href="http://localhost:8081&quot;">http://localhost:8081&quot;</a></p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/7fed0ae1-11a0-4979-a06d-06c10c9e705c/image.png" alt=""></p>
<br>

<ul>
<li>config 클래스 추가하여 해결
<img src="https://velog.velcdn.com/images/songmin_tech/post/b5e68410-fa91-4ccb-aae2-1f858580e3ff/image.png" alt=""></li>
</ul>
<pre><code class="language-java">@Configuration
public class CorsConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping(&quot;/**&quot;)
                .allowedOrigins(&quot;*&quot;)
                .allowedMethods(&quot;GET&quot;, &quot;POST&quot;, &quot;PUT&quot;, &quot;DELETE&quot;)
                .allowedHeaders(&quot;*&quot;);
    }
}</code></pre>
<br>
]]></description>
        </item>
        <item>
            <title><![CDATA[리엑트 (React) - Naver API 연동]]></title>
            <link>https://velog.io/@songmin_tech/React-Naver-API-%EC%97%B0%EB%8F%99</link>
            <guid>https://velog.io/@songmin_tech/React-Naver-API-%EC%97%B0%EB%8F%99</guid>
            <pubDate>Tue, 30 Apr 2024 02:06:39 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/songmin_tech/post/dded4ab3-700b-4304-a586-14decfe649ce/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/9cb5583a-3f5e-4af9-a67a-0430ccb2e781/image.png" alt=""></p>
<hr>
<ul>
<li><p>네이버 api 사용
네이버 &gt; 로그인&gt; 네이버 개발자 센터 &gt; 어플리케이션 &gt; 내 어플리케이션 &gt; 등록하고 &gt; TestReact &gt; 사용api:검색기능 &gt; 환경추가 : WEB설정 &gt; <a href="http://localhost:3000">http://localhost:3000</a> 등록 &gt; 등록된 애플리케이션 id 보관 하기</p>
</li>
<li><p>vscode에 입력하여 설치</p>
<blockquote>
<p>npx create-react-app 07.naver_search_api</p>
</blockquote>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/b3943643-c123-4e9f-948d-8c62d6c8cc31/image.png" alt=""></p>
<ul>
<li>생성 경로 지정 후 axios 연결 (아래 코드입력)</li>
</ul>
<blockquote>
<p>cd ./07.naver_search_ap</p>
</blockquote>
<blockquote>
<p>cd npm i axios    또는    npm install axios</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/deec16a5-4d45-4da1-851c-abc36b04bfc3/image.png" alt=""></p>
<hr>
<ul>
<li>src폴더에 components 폴더 생성 후 Search.jsx 파일 생성</li>
</ul>
<ul>
<li><p>검색 누르기
<img src="https://velog.velcdn.com/images/songmin_tech/post/4b9f4aec-16b6-429a-b994-bcb407b95058/image.png" alt=""></p>
</li>
<li><p>뉴스 탭 눌러서 뉴스관련 정보 가져오기</p>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/c3985b9d-7722-4800-8717-e466b27405f1/image.png" alt=""></p>
<ul>
<li>Search 에 해당 위치 복붙</li>
</ul>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/213c0f31-395b-4b27-abdc-64d73ca31896/image.png" alt=""></p>
<ul>
<li><p>내 애플리케이션에서 정보 확인하기
<img src="https://velog.velcdn.com/images/songmin_tech/post/5446bbdb-9714-408e-ae4c-ff430b63c5d7/image.png" alt=""></p>
</li>
<li><p>해당 위치에 붙여넣기
<img src="https://velog.velcdn.com/images/songmin_tech/post/fdb01f48-96ea-4a28-9ac3-4d5852bdd986/image.png" alt=""></p>
</li>
</ul>
<hr>
<h2 id="네이버-api-최종-코드">네이버 API 최종 코드</h2>
<ul>
<li><p>위 내용 참조하여 작업한 최종 코드</p>
</li>
<li><p>App.js</p>
<pre><code class="language-js">import logo from &quot;./logo.svg&quot;;
import &quot;./App.css&quot;;
import Search from &quot;./components/Search&quot;;
</code></pre>
</li>
</ul>
<p>function App() {
  return (
    <div>
      <h1>NAVER SEARCH API 실습</h1>
      <Search></Search>
    </div>
  );
}</p>
<p>export default App;</p>
<pre><code>
- Search.js
![](https://velog.velcdn.com/images/songmin_tech/post/5d42f18d-7c14-436c-a0e1-6afae953ae5b/image.png)

```js
import React, { useEffect, useState } from &quot;react&quot;;
import axios from &quot;axios&quot;;

const Search = () =&gt; {
  const [data, setData] = useState([]);

  const getSerchDate = async () =&gt; {
    const url = &quot;v1/search/news.json&quot;;
    const options = {
      // 요청헤더 설정
      headers: {
        &quot;X-Naver-Client-Id&quot;: 내 애플리케이션의 Client ID,
        &quot;X-Naver-Client-Secret&quot;: 내 애플리케이션의 Client Secret    ,
      },
      // 파라미터 설정
      params: {
        query: &quot;비트코인&quot;,
      },
    };

    const response = await axios.get(url, options);
    console.log(response.data);

    setData(response.data.items);
  };

  useEffect(() =&gt; {
    getSerchDate();
  }, []);

  return (
    &lt;div&gt;
      {data.map((item, index) =&gt; (
        &lt;div ke={index}&gt;
          &lt;h2&gt;{item.title}&lt;/h2&gt;
          &lt;hr /&gt;
        &lt;/div&gt;
      ))}
    &lt;/div&gt;
  );
};

export default Search;
</code></pre><hr>
<h3 id="데이터-보내기">데이터 보내기</h3>
<ul>
<li>쿼리타입으로 보낼 예정 </li>
</ul>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/f79d3acc-197f-4b81-84e4-7bc183060f47/image.png" alt=""></p>
<hr>
<h2 id="에러발생">에러발생</h2>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/17e8d6db-9f35-4afb-897c-955663306fb0/image.png" alt=""></p>
<ul>
<li>다음 네트워크끼리 정보를 교환할 수 있도록 설정</li>
</ul>
<blockquote>
<p>&quot;proxy&quot;: &quot;<a href="https://openapi.naver.com&quot;">https://openapi.naver.com&quot;</a></p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/3d20b070-37ea-4e1e-a134-9277d02d9866/image.png" alt=""></p>
<hr>
<ul>
<li>서버 재기동</li>
</ul>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/f9a1bbbc-ad10-4fad-b9fc-1c428418c08b/image.png" alt=""></p>
<hr>
<ul>
<li>배열에 넣고 작업하면 해당 기사가 나옴
<img src="https://velog.velcdn.com/images/songmin_tech/post/ed85c460-2e32-4d9c-8fe4-0908911da410/image.png" alt=""></li>
</ul>
<hr>
<h2 id="실습-해보기">실습 해보기</h2>
<ul>
<li>팀별로 각 카테고리 골라서 해보기(각자)</li>
</ul>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/cd0bf676-2416-418c-8380-fe226fc00f9f/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/6becc5a4-bdb9-4fdc-a659-4e4ac02cb1d5/image.png" alt=""></p>
<ul>
<li>index.js<pre><code class="language-js">import React from &quot;react&quot;;
import ReactDOM from &quot;react-dom/client&quot;;
import &quot;./index.css&quot;;
import reportWebVitals from &quot;./reportWebVitals&quot;;
import { BrowserRouter } from &quot;react-router-dom&quot;;
</code></pre>
</li>
</ul>
<p>// 네이버 api 활용
import App from &quot;./DicApp&quot;;</p>
<p>const root = ReactDOM.createRoot(document.getElementById(&quot;root&quot;));
root.render(
  //&lt;React.StrictMode&gt;
  <BrowserRouter>
    <App />
  </BrowserRouter>
  //&lt;/React.StrictMode&gt;
);</p>
<p>// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: <a href="https://bit.ly/CRA-vitals">https://bit.ly/CRA-vitals</a>
reportWebVitals();</p>
<pre><code>
- DicApp.js
```js
import React, { useRef, useState } from &quot;react&quot;;
import { Routes, Route, useNavigate } from &quot;react-router-dom&quot;;
import { KeyWordContext } from &quot;./context/keyWordContext&quot;;
import DicSearch from &quot;./components/DicSearch&quot;;

const DicApp = () =&gt; {
  const keyword = useRef();
  const [keyData, setKeyData] = useState(&quot;&quot;);
  const nav = useNavigate();

  // 입력창 뜨기
  const SearchKeyword = () =&gt; {
    setKeyData(keyword.current.value);
    nav(&quot;/search&quot;);
    console.log(&quot;dic 방문 :&quot;, keyData);
  };

  // 입력시 변화되게
  const handleChange = () =&gt; {
    setKeyData(keyword.current.value);
    console.log(&quot;SearchKeyword 변화 :&quot;, keyData);
  };

  return (
    &lt;div&gt;
      &lt;KeyWordContext.Provider value={{ keyData, setKeyData }}&gt;
        &lt;h1&gt;NAVER SEARCH API&lt;/h1&gt;
        &lt;p&gt;백과 사전&lt;/p&gt;
        &lt;input ref={keyword} type=&quot;text&quot; onChange={handleChange} /&gt;
        &lt;button onClick={SearchKeyword}&gt;검색&lt;/button&gt;

        &lt;Routes&gt;
          &lt;Route path=&quot;/search&quot; element={&lt;DicSearch /&gt;}&gt;&lt;/Route&gt;
        &lt;/Routes&gt;
      &lt;/KeyWordContext.Provider&gt;
    &lt;/div&gt;
  );
};

export default DicApp;
</code></pre><ul>
<li>keyWordContent.js<pre><code class="language-js">import { createContext } from &quot;react&quot;;
</code></pre>
</li>
</ul>
<p>export const KeyWordContext = createContext(&quot;&quot;);</p>
<pre><code>
- DicSearch.jsx
```js
import React, { useEffect, useState, useContext } from &quot;react&quot;;
import axios from &quot;axios&quot;;
import { KeyWordContext } from &quot;../context/keyWordContext&quot;;

const Search = () =&gt; {
  const [data, setData] = useState([]);
  const { keyData, setKeyData } = useContext(KeyWordContext);

  const getSerchDate = async () =&gt; {
    const url = &quot;v1/search/encyc.json&quot;;
    const options = {
      // 요청헤더 설정
      headers: {
        &quot;X-Naver-Client-Id&quot;: Client ID    ,
        &quot;X-Naver-Client-Secret&quot;: Client Secret    ,
      },
      // 파라미터 설정
      params: {
        query: keyData,
      },
    };

    const response = await axios.get(url, options);
    console.log(response.data);

    setData(response.data.items);
  };

  useEffect(() =&gt; {
    getSerchDate();
  }, []);

  useEffect(() =&gt; {
    getSerchDate();
  }, [keyData]);

  return (
    &lt;div&gt;
      {data.map((item, index) =&gt; (
        &lt;div ke={index}&gt;
          &lt;h2&gt;{item.title}&lt;/h2&gt;
          &lt;hr /&gt;
        &lt;/div&gt;
      ))}
    &lt;/div&gt;
  );
};

export default Search;
</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[리엑트 - Context API]]></title>
            <link>https://velog.io/@songmin_tech/%EB%A6%AC%EC%97%91%ED%8A%B8-Context-API</link>
            <guid>https://velog.io/@songmin_tech/%EB%A6%AC%EC%97%91%ED%8A%B8-Context-API</guid>
            <pubDate>Fri, 26 Apr 2024 05:15:31 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/songmin_tech/post/776ee402-413d-4eb6-8207-6ab3e01d7494/image.png" alt=""></p>
<hr>
<h1 id="context">Context</h1>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/211d677c-7fcc-48e4-8353-1ef5b4daaf4f/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/2fdbf4d1-5e1e-48f9-ab65-64012e42ecf5/image.png" alt=""></p>
<h2 id="component">Component</h2>
<ul>
<li>상위에서 하위로 전달</li>
</ul>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/93b47fc8-0241-4343-98d7-397a0185db53/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/d141b0e9-57d0-460d-bcfb-c030c4320edf/image.png" alt=""></p>
<ul>
<li>각 변수들을 사용하려면 최상층에 선언해야 전역변수로 사용할 수 있음 (지역변수로는 모든 곳에 부를 수 없음..)
<img src="https://velog.velcdn.com/images/songmin_tech/post/215702c0-5ab8-4d12-b579-6808b1889d3b/image.png" alt=""></li>
</ul>
<hr>
<h2 id="context-api">Context API</h2>
<ul>
<li>전역 형태로 만들어서 모든 곳에 사용가능하게 함</li>
</ul>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/003e0715-0373-4bdf-bd22-24883d02cccc/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/c9374c1f-eb3c-4cac-a49e-5368cb0b3be2/image.png" alt=""></p>
<ul>
<li>꼭 필요할때만 쓰자!
<img src="https://velog.velcdn.com/images/songmin_tech/post/ba616826-6b79-429a-b0a1-dc6f719bd342/image.png" alt=""></li>
</ul>
<p>Context 파일 생성 (저장소)</p>
<ul>
<li>상위</li>
</ul>
<hr>
<h2 id="component-와-context-api-차이">Component 와 Context API 차이</h2>
<ul>
<li><p>Component
<img src="https://velog.velcdn.com/images/songmin_tech/post/088bc38a-f407-4ab9-b9b7-e029b4124d43/image.png" alt=""></p>
</li>
<li><p>Context API
<img src="https://velog.velcdn.com/images/songmin_tech/post/64957100-0f0d-490d-99b0-7d7d8abfd496/image.png" alt=""></p>
</li>
</ul>
<hr>
<h1 id="context-기초-실습1">Context 기초 실습1</h1>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/25f1b622-a8b9-47f0-ae98-21565c6b60eb/image.png" alt=""></p>
<hr>
<h1 id="context-기초-실습2">Context 기초 실습2</h1>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/15e6d701-84e0-45d1-afb7-986afc13c39e/image.png" alt=""></p>
<ul>
<li>Ex01.js<pre><code class="language-js">import React from &quot;react&quot;;
import ParentComponent from &quot;./components/ParentComponent&quot;;
import { useState } from &quot;react&quot;;
import { InputContext } from &quot;./context/InputContext&quot;;
</code></pre>
</li>
</ul>
<p>const Ex01 = () =&gt; {
  const [content, setContent] = useState(&quot;&quot;);</p>
<p>  console.log(content);</p>
<p>  return (
    <div>
      &lt;InputContext.Provider value={{ content, setContent }}&gt;
        <ParentComponent />
      &lt;/InputContext.Provider&gt;
    </div>
  );
};</p>
<p>export default Ex01;</p>
<pre><code>

- ParentComponent.jsx
```js
import React from &quot;react&quot;;
import ChlidComponent1 from &quot;./ChlidComponent1&quot;;
import { useContext } from &quot;react&quot;;
import { InputContext } from &quot;../context/InputContext&quot;;
import Counter from &quot;./Counter&quot;;

const ParentComponent = () =&gt; {
  console.log(&quot;ParentComponent 방문&quot;);
  const { setContent } = useContext(InputContext);

  return (
    &lt;div&gt;
      &lt;ChlidComponent1 /&gt;
      &lt;input type=&quot;text&quot; onChange={(e) =&gt; setContent(e.target.value)} /&gt;
    &lt;/div&gt;
  );
};

export default ParentComponent;
</code></pre><ul>
<li>ChlidComponent1.jsx<pre><code class="language-js">import React, { memo } from &quot;react&quot;;
import ChlidComponent2 from &quot;./ChlidComponent2&quot;;
</code></pre>
</li>
</ul>
<p>// memo() : 컴포넌트의 랜더링 결과를 저장하고 이후 데이터 변화가 생겼을 떄
//          랜더링 결과를 이전 결과와 비교해서 업데이트
export const ChlidComponent1 = memo(() =&gt; {
  console.log(&quot;ChlidComponent1 랜더링&quot;);
  return (
    <div>
      <ChlidComponent2></ChlidComponent2>
    </div>
  );
});</p>
<p>export default ChlidComponent1;</p>
<pre><code>
- ChlidComponent2.jsx
```js
import React from &quot;react&quot;;
import { useContext } from &quot;react&quot;;
import { InputContext } from &quot;../context/InputContext&quot;;

const ChlidComponent2 = () =&gt; {
  console.log(&quot;ChlidComponent2 랜더링&quot;);
  const { content } = useContext(InputContext);

  return &lt;div&gt;{content}&lt;/div&gt;;
};

export default ChlidComponent2;
</code></pre><ul>
<li>InputContext.js<pre><code class="language-js">import { createContext } from &quot;react&quot;;
</code></pre>
</li>
</ul>
<p>export const InputContext = createContext(&quot;&quot;);</p>
<pre><code>

---

- 컴포넌트 총 4개
![](https://velog.velcdn.com/images/songmin_tech/post/eab4caa9-7648-4ec7-813a-0acc6844e110/image.png)

![](https://velog.velcdn.com/images/songmin_tech/post/2d7361b1-575e-42df-aad7-475e3f21c61e/image.png)

![](https://velog.velcdn.com/images/songmin_tech/post/256b9416-3b70-45ba-a491-a18cbad8ded1/image.png)




![](https://velog.velcdn.com/images/songmin_tech/post/cb9c2995-0923-47fa-be7a-f2bd8685d8b3/image.png)

---

# 라우트

![](https://velog.velcdn.com/images/songmin_tech/post/fac4c8ec-7863-49fd-b208-7c44b7427b9e/image.png)

![](https://velog.velcdn.com/images/songmin_tech/post/dea5f942-b2ce-44af-95bc-d3805a3b7145/image.png)

## 라우트 사용시 초기 세팅 및 주의사항!

- 설치 코드
    - 라우터 사용하는 거라면 꼭 설치하기!
&gt; npm i react-router-dom


- BrowserRouter 태그 감싸주기
![](https://velog.velcdn.com/images/songmin_tech/post/f1cb7767-921f-45a8-84da-42b974c767fb/image.png)

- 라우트 주의사항!
    - &lt;Routes.&gt; 태그 사용시 영역을 분리 해주자 ! 
![](https://velog.velcdn.com/images/songmin_tech/post/b680f2b7-08e7-4b4c-b059-ec3edc6b61cc/image.png)


---

## 라우트 실습1

- App.js
```js
import { Routes, Route, Link } from &quot;react-router-dom&quot;;
import &quot;./App.css&quot;;
import Home from &quot;./component/Home&quot;;
import About from &quot;./component/About&quot;;
import Product from &quot;./component/Product&quot;;

function App() {
  return (
    &lt;div&gt;
      {/* 
        Routes 컴포넌트 : Route에 연결된 컴포넌트 중 
        요청 URL과 일치한 Rote만 랜더링 해주는 컴포넌트

        Route 컴포넌트 : URL을 정의하고 컴포넌트를 매핑해주는 컴포넌트
        path속성 : 매핑할 컴포넌트
        element속성 : 매핑할 컴포넌트
      */}
      &lt;Routes&gt;
        &lt;Route path=&quot;/&quot; element={&lt;Home /&gt;}&gt;&lt;/Route&gt;
        &lt;Route path=&quot;/about&quot; element={&lt;About /&gt;}&gt;&lt;/Route&gt;
        &lt;Route path=&quot;/product&quot; element={&lt;Product /&gt;}&gt;&lt;/Route&gt;

        {/* 
          Product 페이지로 이동할 수 있는 Route 컴포넌트 만들기 
          1. Product 컴포넌트 생성
          2. Route 컴포넌트로 경로 지정 및 컴포넌트 연결
            - 경로 : /product
          3. Home 페이지에서 Product 페이지로 이동할 수 있는 Link 컴포넌트 생성
        */}
      &lt;/Routes&gt;
    &lt;/div&gt;
  );
}

export default App;
</code></pre><ul>
<li>Home.jsx<pre><code class="language-js">import React from &quot;react&quot;;
import { Routes, Route, Link, useNavigate } from &quot;react-router-dom&quot;;
</code></pre>
</li>
</ul>
<p>const Home = () =&gt; {
  // 페이지를 이동할때 사용하는 함수
  // 로직 처리 후에 페이지 이동을 해야할 경우 =&gt; useNavigate
  // 단순히 페이지 이동 -&gt; Link 컴포넌트
  const navigate = useNavigate();</p>
<p>  const goToAbout = () =&gt; {
    navigate(&quot;/about&quot;);
  };</p>
<p>  return (
    <div>
      Home
      <h1>Home</h1>
      <p>Home</p>
      {/* Link 컴포넌트 : 다른 페이지 컴포넌트로 이동할 수 있게 동작하는 컴포넌트
              -&gt; App에 있는 Routes 컴포넌트가 요청경로 확인
              -&gt; 요청 경로에 맞는 Route 컴포넌트를 실행</p>
<pre><code>       to 속성 : 요청할 경로 정의 
    */}
  &lt;Link to={&quot;/product&quot;}&gt;product로 이동&lt;/Link&gt;
  &lt;br&gt;&lt;/br&gt;
  &lt;Link to={&quot;/about&quot;}&gt;about으로 이동&lt;/Link&gt;
  &lt;button onClick={goToAbout}&gt;&lt;/button&gt;
&lt;/div&gt;</code></pre><p>  );
};</p>
<p>export default Home;</p>
<pre><code>
- About.jsx
```js
import React from &quot;react&quot;;
import { Routes, Route, Link } from &quot;react-router-dom&quot;;

const About = () =&gt; {
  return (
    &lt;div&gt;
      About
      &lt;h1&gt;About&lt;/h1&gt;
      &lt;p&gt;About&lt;/p&gt;
      {/* Home 페이지 컴포넌트로 이동하는 Link 컴포넌트 만들어보기 ! */}
      &lt;Link to={&quot;/&quot;}&gt;home으로 이동&lt;/Link&gt;
    &lt;/div&gt;
  );
};

export default About;
</code></pre><ul>
<li>Product.jsx<pre><code class="language-js">import React from &quot;react&quot;;
import { Routes, Route, Link, useNavigate } from &quot;react-router-dom&quot;;
</code></pre>
</li>
</ul>
<p>const Product = () =&gt; {
  return (
    <div>
      Product
      <h1>Product</h1>
      <p>Product</p>
      &lt;Link to={&quot;/&quot;}&gt;home으로 이동</Link>
    </div>
  );
};</p>
<p>export default Product;</p>
<pre><code>
---

## 라우트 실습 2

![](https://velog.velcdn.com/images/songmin_tech/post/e95f3124-af0e-446d-9e30-003eee0931b3/image.png)

---

### 내 방식
- AppMember.js
```js
import React, { useState } from &quot;react&quot;;
import { Routes, Route, Link } from &quot;react-router-dom&quot;;
import &quot;./App.css&quot;;
import Join from &quot;./component/Join&quot;;
import Login from &quot;./component/Login&quot;;
import Main from &quot;./component/Main&quot;;
import { LoginContext } from &quot;./context/LoginContext&quot;;

function AppMember() {
  const [id, setId] = useState(&quot;&quot;);
  const [pw, setPw] = useState(&quot;&quot;);
  const [nick, setNick] = useState(&quot;&quot;);
  return (
    &lt;div&gt;
      &lt;LoginContext.Provider value={{ id, setId, pw, setPw, nick, setNick }}&gt;
        &lt;Routes&gt;
          &lt;Route path=&quot;/&quot; element={&lt;Join /&gt;}&gt;&lt;/Route&gt;
          &lt;Route path=&quot;/login&quot; element={&lt;Login /&gt;}&gt;&lt;/Route&gt;
          &lt;Route path=&quot;/main&quot; element={&lt;Main /&gt;}&gt;&lt;/Route&gt;
        &lt;/Routes&gt;
      &lt;/LoginContext.Provider&gt;
    &lt;/div&gt;
  );
}

export default AppMember;
</code></pre><ul>
<li>LoginContext.js<pre><code class="language-js">import { createContext } from &quot;react&quot;;
</code></pre>
</li>
</ul>
<p>export const LoginContext = createContext(&quot;&quot;);</p>
<pre><code>
- Join.jsx
```js
import React from &quot;react&quot;;
import { useNavigate } from &quot;react-router-dom&quot;;
import { useContext, useRef } from &quot;react&quot;;
import { LoginContext } from &quot;../context/LoginContext&quot;;

const Join = () =&gt; {
  const nav = useNavigate();
  const { id, setId, pw, setPw, nick, setNick } = useContext(LoginContext);

  const putId = useRef();
  const putPw = useRef();
  const putNick = useRef();

  const goToJoin = () =&gt; {
    setId(putId.current.value);
    setPw(putPw.current.value);
    setNick(putNick.current.value);
    nav(&quot;/login&quot;);
  };

  return (
    &lt;div&gt;
      &lt;h1&gt;회원가입 페이지 입니다.&lt;/h1&gt;
      ID:
      &lt;input type=&quot;text&quot; ref={putId} /&gt;
      &lt;br&gt;&lt;/br&gt;
      PW:
      &lt;input type=&quot;text&quot; ref={putPw} /&gt;
      &lt;br&gt;&lt;/br&gt;
      NICK:
      &lt;input type=&quot;text&quot; ref={putNick} /&gt;
      &lt;br&gt;&lt;/br&gt;
      &lt;button onClick={goToJoin}&gt;join&lt;/button&gt;
      &lt;button type=&quot;reset&quot;&gt;초기화&lt;/button&gt;
    &lt;/div&gt;
  );
};

export default Join;
</code></pre><ul>
<li>Login.jsx<pre><code class="language-js">import React from &quot;react&quot;;
import { useNavigate } from &quot;react-router-dom&quot;;
import { useContext, useRef } from &quot;react&quot;;
import { LoginContext } from &quot;../context/LoginContext&quot;;
</code></pre>
</li>
</ul>
<p>const Login = () =&gt; {
  const nav = useNavigate();
  const { id, setId, pw, setPw, nick, setNick } = useContext(LoginContext);</p>
<p>  const inputId = useRef();
  const inputPw = useRef();</p>
<p>  // 확인용
  console.log({ id });
  console.log({ pw });
  console.log({ nick });</p>
<p>  const goToMain = () =&gt; {
    if (inputId.current.value === id &amp;&amp; inputPw.current.value === pw) {
      nav(&quot;/main&quot;);
    } else {
      alert(&quot;비번 아디 틀림!&quot;);
    }
  };</p>
<p>  return (
    <div>
      <h1>Login 페이지</h1>
      ID:
      <input type="text" ref={inputId} />
      <br></br>
      PW:
      <input type="text" ref={inputPw} />
      <br></br>
      <button onClick={goToMain}>join</button>
    </div>
  );
};</p>
<p>export default Login;</p>
<pre><code>
- Main.jsx
```js
import React from &quot;react&quot;;
import { useNavigate } from &quot;react-router-dom&quot;;
import { useContext } from &quot;react&quot;;
import { LoginContext } from &quot;../context/LoginContext&quot;;

const Main = () =&gt; {
  const nav = useNavigate();
  const { id, setId, pw, setPw, nick, setNick } = useContext(LoginContext);
  return (
    &lt;div&gt;
      &lt;h1&gt;Home&lt;/h1&gt;
      {nick}님 환영합니다.
    &lt;/div&gt;
  );
};

export default Main;
</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[리액트 - 라이프 사이클]]></title>
            <link>https://velog.io/@songmin_tech/%EB%A6%AC%EC%95%A1%ED%8A%B8-%EB%9D%BC%EC%9D%B4%ED%94%84-%EC%82%AC%EC%9D%B4%ED%81%B4</link>
            <guid>https://velog.io/@songmin_tech/%EB%A6%AC%EC%95%A1%ED%8A%B8-%EB%9D%BC%EC%9D%B4%ED%94%84-%EC%82%AC%EC%9D%B4%ED%81%B4</guid>
            <pubDate>Thu, 25 Apr 2024 05:13:05 GMT</pubDate>
            <description><![CDATA[<h1 id="학습-목표">학습 목표</h1>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/8ce5ffea-a5f3-4180-af8d-f03ecbb7f6d9/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/c55ebd8f-c01a-4456-8e96-666debe422e8/image.png" alt=""></p>
<hr>
<h1 id="life-cycle-라이프-사이클">Life Cycle (라이프 사이클)</h1>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/1e1ada8b-dd76-4803-9653-6204566004a1/image.png" alt=""></p>
<br>

<h2 id="라이프-사이클의-전체-흐름">라이프 사이클의 전체 흐름</h2>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/c3ecf8f5-7bfe-4675-92af-acc818cbceb2/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/5ac0e5e5-28fb-4c72-9e4c-46c524cfc865/image.png" alt=""></p>
<br>

<h3 id="라이프-사이클의-상세-흐름">라이프 사이클의 상세 흐름</h3>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/573b5182-d350-4cd6-9db6-0183d76846a4/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/cda0f5b4-143d-43e9-a08d-67b29e6e4fe1/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/c61da0ef-0c02-4058-aded-79ad1c2ba581/image.png" alt=""></p>
<h3 id="라이프-사이클-주의점">라이프 사이클 주의점</h3>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/24655b1c-7470-4e39-8107-72534e61765f/image.png" alt=""></p>
<h3 id="그럼으로-useeffect-사용함">그럼으로 useEffect() 사용함</h3>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/05091773-e2b8-4651-b7f3-fa4bc23494a9/image.png" alt=""></p>
<hr>
<h1 id="직접-해보기">직접 해보기</h1>
<ul>
<li><p>터미널에 다음과 같이 입력하여 리액트 환경을 생성해준다.</p>
<blockquote>
<p>npx create-react-app 04.lifecycle</p>
</blockquote>
</li>
<li><p>이렇게 된거라면 완료</p>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/99774134-645d-436a-8a5d-a8394524dfe2/image.png" alt=""></p>
<hr>
<hr>
<pre><code class="language-js">import &quot;./App.css&quot;;
import { useEffect, useState, useRef } from &quot;react&quot;;

/* 
  useEffect()
  : 리액트 컴포넌트가 랜더링될 때마다 특정 시점에 
  작업을 처리해주는 리액트 훅 함수

  [특정시점 - LifeCycle]
  1. Mount : 컴포넌트가 화면에 나타나는 시점 
      ex) 최초 1회 호출, 초기화 로직 or API호출
  2. Update : 컴포넌트 내 데이터가 업데이트되는 시점
      ex) props, state에 대한 변화 발생
  3. UnMount : 컴포넌트가 종료되는 시점
      ex) 자원해제, state 초기화 등

  [useEffect() 구조]
  1. useEffect( () =&gt; { 실행할 로직 } )
    : 랜더링될 때마다 호출
  2. useEffect( () =&gt; { 실행할 로직 }, [state] )
    : []안에 정의한 state를 감시하고 변화가 발생하면 실행
  3. useEffect( () =&gt; { 실행할 로직 }, [] )
    : 랜더링시 최초 1회 실행

*/
function App() {
  const [count, setCount] = useState(0);
  const [val, setVal] = useState(&quot;&quot;);
  const inputRef = useRef();

  const handleClick = () =&gt; {
    setCount(count + 1);
  };

  const handleChange = () =&gt; {
    setVal(inputRef.current.value);
  };

  // state가 변하면 컴포넌트가 리렌더링되서 아래 콘솔이 실행 된다.
  // 원하는 특정 시점에 로직처리하기에는 적합하지 않기 때문에
  // useEffect()로 처리해야 한다.

  // 랜더링 될때마다 실행
  useEffect(() =&gt; {
    console.log(&quot;컴포넌트 랜더링!&quot;);
  });

  // 처음 마운트 되었을때 한 번만 실행
  useEffect(() =&gt; {
    console.log(&quot;마운트!&quot;);
  }, []);

  // &#39;count&#39; state가 변경될때마다 실행
  useEffect(() =&gt; {
    console.log(&quot;count update!&quot;);
  }, [count]);

  // &#39;val&#39; state가 변경될때마다 실행
  useEffect(() =&gt; {
    console.log(&quot;val update!&quot;);
  }, [val]);

  // 하나 이상의 state가 변경될때마다 실행
  useEffect(() =&gt; {
    console.log(&quot;count : &quot;, count);
    console.log(&quot;val : &quot;, val);
  }, [count, val]);

  return (
    &lt;div&gt;
      &lt;h1&gt;useEffect&lt;/h1&gt;
      &lt;p&gt;Count 변화 : {count}&lt;/p&gt;
      &lt;button onClick={handleClick}&gt;클릭&lt;/button&gt;

      &lt;div&gt;
        &lt;input type=&quot;text&quot; ref={inputRef} onChange={handleChange} /&gt;
        &lt;p&gt;{val}&lt;/p&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  );
}

export default App;
</code></pre>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/5832b696-9db4-45b7-a8cb-744e7cbb1592/image.png" alt=""></p>
<hr>
<h1 id="실습-참참참-게임-만들기">실습 참참참 게임 만들기!</h1>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/f3662737-53e9-4c2e-84a4-46cd3788330d/image.png" alt=""></p>
<ul>
<li>실습) 참참참 게임<ul>
<li>Rule</li>
</ul>
<ol>
<li>유저는 공격, 컴퓨터는 수비를 담당함</li>
<li>유저가 &#39;좌&#39;, &#39;정면&#39;, &#39;우&#39; 버튼을 클릭했을때, 
 유저와 컴퓨터의 선택이 같다면 유저의 승리!</li>
<li>방향이 다르면 컴퓨터 승리</li>
</ol>
</li>
</ul>
<br>

<ul>
<li>제작시 반영사항<ul>
<li>유저와 컴퓨터의 선택, 게임 결과에 대한 state 생성</li>
<li>유저가 &#39;좌&#39;, &#39;정면&#39;, &#39;우&#39; 중에 하나를 클릭 -&gt; 유저의 state에 업데이트</li>
<li>컴퓨터는 3가지의 방향을 랜덤으로 생성- &gt; 컴퓨터의 state에 업데이트</li>
<li>유저가 선택한 방향의 값으로 state가 변경되면 승패를 판단 -&gt; 결과를 state에 업데이트</li>
<li>게임결과를 화면에 출력</li>
</ul>
</li>
</ul>
<pre><code class="language-js">const Ex01 = () =&gt; {
  let data = [&quot;좌&quot;, &quot;정면&quot;, &quot;우&quot;];
  const [user, setUser] = useState(&quot;&quot;);
  const [com, setCom] = useState(&quot;&quot;);
  const [result, setResult] = useState(&quot;&quot;);
  const handleClick = (e) =&gt; {
    console.log(e.target.innerText);
    setUser(e.target.innerText);
    let pos = Math.floor(Math.random() * 3);
    setCom(data[pos]);
  };
  useEffect(() =&gt; {
    if (user === com) {
      setResult(&quot;유저의 승리!&quot;);
    } else {
      setResult(&quot;컴퓨터의 승리!&quot;);
    }
  }, [user, com]);
  return (
    &lt;div&gt;
      &lt;h1&gt;참참참 게임&lt;/h1&gt;
      &lt;h3&gt;나의 선택: {user}&lt;/h3&gt;
      &lt;h3&gt;컴퓨터의 선택: {com}&lt;/h3&gt;
      {user &amp;&amp; &lt;h3&gt;게임 결과: {result}&lt;/h3&gt;}
      {data.map((item, index) =&gt; (
        &lt;button key={index} onClick={handleClick}&gt;
          {item}
        &lt;/button&gt;
      ))}
    &lt;/div&gt;
  );
};
export default Ex01;</code></pre>
<hr>
<h1 id="리액트-공동-api-활용">리액트 공동 api 활용</h1>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/ef199e38-b46c-433d-92bf-8cdf46c61ee5/image.png" alt=""></p>
<p><a href="https://developer.mozilla.org/ko/docs/Web/API/Fetch_API/Using_Fetch">https://developer.mozilla.org/ko/docs/Web/API/Fetch_API/Using_Fetch</a></p>
<p><a href="https://kobis.or.kr/kobisopenapi/webservice/rest/boxoffice/searchDailyBoxOfficeList.json?key=f5eef3421c602c6cb7ea224104795888&amp;targetDt=20240424">https://kobis.or.kr/kobisopenapi/webservice/rest/boxoffice/searchDailyBoxOfficeList.json?key=f5eef3421c602c6cb7ea224104795888&amp;targetDt=20240424</a></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/45271299-2979-423c-aa1c-10df33c05db6/image.png" alt=""></p>
<ul>
<li>axios 설치하기<ul>
<li>터미널 구동끄기</li>
<li>다음과 같이 입력<blockquote>
<p>npm install axios</p>
</blockquote>
</li>
</ul>
</li>
</ul>
<hr>
<h2 id="env">ENV</h2>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/352f08ac-1b45-4748-b149-5efd10fbe7f1/image.png" alt=""></p>
<ul>
<li>노출되면 안되는 정보들을 사용할때 쓸 수 있다.</li>
</ul>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/47cb2fe6-138b-4fc4-b949-f2657d72545a/image.png" alt=""></p>
<ul>
<li><p>폴더 아래 경로로 .env 파일 생성</p>
</li>
<li><p>gitignore 파일 다음과 같이 설정
<img src="https://velog.velcdn.com/images/songmin_tech/post/da19be07-b4d7-4fbe-bf8a-0d2c7e9127e8/image.png" alt=""></p>
</li>
<li><p>.env 설정</p>
<blockquote>
<p>REACT_APP_MOVIE_API_KEY = &quot;f5eef3421c602c6cb7ea224104795888&quot;
<img src="https://velog.velcdn.com/images/songmin_tech/post/b4e58112-3e74-4ed3-8981-1bdbee5d93ea/image.png" alt=""></p>
</blockquote>
</li>
<li><p>.env
서버 중단 &gt; 재실행 &gt; 완료</p>
</li>
</ul>
<hr>
<h1 id="실습-axios-사용하기">실습 axios 사용하기</h1>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/cd371a03-4318-4d2a-a90b-309b2521e1c5/image.png" alt=""></p>
<ul>
<li>날씨 데이터 받아올 수 있는 홈페이지
<a href="https://openweathermap.org/">https://openweathermap.org/</a>
api &gt; api doc &gt; 로그인 &gt; 해당 버튼 클릭
<img src="https://velog.velcdn.com/images/songmin_tech/post/746f0e55-d18c-4f2c-b8f9-411e322d8ea1/image.png" alt=""></li>
</ul>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/e14fdf36-1546-41db-adb6-564f78cdebed/image.png" alt=""></p>
<pre><code class="language-js">import React, { useEffect, useState } from &quot;react&quot;;
import &quot;bootstrap/dist/css/bootstrap.min.css&quot;;
import { Button, Card } from &quot;react-bootstrap&quot;;
import axios from &quot;axios&quot;;

let myKey = &quot;152a46ac954e10f647076cc090f9dac0&quot;;

const Weather = () =&gt; {
  // 각각의 도시 버튼을 클릭했을때
  // https://api.openweathermap.org/data/2.5/weather?q=${city}&amp;appid=${myKey}
  // &amp;units=metric&amp;lang=kr
  // 통해서 도시의 날씨 정보를 가져와 주세요 !!
  // -&gt; axios를 이용 !

  const [cityData, setCityData] = useState(&quot;Gwangju&quot;); // 도시
  const [temData, setTemData] = useState(0); // 온도
  const [stateData, setStateData] = useState(0); // 날씨상태

  //useEffect : 맨처음(랜더링 되었을때 -&gt; 사용자에게 보여줬을때), state가 바꿨을때(재랜더링)
  useEffect(() =&gt; {
    // Promise : 비동기 통신 정보를 가지고 있는 객체
    // 바로 데이터를 사용할 수 없다!!
    // -&gt; 데이터 파싱(데이터를 전부 받아온뒤 -&gt; 후속처리)
    let data = axios.get(
      `https://api.openweathermap.org/data/2.5/weather?q=${cityData}&amp;appid=${myKey}&amp;units=metric&amp;lang=kr`
    );
    data.then((res) =&gt; {
      setCityData(res.data.name);
      setTemData(res.data.main.temp);
      setStateData(res.data.weather[0].description);
      console.log(res);
    });
  }, [cityData]);

  return (
    &lt;div&gt;
      &lt;Card style={{ width: &quot;18rem&quot; }}&gt;
        &lt;Card.Body&gt;
          &lt;Card.Title&gt;도시 : &quot;{cityData}&quot;&lt;/Card.Title&gt;
          &lt;Card.Subtitle&gt;온도 : &quot;{temData}&quot;&lt;/Card.Subtitle&gt;
          &lt;Card.Subtitle&gt;날씨상태 : &quot;{stateData}&quot;&lt;/Card.Subtitle&gt;
        &lt;/Card.Body&gt;
      &lt;/Card&gt;

      &lt;Button variant=&quot;danger&quot; onClick={() =&gt; setCityData(&quot;Gwangju&quot;)}&gt;
        광주
      &lt;/Button&gt;
      &lt;Button variant=&quot;warning&quot; onClick={() =&gt; setCityData(&quot;Seoul&quot;)}&gt;
        서울
      &lt;/Button&gt;
      &lt;Button variant=&quot;success&quot; onClick={() =&gt; setCityData(&quot;London&quot;)}&gt;
        런던
      &lt;/Button&gt;
      &lt;Button onClick={() =&gt; setCityData(&quot;Washington&quot;)}&gt;워싱턴&lt;/Button&gt;
    &lt;/div&gt;
  );
};

export default Weather;
</code></pre>
<hr>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/2d53abb3-a487-45b7-baa2-62ba6d350ba7/image.png" alt=""></p>
<p>04 디테일파일 참조</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[리액트 - 컴포넌트( Map, Filter )]]></title>
            <link>https://velog.io/@songmin_tech/%EB%A6%AC%EC%95%A1%ED%8A%B8-%EC%BB%B4%ED%8F%AC%EB%84%8C%ED%8A%B8</link>
            <guid>https://velog.io/@songmin_tech/%EB%A6%AC%EC%95%A1%ED%8A%B8-%EC%BB%B4%ED%8F%AC%EB%84%8C%ED%8A%B8</guid>
            <pubDate>Wed, 24 Apr 2024 05:15:41 GMT</pubDate>
            <description><![CDATA[<h1 id="map-for문">Map (for문)</h1>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/cdf93c11-02bd-4bdf-ac1f-bbb93ff0b9c7/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/268c4a89-8d5c-46ad-9ff9-f9b2dcff4004/image.png" alt=""></p>
<ul>
<li><p>배열 정보가 item에 담겨 진다. 
(여기서 index는 아무거나 적어도 된다.)
<img src="https://velog.velcdn.com/images/songmin_tech/post/223d8be6-5bd2-4eca-9459-1b4ca7061246/image.png" alt=""></p>
</li>
<li><p>바로 실행하면 에러나기 때문에 key 속성을 추가함
<img src="https://velog.velcdn.com/images/songmin_tech/post/b84dc32b-91ff-4875-a6dd-f773a45a0918/image.png" alt=""></p>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/cf336566-fd37-4935-b9c7-e96fd66a1aba/image.png" alt=""></p>
<hr>
<h1 id="filter-select절-where">Filter (select절 where)</h1>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/717ffcf6-61d6-41c1-af45-95db94fe0dcd/image.png" alt=""></p>
<pre><code class="language-js">import &quot;./App.css&quot;;

function App() {
  let arr = [1, 2, 3, 4, 5];
  let copyArr = arr.map((item) =&gt; {
    return item + 1;
  });

  let copyArr2 = arr.map((item, index) =&gt; (
    &lt;button key={index} onClick={() =&gt; SharedWorker()}&gt;
      {item}번
    &lt;/button&gt;
  ));

  const show = () =&gt; {
    console.log(&quot;클릭이벤트 발생!&quot;);
  };

  console.log(&quot;원본 배열 : &quot;, arr);
  console.log(&quot;복사된 배열 : &quot;, copyArr);

  let objArr = [
    { name: &quot;임경남&quot;, agr: &quot;25&quot;, job: &quot;Front-end&quot; },
    { name: &quot;임승환&quot;, agr: &quot;25&quot;, job: &quot;Back-end&quot; },
    { name: &quot;임명진&quot;, agr: &quot;27&quot;, job: &quot;Date Modeling&quot; },
  ];

  let copyObjArr = objArr.map((item) =&gt; {
    return { name: item.name, job: item.job };
  });

  return (
    &lt;div&gt;
      {/* 객체 혹은 객체 배열을 표현식으로 출력할 수 없음 */}
      &lt;div&gt;{copyArr[0].name}&lt;/div&gt;

      {/* return문 안에 map() 사용할때
      () =&gt; {} (틀린방법)
      () =&gt; () (옮은 방법) 
      */}
      {copyObjArr.map((item, index) =&gt; (
        &lt;div&gt;
          &lt;h3 key={index}&gt;
            {item.name}/{item.job}
          &lt;/h3&gt;
        &lt;/div&gt;
      ))}
      {/* 
        copyArr의 모든 요소를 웹 페이지에 출력해보기
        * &lt;p&gt; 태그 안에 요소를 넣어서 출력되도록
      */}

      {copyArr.map((item) =&gt; (
        &lt;p&gt;{item}&lt;/p&gt;
      ))}

      {copyArr2}
    &lt;/div&gt;
  );
}

export default App;
</code></pre>
<hr>
<h1 id="실습-해보기">실습 해보기</h1>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/65208a71-1671-45ad-8353-0fe45ced3dd9/image.png" alt=""></p>
<pre><code class="language-js">import React, { useState, useRef, useEffect } from &quot;react&quot;;
// useEffect : 랜더링 시점에 맞춰서 실행하는 기능

const ToDoList = () =&gt; {
  const [array, setArray] = useState([]);
  const inp = useRef();

  // 랜더링 시점에 맞춰서 특정 로직을 실행하겠습니다.
  useEffect(() =&gt; {
    console.log(&quot;useEffect&quot;);

    if (array.length === 3) {
      alert(&quot;모두 입력하셨습니다.&quot;);
    }
  }, [array]);
  // dependence Array
  // [array] -&gt; 맨 처음 과 arry 라는 state 값이 바뀌었을때만 실행하겠습니다.

  function putsh() {
    // concat : 데이터를 추가 새로운 배열 생성하는 기능
    // setArray : 클로저 함수 (함수 제일 마지막에 실행됨)
    setArray(array.concat(inp.current.value));
  }

  function del(num) {
    // 배열에서 조건에 부합하는 요소들만 뽑아서 새로운 배열을 만든다.
    setArray(array.filter((item, index) =&gt; index !== num));
    console.log(num);
  }

  return (
    &lt;div&gt;
      &lt;h1&gt;2024 올해는 꼭 해봅시다!!&lt;/h1&gt;
      &lt;input ref={inp}&gt;&lt;/input&gt;
      &lt;button onClick={putsh}&gt;계획추가&lt;/button&gt;
      &lt;h1&gt;ToDoList&lt;/h1&gt;
      &lt;ul&gt;
        {array.map((item, index) =&gt; (
          &lt;li key={index}&gt;
            {item}
            &lt;button key={index} onClick={() =&gt; del(index)}&gt;
              삭제
            &lt;/button&gt;
          &lt;/li&gt;
        ))}
      &lt;/ul&gt;
    &lt;/div&gt;
  );
};

export default ToDoList;
</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[리엑트 - Hooks(스테이트 변수)]]></title>
            <link>https://velog.io/@songmin_tech/%EB%A6%AC%EC%97%91%ED%8A%B8-Hooks%EC%8A%A4%ED%85%8C%EC%9D%B4%ED%8A%B8-%EB%B3%80%EC%88%98</link>
            <guid>https://velog.io/@songmin_tech/%EB%A6%AC%EC%97%91%ED%8A%B8-Hooks%EC%8A%A4%ED%85%8C%EC%9D%B4%ED%8A%B8-%EB%B3%80%EC%88%98</guid>
            <pubDate>Tue, 23 Apr 2024 09:06:15 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/songmin_tech/post/c8ce698f-b5ab-40d8-94e8-a8bdbece4ede/image.jpg" alt=""></p>
<ul>
<li>불러오기 방법<blockquote>
<p>import React, { useState } from &quot;react&quot;;</p>
</blockquote>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/e2dc0eca-d1f0-45b9-80dc-8f35ab2233a9/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/90c93181-9bb9-4792-8970-89c5ca971496/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/3c2cc46a-e19a-419a-bcd2-2622a8a5714f/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/cf7de70e-d53b-4b8b-b375-4b0fbf097f0b/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/67d5a70c-793d-4cd0-864b-3480c495c9b2/image.png" alt=""></p>
<h1 id="usestate">useState</h1>
<h2 id="스테이트-변수-와-일반-변수">스테이트 변수 와 일반 변수</h2>
<ul>
<li><p>리엑트는 변경되는 값 화면과 변경되는 값을 유동적으로 보여지는화면이 분리되어 있음.</p>
</li>
<li><p>일반 변수(값변화가 실시간 안보임)</p>
</li>
<li><p>스테이트 변수(변경된 값이 실시간으로 보임)</p>
</li>
</ul>
<br>

<h2 id="스테이트-변수-사용해보기">스테이트 변수 사용해보기</h2>
<ul>
<li>{ useState } 기능을 import 해주기</li>
</ul>
<blockquote>
<p>const [number, setNumber] = useState(0);</p>
</blockquote>
<p>number : 실제 값을 가지고 있는 변수(state값)
setNumber : state값을 바꿀 수 있는 기능</p>
<br>

<pre><code class="language-js">import React, { useState } from &quot;react&quot;;

const Ex01 = () =&gt; {
  // 특별한 변수를 만드는 방법
  // -&gt; 값이 변경될때 마다 화면에 적용되어질 변수를 만드는 방법
  // number : 실제 값을 가지고 있는 변수(state값)
  // setNumber : state값을 바꿀 수 있는 기능
  const [number, setNumber] = useState(0);

  let num = 0;

  function plus() {
    num++;
    console.log(num);

    setNumber(number + 1);
  }

  return (
    &lt;div&gt;
      &lt;div&gt;{number}&lt;/div&gt;
      &lt;button onClick={plus}&gt;PLUS&lt;/button&gt;
    &lt;/div&gt;
  );
};

export default Ex01;
</code></pre>
<br>

<h2 id="es6-문법의-문제">es6 문법의 문제</h2>
<ul>
<li><p>해당 코드에 원클릭 변수 호출시 ( ) =&gt; 가 없으면 무한 반복으로 함수가 호출 된다.</p>
</li>
<li><p>( ) =&gt; 는 에로펑션 이라 불린다.</p>
</li>
<li><p>주의 ! state 값이 바뀌어지면 -&gt; 컴포넌트가 재랜더링(재실행) 된다!</p>
</li>
</ul>
<pre><code class="language-js">import React, { useState } from &quot;react&quot;;

let num1 = Number(prompt(&quot;첫번째 숫자 입력&quot;));
let num2 = Number(prompt(&quot;두번째 숫자 입력&quot;));

const Ex02 = () =&gt; {
  // result : state 값을 가지는 변수
  // setResult : state 변수를 바꿀 수 있는 함수
  // 주의 ! state 값이 바뀌어지면 -&gt; 컴포넌트가 재랜더링(재실행) 된다!
  const [number, setNumber] = useState(0);

  function result(string) {
    if (string === &quot;+&quot;) {
      setNumber(num1 + num2);
    } else if (string === &quot;-&quot;) {
      setNumber(num1 - num2);
    } else if (string === &quot;*&quot;) {
      setNumber(num1 * num2);
    } else if (string === &quot;/&quot;) {
      setNumber(num1 / num2);
    }
  }

  return (
    &lt;div&gt;
      &lt;button onClick={() =&gt; result(&quot;+&quot;)}&gt;+&lt;/button&gt;
      &lt;button onClick={() =&gt; result(&quot;-&quot;)}&gt;-&lt;/button&gt;
      &lt;button onClick={() =&gt; result(&quot;*&quot;)}&gt;*&lt;/button&gt;
      &lt;button onClick={() =&gt; result(&quot;/&quot;)}&gt;/&lt;/button&gt;
      &lt;p&gt;{number}&lt;/p&gt;
    &lt;/div&gt;
  );
};

export default Ex02;
</code></pre>
<hr>
<h1 id="useref">useRef</h1>
<ul>
<li>React에서 태그를 가져올때 document를 통한 태그 선택은 절대 권장하지 않음</li>
</ul>
<h3 id="사용방법">사용방법</h3>
<ul>
<li>useRef : 태그를 참조할 수 있는 React Hook<blockquote>
<p>import React, { useRef } from &quot;react&quot;;</p>
</blockquote>
</li>
</ul>
<hr>
<h2 id="입력하는-값에-따라-화면-출력-해보기">입력하는 값에 따라 화면 출력 해보기</h2>
<pre><code class="language-js">import React, { useRef, useState } from &quot;react&quot;;
// React Hook 사용법 1. 사용하고자 하는 hook을 import 해줘야 한다.

const Ex03 = () =&gt; {
  // React Hook 사용법 2. 기능을 컴포넌트 안에 있는 변수에 담아주기
  const input = useRef();

  // input 태그에 적은 값을 가져와서 반양시킬 state
  const [inputText, setInputText] = useState(&quot;&quot;);

  return (
    &lt;div&gt;
      &lt;h1&gt;Input태그 다루기&lt;/h1&gt;

      {/* 
        &lt;input ref={input}&gt;&lt;/input&gt;
        -&gt; input 변수를 통해서 input 태그에 매칭 시켜주겠다.
    */}
      &lt;input
        ref={input}
        onChange={() =&gt; setInputText(input.current.value)}
      &gt;&lt;/input&gt;
      {/* 
        input.current == document.querySelector(&#39;input&#39;)
      */}
      &lt;h1&gt;{inputText}&lt;/h1&gt;
    &lt;/div&gt;
  );
};

export default Ex03;
</code></pre>
<ul>
<li>입력한데로 값이 들어 간다.</li>
</ul>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/800cd0a1-7f0b-414b-9a0f-8bdea5699bd5/image.png" alt=""></p>
<hr>
<h2 id="태그를-참조하는-기능">태그를 참조하는 기능</h2>
<ul>
<li>input 태그에 값을 참조한다.</li>
</ul>
<blockquote>
<p>&lt;input ref={num1} ./&gt;</p>
</blockquote>
<ul>
<li>num1 이라는 변수에 input 태그가(값 속성 모두) 들어간다.</li>
</ul>
<blockquote>
<p>const num1 = useRef();</p>
</blockquote>
<ul>
<li>nm1 변수에 input에 담긴 값을 정수형으로 형변환 한다.</li>
</ul>
<blockquote>
<p>let nm1 = parseInt(num1.current.value);</p>
</blockquote>
<hr>
<h1 id="리액트-부트-스크랩">리액트 부트 스크랩</h1>
<ul>
<li><p>주소창에 리액트 부트 스크랩 검색 &gt; get stated</p>
</li>
<li><p>해당 내용 복사 &gt; 터미널 종료 이후 입력 &gt; 설치됨!
<img src="https://velog.velcdn.com/images/songmin_tech/post/acd2f82f-dec8-4c4c-b866-e3bdd93dde24/image.jpg" alt=""></p>
</li>
</ul>
<blockquote>
<p>npm install react-bootstrap bootstrap </p>
</blockquote>
<ul>
<li><p>설치완료됬는지 확인 방법
<img src="https://velog.velcdn.com/images/songmin_tech/post/7c1c610d-aaa6-4035-92da-7ae11c5cf8d3/image.jpg" alt="">
<img src="https://velog.velcdn.com/images/songmin_tech/post/36c99bff-733f-4c5d-b857-9989b8dc8b1b/image.jpg" alt=""></p>
</li>
<li><p>리액트 부트 스크랩을 사용할때는 css 를 import 해줘야함</p>
</li>
<li><p>그외 필요한 샘플은 해당 위치에서 맞춰 찾아 볼 수 있다.</p>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/2668ee42-d205-4939-8bca-d13986a8f6ca/image.png" alt=""></p>
<ul>
<li>예로 버튼 종류</li>
</ul>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/67b9527b-eca1-4d31-931b-8f2e35475654/image.png" alt=""></p>
<hr>
<h2 id="실습-주사위-굴리기">실습 주사위 굴리기</h2>
<ul>
<li>해당 구조로 만들 예정</li>
</ul>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/ea38a04c-6be1-4f21-b3bd-5d7e84342c1e/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/8a1dbf44-aa54-4c51-b71f-71d5acd16b96/image.png" alt=""></p>
<ul>
<li><p>폴더에 해당 파일 만들어주기
<img src="https://velog.velcdn.com/images/songmin_tech/post/c719a5e6-5f25-4217-b4e7-6048406d6a41/image.png" alt=""></p>
</li>
<li><p>index.js에서 연결하여 호출 &gt; npm start
<img src="https://velog.velcdn.com/images/songmin_tech/post/14d66b92-ea5b-44f9-833f-a6d57a865b4f/image.png" alt=""></p>
</li>
<li><p>DiceApp.jsx</p>
<pre><code>import &quot;bootstrap/dist/css/bootstrap.min.css&quot;;
import React, { useState } from &quot;react&quot;;
import ButtonArea from &quot;./ButtonArea&quot;;
import BoardArea from &quot;./BoardArea&quot;;
import &quot;./dice.css&quot;;
</code></pre></li>
</ul>
<p>const DiceApp = () =&gt; {
  // 나와 컴퓨터에 대한 정보를 가진 state 생성(값 형태 : 객체)
  const [user, setUser] = useState({
    name: &quot;나&quot;,
    diceNum: &quot;1&quot;,
    score: &quot;0&quot;,
    imgPath: &quot;./img/dice1.png&quot;,
  });</p>
<p>  const [com, setCom] = useState({
    name: &quot;컴퓨터&quot;,
    diceNum: &quot;1&quot;,
    score: &quot;0&quot;,
    imgPath: &quot;./img/dice1.png&quot;,
  });</p>
<p>  const throwDice = () =&gt; {
    console.log(&quot;주사위 던지기!&quot;);</p>
<pre><code>// 랜덤 숫자 생성 -&gt; 숫자 비교, 이미지 값 적용
// Math.random() : 실수를 생성하는 함수
// Math.floor() : 소수점을 버림
let userDiceNum = Math.floor(Math.random() * 6) + 1;
let comDiceNum = Math.floor(Math.random() * 6) + 1;
let userScore = parseInt(user.score);
let comScore = parseInt(com.score);

// 두 주사위 눈 비교
// 1) 동일한 숫자일 때 -&gt; 무승부 출력 카운트 필요없음
// 2) 나의 숫자가 클 때 -&gt; 나의 카운트 +1
// 3) 컴퓨터의 숫자가 클 때 -&gt; 컴퓨터의 카운트 +1

if (userDiceNum &gt; comDiceNum) {
  userScore += 1;
} else if (userDiceNum &lt; comDiceNum) {
  comScore += 1;
}

// 결과 값을 state에 반영 -&gt; 웹 페이지의 정보를 업데이트
// { ...user } -&gt; {name:&#39;&#39;, diceNum:1. score:0, imPath:&#39;&#39;} 분할 -&gt; spread 연산자
setUser({
  ...user,
  diceNum: userScore,
  score: userScore,
  imgPath: `./img/dice${userDiceNum}.png`,
});

setCom({
  ...com,
  diceNum: comScore,
  score: comScore,
  imgPath: `./img/dice${comDiceNum}.png`,
});</code></pre><p>  };</p>
<p>  // 초기화 기능 구현하기
  // 함수명 : initDice
  function initDice() {
    setUser({
      ...user,
      diceNum: 0,
      score: 0,
      imgPath: <code>./img/dice1.png</code>,
    });</p>
<pre><code>setCom({
  ...com,
  diceNum: 0,
  score: 0,
  imgPath: `./img/dice1.png`,
});</code></pre><p>  }</p>
<p>  return (
    <div className="container">
      <h1>주사위 게임</h1>
      <ButtonArea throwDice={throwDice} initDice={initDice} />
      <BoardArea user={user} com={com} />
    </div>
  );
};</p>
<p>export default DiceApp;</p>
<pre><code>- ButtonArea.jsx</code></pre><p>import React from &quot;react&quot;;
import Button from &quot;react-bootstrap/Button&quot;;</p>
<p>const ButtonArea = ({ throwDice, initDice }) =&gt; {
  return (
    <div className="button-area">
      &lt;Button variant=&quot;warning&quot; onClick={() =&gt; throwDice()}&gt;
        던지기
      </Button>
      &lt;Button variant=&quot;danger&quot; onClick={() =&gt; initDice()}&gt;
        초기화
      </Button>
    </div>
  );
};</p>
<p>export default ButtonArea;</p>
<pre><code>- BoardArea.jsx</code></pre><p>import React from &quot;react&quot;;
import Board from &quot;./Board&quot;;</p>
<p>const BoardArea = ({ user, com }) =&gt; {
  return (
    <div className="board-area">
      <Board user={user} />
      <Board user={com} />
    </div>
  );
};</p>
<p>export default BoardArea;</p>
<pre><code>- Board.jsx</code></pre><p>import React from &quot;react&quot;;</p>
<p>const Board = ({ user }) =&gt; {
  console.log(user);
  return (
    <div className="board">
      <h4>{user.name}</h4>
      <img src={user.imgPath} alt="이미지 없음." />
      <div className="score-area">
        <h4>현재 점수는?</h4>
        <h4>{user.score}</h4>
      </div>
    </div>
  );
};</p>
<p>export default Board;</p>
<pre><code>
- dice.css</code></pre><p>.container {
  display: flex;
  justify-content: center;
  flex-direction: column;
  text-align: center;
  height: 100vh;
}</p>
<p>.button-area &gt; button {
  margin-left: 10px;
}</p>
<p>.board-area {
  display: flex;
  justify-content: center;
}</p>
<p>.board-area &gt; div {
  margin-left: 10px;
  margin-top: 20px;
}</p>
<p>.score-area {
  margin-top: 20px;
}</p>
<pre><code>
![](https://velog.velcdn.com/images/songmin_tech/post/073a0ce4-a343-487d-9bee-b36f52b96b4a/image.png)</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[리엑트 - 리액트 흐름과 컴포넌트]]></title>
            <link>https://velog.io/@songmin_tech/%EB%A6%AC%EC%97%91%ED%8A%B8-%EC%8B%A4%EC%8A%B51</link>
            <guid>https://velog.io/@songmin_tech/%EB%A6%AC%EC%97%91%ED%8A%B8-%EC%8B%A4%EC%8A%B51</guid>
            <pubDate>Tue, 23 Apr 2024 04:42:22 GMT</pubDate>
            <description><![CDATA[<h1 id="실습해보기">실습해보기</h1>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/5171783a-35c9-4021-b053-546f17187737/image.png" alt=""></p>
<pre><code></code></pre><h2 id="실습2">실습2</h2>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/f6ab5e11-1315-4819-87c5-aa620884df5a/image.png" alt=""></p>
<pre><code></code></pre><hr>
<h1 id="알아두면-좋은-명령어">알아두면 좋은 명령어</h1>
<ul>
<li>컴포넌트 구조 자동생성 명령어 : rafce</li>
</ul>
<hr>
<h1 id="리엑트-흐름">리엑트 흐름</h1>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/9410af44-87aa-4d32-a00c-f992168f462e/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/0ed5124f-7235-44c3-84b3-6b518dbcd705/image.jpg" alt=""></p>
<hr>
<h1 id="component">Component</h1>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/85cb13c5-48ff-48f5-b32d-aabd931b01ed/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/6432088c-95d1-4ff6-91d7-8b8676a1517a/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/9139e83b-d040-45d9-b657-36dc20beb6f5/image.png" alt=""></p>
<hr>
<ul>
<li><p>02.component 폴더 생성</p>
</li>
<li><p>cd로 터미널 위치 변경</p>
</li>
<li><p>npx create-react-app .</p>
</li>
</ul>
<hr>
<h2 id="에러-발생시">에러 발생시</h2>
<ul>
<li>노드 패키지를 수동으로 설치하여 해결<blockquote>
<p>npm install npm -g</p>
</blockquote>
</li>
</ul>
<hr>
<ul>
<li>두 파일 생성하기
<img src="https://velog.velcdn.com/images/songmin_tech/post/7ed60c6c-ba2b-4df8-9f43-46ed21fd9c52/image.png" alt=""></li>
</ul>
<hr>
<h1 id="컴포넌트">컴포넌트</h1>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/a029c9ed-ae52-45f7-8de4-9c9bf92983ac/image.jpg" alt=""></p>
<ul>
<li>top 태그에 불러서 사용가능 이를 컴포넌트라고 함</li>
</ul>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/285b0fb8-7b1a-48ba-835a-3374d8414284/image.jpg" alt=""></p>
<h2 id="컴포넌트-생성-규칙">컴포넌트 생성 규칙</h2>
<ol>
<li>반드시 시작 이름의 첫 문자는 대문자이어야 한다!!</li>
<li>함수형 컴포넌트 또는 클래스 컴포넌트</li>
</ol>
<p>사용자 정의 함수</p>
<ul>
<li>rafce --&gt; 함수형 컴포넌트 생성 단축키</li>
<li>props : <ul>
<li>index.js에서 전달 받은 데이터(객체 형식)</li>
<li>상위 컴포넌트에서 하위 컴포넌트로 데이터를 넘길때 사용 되어 진다.<pre><code class="language-js">import React from &quot;react&quot;;
</code></pre>
</li>
</ul>
</li>
</ul>
<p>const MyTeam = (props) =&gt; {
  return (
    <div>
      <p>{props.title}</p>
      <p>{props.name}</p>
      <br></br>
    </div>
  );
};</p>
<p>// 내보내기
export default MyTeam;</p>
<pre><code>&lt;br&gt;

### index.js 에서 설정
```js
import React from &quot;react&quot;;
import ReactDOM from &quot;react-dom/client&quot;;
import &quot;./index.css&quot;;
import reportWebVitals from &quot;./reportWebVitals&quot;;

// 컴포넌트 불러오기
// Menu 컴포넌트를 App이라는 이름으로 불러와서 사용하겠다 !
import Footer from &quot;./component/Menu_header&quot;;
import App from &quot;./component/Menu&quot;;

const root = ReactDOM.createRoot(document.getElementById(&quot;root&quot;));
root.render(
  &lt;React.StrictMode&gt;
    {/* propos : 컴포넌트를 사용할때 데이터를 전달하는 방법 */}
    &lt;Footer /&gt;
    &lt;App menu={&quot;아메리카노&quot;} price={4100} /&gt;
    &lt;App menu={&quot;카페라떼&quot;} price={4500} /&gt;
  &lt;/React.StrictMode&gt;
);</code></pre><p><img src="https://velog.velcdn.com/images/songmin_tech/post/2a8254db-0edc-4235-b94b-76791b31c32d/image.png" alt=""></p>
<hr>
<h2 id="props를-이용한-대략적인-흐름">props를 이용한 대략적인 흐름</h2>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/bd5b176f-d5f9-474a-a3b3-5f4ba9ad63eb/image.png" alt=""></p>
<hr>
<h2 id="실습">실습</h2>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/322e8647-65d7-4c4f-9180-230df68b57ad/image.png" alt=""></p>
<hr>
<h2 id="defaultprops">defaultProps</h2>
<ul>
<li>넘겨받은 데이터가 없을때 기본 값을 지정할 수 있다.</li>
</ul>
<pre><code>import React from &quot;react&quot;;

const MyTeam = (props) =&gt; {
  return (
    &lt;div&gt;
      &lt;p&gt;{props.title}&lt;/p&gt;
      &lt;p&gt;{props.name}&lt;/p&gt;
      &lt;br&gt;&lt;/br&gt;
    &lt;/div&gt;
  );
};

// default props : 넘겨받은 데이터가 없을때 기본 값을 지정할 수 있다.
MyTeam.defaultProps = {
  name: &quot;아무도 없습니다.&quot;,
};

// 내보내기
export default MyTeam;
</code></pre><p><img src="https://velog.velcdn.com/images/songmin_tech/post/546d20bf-a482-4df6-9b94-8a4b1cdb787b/image.png" alt=""></p>
<p>name의 값이 없어도 기본값이 아무도 없습니다로 적용된다.</p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/f0459415-f149-4813-a8a3-8c00cc9f8758/image.png" alt=""></p>
<hr>
]]></description>
        </item>
        <item>
            <title><![CDATA[리엑트 - 실행 환경 설정]]></title>
            <link>https://velog.io/@songmin_tech/%EB%A6%AC%EC%97%91%ED%8A%B8-%EC%8B%A4%ED%96%89-%ED%99%98%EA%B2%BD-%EC%84%A4%EC%A0%95</link>
            <guid>https://velog.io/@songmin_tech/%EB%A6%AC%EC%97%91%ED%8A%B8-%EC%8B%A4%ED%96%89-%ED%99%98%EA%B2%BD-%EC%84%A4%EC%A0%95</guid>
            <pubDate>Mon, 22 Apr 2024 04:31:32 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/songmin_tech/post/be60b169-e248-4afd-b7a7-bf89182f6e84/image.png" alt=""></p>
<hr>
<h1 id="react">React</h1>
<h2 id="개요">개요</h2>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/941637fd-9c1e-4aaf-a128-12d0d50059e0/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/032ca285-f227-483e-bcf5-7e0c9861fd63/image.jpg" alt=""></p>
<h2 id="react-사용해야하는-이유">React 사용해야하는 이유</h2>
<ol>
<li><p>자바스크립트 만으론 ui구성이 어렵다!&gt;</p>
<ul>
<li><p>HTML 과 JS 분리</p>
</li>
<li><p>JSX로 HTML와 JS의 필요한 부분을 합쳐준다 !</p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/713d8097-d74a-4ca9-b8d7-a4f238750449/image.png" alt=""></p>
</li>
</ul>
</li>
</ol>
<ol start="2">
<li><p>직관적이지만 너무 긴 js
<img src="https://velog.velcdn.com/images/songmin_tech/post/276dc87d-774f-44e8-8b53-14de9b5b9d46/image.jpg" alt=""></p>
</li>
<li><p>기존 새 페이지를 들어갈 때 마다 새로고침의 문제점
<img src="https://velog.velcdn.com/images/songmin_tech/post/1f3c1bc5-67d0-45a8-94ec-614f2f53fb17/image.jpg" alt=""></p>
</li>
</ol>
<hr>
<h1 id="react란">React란?</h1>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/1334659e-72f5-4708-b33a-3a9260295086/image.jpg" alt=""></p>
<h2 id="라이브러리-프레임워크">라이브러리, 프레임워크</h2>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/c9f50104-c925-47ba-9986-4c880bdf9506/image.jpg" alt=""></p>
<h2 id="리엑트-역사와-선호도">리엑트 역사와 선호도</h2>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/9911dada-662a-481f-bb76-459c2518885c/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/ba00e459-59bc-4e15-a11e-ce0b6deda195/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/cf409d94-cd3a-4b27-b985-91a12c290aac/image.jpg" alt=""></p>
<hr>
<h1 id="react-개발환경-구축">React 개발환경 구축</h1>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/e27d39bc-51bc-4680-abde-789cf76e2648/image.jpg" alt=""></p>
<ul>
<li><p>바탕화면에 react-master 폴더명으로 생성</p>
</li>
<li><p>node.js 다운</p>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/503fc13c-5f13-4dc2-bcf5-d166c311e423/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/a2fa9f5a-a82f-4d4d-aaf3-e84c14eb27eb/image.png" alt=""></p>
<ul>
<li><p>동의사항 외 모두 체크 없이 next 버튼 클릭후 설치 누르면됨!</p>
</li>
<li><p>파워셀 열기 &gt; cd .\Desktop\ &gt; cd .\react-master\ code .</p>
<ul>
<li>vscode 실행됨</li>
<li>실행된 vscode의 경로 지정한 곳인지 확인해보기(react-master)</li>
</ul>
</li>
<li><p>컨트롤 + ~ 누르면 vscode에 터미널 켜짐(아래와 같이 입력해보기)</p>
<ul>
<li>에러뜨면 다시해야함..
<img src="https://velog.velcdn.com/images/songmin_tech/post/18bb52c1-6585-4381-804c-861b08427e74/image.png" alt=""></li>
</ul>
</li>
<li><p>npx create-react-app 01.basic </p>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/95433cc9-682b-46f6-a17e-ae06cd0ab810/image.png" alt=""></p>
<ul>
<li>이렇게 뜨면 성공</li>
</ul>
<hr>
<h3 id="에러발생">에러발생</h3>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/91323947-1e5d-46a1-8d98-8a8f262f2f08/image.png" alt=""></p>
<ul>
<li>해당 폴더에 npm 폴더를 생성해줘야함.<ul>
<li>appData는 숨겨있음으로 보기에서 숨겨진 파일 보이기 하고 들어가야함
<img src="https://velog.velcdn.com/images/songmin_tech/post/49f3c9a1-5e1d-4c9d-b2fc-275eaa21157a/image.jpg" alt=""></li>
</ul>
</li>
</ul>
<hr>
<ul>
<li>cd로 경로 지정해주고 npm 실행해주기</li>
</ul>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/62d09f81-e505-45ec-9830-a02abba40dd6/image.png" alt=""></p>
<hr>
<h2 id="vscode">vscode</h2>
<p>설정을 완료하였다면 해당 파일이 있는 것을 확인해볼 수 있다.</p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/fb61c34c-3ef6-498f-97ec-dad410114994/image.jpg" alt=""></p>
<h2 id="vscode-환경설정">vscode 환경설정</h2>
<ul>
<li><p>다음 3가지 다운로드
<img src="https://velog.velcdn.com/images/songmin_tech/post/1f57057d-34b9-47c4-a4d7-d7ebda6e9d94/image.png" alt=""></p>
</li>
<li><p>컨트롤 + , 으로 환경설정 체크하고 변경하기
<img src="https://velog.velcdn.com/images/songmin_tech/post/7bf62d26-0ef6-47fe-8074-b5b5852e8d84/image.png" alt=""></p>
</li>
</ul>
<hr>
<h2 id="리엑트-기본-디렉토리-구조">리엑트 기본 디렉토리 구조</h2>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/95390d85-42bf-4c71-a1bc-a61bb5236943/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/d279af63-0873-48f3-bbc7-1d05a2afb208/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/6b664fd5-d7ea-4319-8cef-2281b1e9f443/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/a65c97f3-3a3d-4bb8-b5ab-88c6d117019d/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/d3191657-a38e-4627-8cad-a7ae473fd61d/image.jpg" alt=""></p>
<hr>
<h1 id="jsx-문법">JSX 문법</h1>
<h3 id="jsx-문법-특징">JSX 문법 특징</h3>
<ol>
<li><p>하나 이상의 HTMl문법을 사용하려면 반드시 부모 요소로 감싸야 한다!</p>
</li>
<li><p>표현식 {} 을 통해서 HTML과 JS를 같이 사용할 수 있다.</p>
<ul>
<li><p>{} 안에 JS의 변수나 데이터를 넣어주면 페이지에 출력된다.</p>
</li>
<li><p>조건부 렌더링를 통해 데이터 출력</p>
</li>
<li><blockquote>
<p>if문을 사용할때 return문 바깥쪽에서 정의하거나, 
 if문 안에 return문을 넣는 방식</p>
</blockquote>
</li>
<li><blockquote>
<p>삼항 연산자는 return문 안에 정의할 수 있다.
 조건에 따라 결과 값은 HTML 문법과 같이 출력 할 수 있음
 한 줄인 경우 : 소괄호 생략
 한 줄 이상의 경우 : 소괄호 추가 + 부모요소 감싸주기</p>
</blockquote>
</li>
<li><blockquote>
<p>&amp;&amp;, || 연산자를 활용해서 true or false에 대한 결과 값 출력</p>
</blockquote>
</li>
</ul>
</li>
</ol>
<ol start="3">
<li>기존 HTML 문법과 다른점<ul>
<li>class -&gt; className으로 정의</li>
<li>HTML 문법은 소문자 | 컴포넌트는 대문자로 인식</li>
</ul>
</li>
</ol>
<ol start="4">
<li>스타일 적용은 객체형태로 정의<ul>
<li>인라인 방식 ex) &lt;p style = {{color:&#39;red&#39;}}</p></li>
<li>변수 정의
ex)
const styled={color:&#39;red&#39;}
&lt;.p style={styled}&gt;</p></li>
<li>css파일 import</li>
</ul>
</li>
</ol>
<hr>
]]></description>
        </item>
        <item>
            <title><![CDATA[07. 애플리케이션 테스트 관리]]></title>
            <link>https://velog.io/@songmin_tech/07.-%EC%95%A0%ED%94%8C%EB%A6%AC%EC%BC%80%EC%9D%B4%EC%85%98-%ED%85%8C%EC%8A%A4%ED%8A%B8-%EA%B4%80%EB%A6%AC</link>
            <guid>https://velog.io/@songmin_tech/07.-%EC%95%A0%ED%94%8C%EB%A6%AC%EC%BC%80%EC%9D%B4%EC%85%98-%ED%85%8C%EC%8A%A4%ED%8A%B8-%EA%B4%80%EB%A6%AC</guid>
            <pubDate>Sat, 13 Apr 2024 02:43:09 GMT</pubDate>
            <description><![CDATA[<h1 id="정보처리기사-정리">정보처리기사 정리</h1>
<p>(1) ~ (6)은 출제도가 낮아 제외</p>
<h3 id="▶-23년-3회까지-출제-횟수-분석">▶ 23년 3회까지 출제 횟수 분석</h3>
<blockquote>
<p>(1) (최하)7 요구사항 확인<br>(2) (최하)5 데이터 입출력 구현
(3) (하)9 통합 구현
(4) (중하)17 서버 프로그램 구현
(5) (최하하)3 인터페이스 구현
(6) (최하)5 화면설계
(7) (중)23 <a href="https://velog.io/@songmin_tech/07.-%EC%95%A0%ED%94%8C%EB%A6%AC%EC%BC%80%EC%9D%B4%EC%85%98-%ED%85%8C%EC%8A%A4%ED%8A%B8-%EA%B4%80%EB%A6%AC">애플리케이션 테스트 관리</a></p>
</blockquote>
<hr>
<h1 id="1-애플리케이션-테스트">(1) 애플리케이션 테스트</h1>
<h3 id="애플리케이션-테스트">애플리케이션 테스트</h3>
<ul>
<li>애플리케이션에 잠재된 결함을 찾아내는 일련 행위/절차</li>
<li>소프트웨어가 요구사항을 만족하는지 확인(Validation)</li>
<li>소프트웨어가 기능을 정확시 수행하는지 검증(Verification)</li>
</ul>
<h3 id="애플리케이션-테스트-기본원리">애플리케이션 테스트 기본원리</h3>
<ul>
<li>완벽한 테스트 불가능 : 잠재적 결함은 줄일 수 있지만, 소프트웨어에 결함이 없다고 증명 불가능</li>
<li>파레토 법칙 : 20%에 해당하는 코드에서 전체 결함 80% 발견 법칙</li>
<li>살충제 패러독스 : 동일한 방법으로 테스트를 반복하면 더 이상 결함 발견되지 않는 현상</li>
<li>오류 부제의 궤변 : 결함을 모두 제거해도 요구사항에 만족시키지 못하면 품질에 문제가 있는 것</li>
</ul>
<h3 id="정적-테스트">정적 테스트</h3>
<ul>
<li>프로그램을 실행하지 않고 명세서나 소스코드 대상 분석 테스트</li>
<li>코딩 표준. 스타일, 복잡도 , 남은 결함 발견 목적</li>
<li>종류 워크스루, 인스펙션, 코드검사</li>
</ul>
<hr>
<h2 id="2-애플리케이션-테스트의-분류">(2) 애플리케이션 테스트의 분류</h2>
]]></description>
        </item>
        <item>
            <title><![CDATA[AWS(EC2) ubuntu 연동 방법]]></title>
            <link>https://velog.io/@songmin_tech/aws%EB%A9%98%ED%86%A0%EB%8B%98-%EB%B0%A9%EB%B2%95</link>
            <guid>https://velog.io/@songmin_tech/aws%EB%A9%98%ED%86%A0%EB%8B%98-%EB%B0%A9%EB%B2%95</guid>
            <pubDate>Fri, 12 Apr 2024 11:25:13 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/songmin_tech/post/06b97979-9ea1-4520-a669-ea8252eed83f/image.jpg" alt=""></p>
<h1 id="연동방법-정리">연동방법 정리</h1>
<ul>
<li>윈도우10 운영체제</li>
<li>EC2 인스턴스 생성시 주의해야할 사항에 대해 알아보자</li>
<li>cml의 cmd로 EC2를 ubuntu로 연동하고 html 생성</li>
<li>vscode로 EC2를 연동하여 EC2 내 html과 Flask로 연동 실행하여 실시간 업데이트 체험해보기</li>
</ul>
<hr>
<h1 id="ec2-인스턴스-생성시-주의사항">EC2 인스턴스 생성시 주의사항</h1>
<ul>
<li>EC2의 인스턴스 먼저 생성함 </li>
<li>환경은 우분투로 설정하고 인스턴스 유형은 t2스몰 ~ t3스몰 사이 성능으로 만들것!
(이하 성능으로 인스턴스 생성시vscode 연결시 무한 로딩에 빠짐)</li>
</ul>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/67f10df3-3a8b-483f-9faf-a0cf6e975f58/image.jpg" alt=""></p>
<ul>
<li><p>t2스몰 ~ t3스몰 사이로 생성할 것.
<img src="https://velog.velcdn.com/images/songmin_tech/post/acbc27b7-8baf-4130-b57a-85abf137c776/image.jpg" alt=""></p>
</li>
<li><p>키 생성 위치(경로) 복사해두기</p>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/3a7c88d4-a2c0-4fbd-a83e-86698d118902/image.jpg" alt=""></p>
<ul>
<li>인스턴스 생성 &gt; 실행중 상태 &gt; 보안 &gt; 보안그룹 &gt; 인바인드 규칙 HTTP/SSH 사용자 설정(주소 0.0.0.0)으로 만들기</li>
</ul>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/9e2c6985-92cc-4ed9-aa3f-a1a129a8bcdf/image.jpg" alt=""></p>
<ul>
<li>퍼블릭 IPv4 주소 메모장에 복사해두기</li>
</ul>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/28cfd87c-c77b-44d7-8f69-b4ecdec833ce/image.jpg" alt=""></p>
<hr>
<h1 id="ec2-unbuntu-연결">EC2 unbuntu 연결</h1>
<ul>
<li>윈도우 환경에 cmd로 CLI로 접속 </li>
<li>리눅스 권한주고 확인해보기</li>
<li>HTML 파일 생성해보기</li>
</ul>
<h2 id="cmd-에서-unbuntu-접속">cmd 에서 unbuntu 접속</h2>
<ul>
<li><p>key.pem에 대한 경로로 설정하기
cd C:\Users\smhrd4\Downloads
<img src="https://velog.velcdn.com/images/songmin_tech/post/a620cb21-f47c-4469-9710-b8e5834338a5/image.jpg" alt=""></p>
</li>
<li><p>ssh -i key.pem ubuntu@퍼블릭 IPv4 주소입력 &gt; yes &gt; 초록색 문구로 unbuntu@ ... ~$ 문구 뜨면 성공
<img src="https://velog.velcdn.com/images/songmin_tech/post/fc951f08-47e6-410e-a833-61f77876486d/image.jpg" alt=""></p>
</li>
<li><p>우분투 나가는 키는 
exit</p>
</li>
</ul>
<hr>
<h2 id="리눅스로-기본-상태보기">리눅스로 기본 상태보기</h2>
<ul>
<li><p>htop : cpu 성능 보는것 (나가기 : q)
<img src="https://velog.velcdn.com/images/songmin_tech/post/8d3e31fa-c682-4b17-b608-2fe3f29fe282/image.jpg" alt=""></p>
</li>
<li><p>hello.txt 파일생성</p>
<p>  touch hello.txt</p>
</li>
<li><p>hello.txt에 내용 저장 &quot; &quot;</p>
<p>  echo &quot;hello&quot; &gt; hello.txt</p>
<ul>
<li>내용 보기 : cat hello.txt</li>
<li>파일 삭제 : rm hello.txt</li>
</ul>
</li>
<li><p>권한보기 : ls -l
<img src="https://velog.velcdn.com/images/songmin_tech/post/63ac1094-0f49-486d-84e8-9ff03815def6/image.jpg" alt=""></p>
</li>
</ul>
<hr>
<h2 id="웹서버-연동-해보기">웹서버 연동 해보기</h2>
<ul>
<li>주요 내용<ul>
<li>우분투에서 웹서버를 설치한다.</li>
<li>웹서버에 접속하여 페이지 내용을 불러와 본다.</li>
<li>퍼블릭 IPv4 주소입력하여 웹 페이지에 접속해 본다.</li>
</ul>
</li>
</ul>
<br>

<ul>
<li>웹서버 설치(nginx 설치)<blockquote>
<p>apt install nginx -y</p>
</blockquote>
</li>
</ul>
<br>

<p>통상적인 방법으로 입력할시 에러 발생
(sudo로 관리자 권한 명령하자!)</p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/0bfe0947-bb87-4111-875f-c416ae5f5892/image.jpg" alt=""></p>
<blockquote>
<p>sudo apt install nginx -y</p>
</blockquote>
<ul>
<li><p>웹서버레 접속해서 페이지 내용을 불러온것 </p>
<blockquote>
<p>curl localhost</p>
</blockquote>
</li>
<li><p>이와 같은 문구를 출력하면 웹서버 접속 성공적! 
<img src="https://velog.velcdn.com/images/songmin_tech/post/706428d5-9650-45b3-8000-a8aa815aa5e7/image.jpg" alt=""></p>
</li>
<li><p>브라우저에 퍼블릭 IPv4 주소입력하여 다음과 같이 뜨면 성공!
<img src="https://velog.velcdn.com/images/songmin_tech/post/8ad37607-3545-40aa-bfc7-75f06f57b90f/image.jpg" alt=""></p>
</li>
</ul>
<hr>
<h2 id="만약-안된다면-재-확인-해볼-것">만약 안된다면 재 확인 해볼 것!</h2>
<ol>
<li>인바인드 규칙 설정(HTTP/SSH)</li>
<li>sudo apt install nginx -y 설치 재확인
<img src="https://velog.velcdn.com/images/songmin_tech/post/9e2c6985-92cc-4ed9-aa3f-a1a129a8bcdf/image.jpg" alt=""></li>
</ol>
<hr>
<h2 id="우분투로-기본적인-html-생성">우분투로 기본적인 html 생성</h2>
<ul>
<li><p>우분투 입력</p>
<blockquote>
<p>cd /var/www/html</p>
</blockquote>
</li>
<li><p>현재 디렉토리(.)의 소유자를 root 사용자로, 그룹 소유자를 ubuntu 그룹으로 변경합니다.</p>
<blockquote>
<p>sudo chown root:ubuntu .</p>
</blockquote>
</li>
<li><p>현재 디렉토리(.)에 대해 그룹(g)에게 쓰기 권한(+w)을 추가합니다. </p>
<blockquote>
<p>sudo chmod g+w .</p>
</blockquote>
</li>
<li><p>index.html에 태그를 추가합니다.</p>
<blockquote>
<p><code>echo &quot;&lt;H1&gt;Hello &lt;/H1&gt;&quot; &gt; index.html</code></p>
</blockquote>
</li>
<li><p>index.html내용을 확인합니다.</p>
<blockquote>
<p>cat index.html
<img src="https://velog.velcdn.com/images/songmin_tech/post/e175b46d-3dd4-4899-93c9-94fddaaed984/image.jpg" alt=""></p>
</blockquote>
</li>
</ul>
<hr>
<h1 id="vscode로-ec2접속해보기">VScode로 EC2접속해보기</h1>
<ul>
<li>remote-ssh를 설치하여 EC2 우분투와 연결</li>
</ul>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/a5521aeb-c04b-4931-9a9e-dd791b1f53bf/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/04ff66cf-898d-4a9d-8298-5ac0ac15ca05/image.png" alt=""></p>
<ul>
<li>ssh -i key.pem ubuntu@퍼블릭 IPv4 주소입력<ul>
<li>1번째 항목 선택</li>
</ul>
</li>
</ul>
<br>

<ul>
<li>F1 키 눌러서 아래 이미지같이 입력
<img src="https://velog.velcdn.com/images/songmin_tech/post/6d5d138e-f48f-40ca-82ce-0fbf7b322126/image.png" alt=""></li>
</ul>
<p>Host : 별칭(아무렇게나 해도됨)
HostName : 서버의 IP 혹은 도메인
User : 서버의 사용자 계정명
IdentityFile : 방금 위에서 export 한 key파일 (내껀 이름이 ssalbot 이다)</p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/ace4603c-e92b-46d8-b67f-c14714e4f5ac/image.jpg" alt=""></p>
<ul>
<li><p>새창으로 열기 &gt; 리눅스 선택 &gt; 초록색 터미널 창뜸
이후 작업은 클라우드에서 되는 작업이다.</p>
</li>
<li><p>오픈폴더 &gt; /var/www/html &gt; yes &gt; 파일 열고 html 수정하면됨(이미지는 태그 추가한 내용임)
<img src="https://velog.velcdn.com/images/songmin_tech/post/818b424a-3068-4354-942b-953492db57a6/image.png" alt=""></p>
</li>
</ul>
<br>

<h2 id="python-언어로-flask-환경-만들어보기">python 언어로 flask 환경 만들어보기</h2>
<ul>
<li>상위탭 &gt; 폴더열기 &gt; /home/ubuntu 경로 선택</li>
<li>윈도우에서 아나콘다 좋은점</li>
</ul>
<ol>
<li>가상환경 만든다</li>
<li>기능이 편리해서</li>
<li>라이브러리가 많아서</li>
</ol>
<br>

<ul>
<li><p>파이선 환경 구축</p>
<blockquote>
<p>sudo apt update
sudo apt install python3-venv</p>
</blockquote>
</li>
<li><p>가상환경을 만들기 위한 폴더 셋업한것</p>
<blockquote>
<p>python3 -mvenv ~/.venv/flask</p>
</blockquote>
</li>
<li><p>가상환경 불러온것(로딩)</p>
<blockquote>
<p>source ~/.venv/flask/bin/activate</p>
</blockquote>
</li>
<li><p>플라스크 라이브러리 설치</p>
<blockquote>
<p>pip install flask</p>
</blockquote>
</li>
</ul>
<hr>
<h2 id="java-설치">java 설치</h2>
<ul>
<li>자바 설치<blockquote>
<p>sudo apt install default-jdk</p>
</blockquote>
</li>
</ul>
<hr>
<h2 id="flask-구동">flask 구동</h2>
<ul>
<li>app.py<pre><code class="language-python">from flask import Flask, render_template
</code></pre>
</li>
</ul>
<p>app = Flask(<strong>name</strong>)</p>
<p>@app.route(&#39;/&#39;)
def home():
    return render_template(&#39;index.html&#39;)</p>
<p>@app.route(&#39;/user&#39;)
def user():
    return render_template(&#39;user.html&#39;)</p>
<p>@app.route(&#39;/admin&#39;)
def admin():
    return render_template(&#39;admin.html&#39;)</p>
<p>if <strong>name</strong> == &quot;<strong>main</strong>&quot;:
    app.run(host = &quot;0.0.0.0&quot;, debug=True)</p>
<pre><code>
- / admin / user.html</code></pre><p>간략한 태그에 간략한 내용... 각 구분만 할 수 있게 구성</p>
<pre><code>
- 설명
    - bash : python app.py
    - python :    curl localhost:5000 # 해당 cmd를 사용할 수 없어서 cmd하나 더 생성함.
![](https://velog.velcdn.com/images/songmin_tech/post/662ec8f6-8feb-45a8-91f0-0cbe96a3b451/image.png)</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[딥러닝 - 언어지능 Part2]]></title>
            <link>https://velog.io/@songmin_tech/%EB%94%A5%EB%9F%AC%EB%8B%9D-%EC%96%B8%EC%96%B4%EC%A7%80%EB%8A%A5-Part2</link>
            <guid>https://velog.io/@songmin_tech/%EB%94%A5%EB%9F%AC%EB%8B%9D-%EC%96%B8%EC%96%B4%EC%A7%80%EB%8A%A5-Part2</guid>
            <pubDate>Tue, 09 Apr 2024 08:51:20 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/songmin_tech/post/84593311-948a-4540-a1b8-38a3eb290641/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/939e815a-ff7f-4cb3-8bfe-bb00877ef51e/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/69736129-2087-4f01-aec1-0e51393ffcc1/image.jpg" alt=""></p>
<hr>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/a5192bf9-4eec-4035-bd4a-478ed9537991/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/7b49e861-e551-4581-a0c7-7b580f910504/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/588cbead-5902-4e3c-9cdd-37dab84873c9/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/8543e55a-85ed-4466-b8d4-82c80d3727d9/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/a9197c6a-21ad-41a6-a478-9b5f07b09722/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/d954fcfe-558b-4dee-afc7-0ad92e456dda/image.jpg" alt=""></p>
<hr>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/d93dd76c-4b8a-4a71-b0aa-1066c214d2fc/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/9f783947-a256-4823-8e8d-f18e40ca6deb/image.jpg" alt=""></p>
<hr>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/f4e13f11-784f-44a2-8486-439576f0474f/image.jpg" alt=""></p>
<hr>
<h2 id="트랜스포머">트랜스포머</h2>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/3b56df7b-a5b2-4432-8062-6aa199e8a313/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/d272ddbb-7b5d-4541-a3f6-a581c273c153/image.jpg" alt=""></p>
<h3 id="셀프-어텐션">셀프 어텐션</h3>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/daa16256-969e-4153-bf76-0ac288cc03bc/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/5eff915f-fa39-41a3-a74d-bf940476c6ba/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/db7dfe3b-8702-4766-ba9b-13aac2ce2332/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/7d0b0b0e-8a9a-4149-a7a8-04e58b5f0cdd/image.jpg" alt=""></p>
<hr>
<h1 id="실습">실습</h1>
<p><a href="https://colab.research.google.com/drive/1_zFdm2JwIVwWa0ZG6Vfi7LA7804t8TI5#scrollTo=0OaMD3LN0oKT">transformers기반 혐오표현 분류기</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[딥러닝 - 언어지능 Part1]]></title>
            <link>https://velog.io/@songmin_tech/%EB%94%A5%EB%9F%AC%EB%8B%9D-%EC%96%B8%EC%96%B4%EC%A7%80%EB%8A%A5-Part</link>
            <guid>https://velog.io/@songmin_tech/%EB%94%A5%EB%9F%AC%EB%8B%9D-%EC%96%B8%EC%96%B4%EC%A7%80%EB%8A%A5-Part</guid>
            <pubDate>Mon, 08 Apr 2024 04:40:37 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/songmin_tech/post/6a4dc0ff-341f-4e42-bc89-1c00768d5c3b/image.jpg" alt=""></p>
<hr>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/66c486cf-6126-4f62-99dc-f6a0445e1bbb/image.jpg" alt=""></p>
<ul>
<li>Part3에서는 프로젝트 관련하여 배울 예정이다.</li>
</ul>
<hr>
<h2 id="ai-관련-홈페이지">AI 관련 홈페이지</h2>
<ul>
<li>paperswithcode<ul>
<li><a href="https://paperswithcode.com/">https://paperswithcode.com/</a></li>
</ul>
</li>
<li>huggingface<ul>
<li><a href="https://huggingface.co/">https://huggingface.co/</a></li>
</ul>
</li>
</ul>
<hr>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/2c5964b3-f242-47f3-b815-2f7a58c7624b/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/6d5800c3-324b-463d-96d3-c9edefab84bd/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/09de8c34-e3a6-495d-87af-a8b042445fe9/image.jpg" alt=""></p>
<hr>
<h1 id="실습-1">실습 1</h1>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/3947a6ab-01a0-4153-836f-3937b222a62b/image.jpg" alt=""></p>
<p>※ <a href="https://colab.research.google.com/drive/1drt08eliyEkJdXC-9O8Zh2xmYuRvwh8u#scrollTo=lGo__PQYWG9E">허깅페이스 사전학습모델사용하기</a></p>
<ul>
<li><a href="https://huggingface.co/">https://huggingface.co/</a> 접속</li>
<li>로그인하기</li>
</ul>
<p>필요한 모델 복사 &gt; 입력하여 다운받고 사용하기
<img src="https://velog.velcdn.com/images/songmin_tech/post/d31a4678-4743-4e7b-965f-8182d6fbd4c9/image.jpg" alt=""></p>
<hr>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/8c043791-d438-4f2e-9f3a-0d19d60cbeb3/image.jpg" alt=""></p>
<ol>
<li><p>텍스트 마이닝, 자연어처리 -&gt; 토큰화 / 수치화</p>
<ul>
<li><p>예시) 나는 / 오늘 / 밥을 / 먹었다.</p>
<ul>
<li>유니그램 : 나는/오늘/밥을/먹었다.</li>
<li>바이그램 : 나는오늘/오늘밥을/밥을먹었다.</li>
<li>트라이그램 : 나는오늘밥을/오늘밥을먹었다.</li>
</ul>
</li>
</ul>
</li>
</ol>
<br>

<ol start="2">
<li>빈도 기반 vs 임베딩 방식</li>
</ol>
<ul>
<li><p>빈도 기반  </p>
<ul>
<li>단어를 구분만</li>
<li>부피가 커진다.</li>
</ul>
</li>
<li><p>임베딩 방식</p>
<ul>
<li>컬럼이 추가됨(친밀도, 크기, 등등)</li>
<li>빈도 기반보다 더 디테일 있다.</li>
</ul>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/10a7a8e5-2eb5-4bf0-b45b-f3d45fe446eb/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/d5cdbf4b-c955-4204-bff4-48f85db40637/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/68f75e9d-5ffb-43ad-8af9-8806ed324910/image.jpg" alt=""></p>
<hr>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/5f33ae72-a753-4d7b-b387-41dd221d3f19/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/5f094547-9687-4127-9d0a-d400d35e1cfe/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/acc3a3b9-9027-4472-9127-afc50c35f93e/image.jpg" alt=""></p>
<hr>
<h2 id="실습2">실습2</h2>
<p>※ <a href="https://colab.research.google.com/drive/1_xs9Fe6WbfEsH8Tak2YQLRopoAlOugHy#scrollTo=LdaRrnYAlKYS">워드 임베딩 실습</a></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/cfad18bd-8b7c-4fa2-9708-b874e521d5f2/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/04e7ff82-a60e-410b-b627-9cfa18feed70/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/14219aa3-11f9-42d2-80f0-a564c7647934/image.jpg" alt=""></p>
<hr>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/e8ac3114-e983-4204-9312-288cd2021e9f/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/f92031b1-9801-4faf-9894-86f5a7362d8f/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/3ba266f1-aea1-4e4e-8fd8-8ac5587a7c08/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/9f50049c-7e0a-4273-bd03-f0a552f2e3da/image.jpg" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[인공지능 되돌아보기]]></title>
            <link>https://velog.io/@songmin_tech/%EC%9D%B8%EA%B3%B5%EC%A7%80%EB%8A%A5-%EB%90%98%EB%8F%8C%EC%95%84%EB%B3%B4%EA%B8%B0</link>
            <guid>https://velog.io/@songmin_tech/%EC%9D%B8%EA%B3%B5%EC%A7%80%EB%8A%A5-%EB%90%98%EB%8F%8C%EC%95%84%EB%B3%B4%EA%B8%B0</guid>
            <pubDate>Fri, 05 Apr 2024 04:32:29 GMT</pubDate>
            <description><![CDATA[<h1 id="딥러닝-개념">딥러닝 개념</h1>
<pre><code>- 딥러닝이란 뭘까?</code></pre><hr>
<h2 id="1-인공지능">1) 인공지능</h2>
<ul>
<li>인간이 가지는 지적 능력들을 컴퓨터를 통해 구현하는 기술들의 집합</li>
<li>기술 자체를 총칭하는 개념 -&gt; 형태 자체가 없는 포괄적 개념이다.</li>
</ul>
<hr>
<h2 id="2-머신러닝">2) 머신러닝</h2>
<ul>
<li>데이터를 기반으로 컴퓨터 스스로 규칙을 찾아 학습하는 기술</li>
<li>인공지능을 구현하기 위한 핵심 기술이 머신러닝이다.</li>
</ul>
<hr>
<h2 id="3-딥러닝">3) 딥러닝</h2>
<ul>
<li>인간의 신경망을 모방하여 학습하는 기술</li>
<li>머신러닝에 포함된 세부적 기술
  -&gt; 머신러닝이 할 수 없는 것들을 해결해주는 기술</li>
</ul>
<p>가) 머신러닝이 학습을 할때 사용하는 데이터를 살펴보자!</p>
<ul>
<li>정형데이터 : 표의 형태를 가지고 있음</li>
<li><blockquote>
<p>DataFrame / ndarray</p>
</blockquote>
</li>
</ul>
<p>나) 딥러닝이 학습을 할때 사용하는 데이터를 살펴보자!</p>
<ul>
<li><p>유방암 데이터(ndarray), 폐암 데이터(ndarray)
보스턴 집값(CSV파일), 개고양이 분류(img), 네이버 감성분석(텍스트 데이터), 로이터 뉴스(텍스트 데이터), 패션데이터(img), 아기울음소리/섬집아기/자장가(음성데이터)</p>
</li>
<li><p>딥러닝의 구조</p>
<ul>
<li><p>딥러닝은 어떤 요소들로 구성이 되어 있을까?</p>
</li>
<li><blockquote>
<p>딥러닝 모델은 사람의 신경망을 모방해서 만들었다</p>
</blockquote>
<p>1) 뉴런 : 신경계를 구성하는 세포, 전기 신호를 전달 </p>
</li>
<li><blockquote>
<p>생각/반응/행동
사람의 뉴런은 신경세포, 인공신경망에서 뉴런은 선형회귀(y=wx+b)</p>
</blockquote>
<p>2) 퍼셉트론 : 기존 뉴런은 모든 신호를 다음 뉴런으로 전달해주는 구조 사람의 신경망은 역치라는 문턱 값을 가지고 있음.</p>
<blockquote>
</blockquote>
<p>신호 강도 &gt; 역치(문턱값) : 다음 뉴런으로 신호 전달
신호 강도 &lt; 역치(문턱값) : 신호 전달 X
인공신경망도 사람의 신경망과 최대한 유사하게 역치를 구현
역치를 구현하기 위해 뉴런에 활성화 함수를 연결시켜 역치 구현 뉴런 + 활성화 함수 = 퍼셈트론</p>
<p>3) 다중 퍼셉트론 : </p>
<blockquote>
</blockquote>
<p>기존 퍼셉트론 </p>
</li>
<li><blockquote>
<p>인간의 신경망을 모방 -&gt; 문제 해결능력 뛰어남 </p>
</blockquote>
</li>
<li><blockquote>
<p>논리게이트 XOR문제 해결 x </p>
</blockquote>
</li>
<li><blockquote>
<p>인공지능의 첫번째 겨울(연구 동결) </p>
</blockquote>
</li>
<li><blockquote>
<p>문제 해결을 위해 퍼셉트론(하나의 직선)을 여러 층으로 쌓아서 다층 퍼셉트론으로 구성(연산을 여러번 하도록)</p>
</blockquote>
</li>
</ul>
</li>
</ul>
<hr>
<h2 id="--출력층의-구조">- 출력층의 구조</h2>
<h3 id="1-회귀">1) 회귀</h3>
<ul>
<li>출력층 뉴런의 갯수 : 1개</li>
<li>손실함수 (loss) : MSE(평균 제곱 오차)</li>
<li>출력층 활성화 함수 : 생략 가능(Linear)<ul>
<li>뉴런의 구조(형태) -&gt; 선형 회귀 함수
선형회귀 함수에서 나온 예측값을 활성화 함수를 통과시키지 않고 그대로 출력하면 회귀 예측값이 나온다.</li>
</ul>
</li>
</ul>
<h3 id="2-분류">2) 분류</h3>
<p>2-1) 이진 분류
    - 출력층 뉴런의 갯수 : 1개
    - 손실함수 (loss) : Binary_crossentropy
    - 출력층 활성화 함수 : Sigmoid</p>
<blockquote>
<ul>
<li>Sigmoid : 0~1 사이의 확률 정보를 예측해서 예측값이 0.5보다 크거나 같으면 1로 예측, 작으면 0으로 예측</li>
</ul>
</blockquote>
<p>2-2) 다중 분류
    - 출력층 뉴런의 갯수 : 원핫 인코딩한 정답 데이터의 컬럼 갯수
    - 손실함수 (loss) : categorical_crossentropy
    - 출력층 활성화 함수 : Softmax</p>
<blockquote>
<ul>
<li>Softmax : 다중 분류에서 각 퍼셉트론의 예측 확률합을 1로 설정
  기존 Sigmoid 함수 -&gt; 이진 분류에 특화가 되어 있다.(0/1)
  실제 정답의 범위(0~1)와 예측 확률이 같아야 비교가 가능하다.
  시그모이드 함수의 다중분류에서 오차 파악이 제대로 되지 않는다.
  다중 분류에서 오차파악 / 예측확률을 정확하게 알아보기 위해 Softmax 사용</li>
</ul>
</blockquote>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/cb3c48f4-9bff-41b5-8dc8-fc1506ec44ec/image.jpg" alt=""></p>
<hr>
<h2 id="--오차-역전파중요">- 오차 역전파(중요)</h2>
<ul>
<li><p>신경망이 학습되는 원리는 무엇일까?</p>
</li>
<li><p>역으로 가중치를 수정하면서 신경망의 성능 개선</p>
<ul>
<li><p>순전파 : 입력 데이터를 입력층에서부터 출력층까지 정 방향으로 이동시키면서 출력 값을 예측해나가는 과정(예측)</p>
</li>
<li><p>역전파 : 출력층에서 예측값이 예측됨과 동시에 에러값(오차) 발생. 에러 값을 중간층을 통해 입력층 쪽으로 전파시키면서 가중치를 업데이트 하는 과정 - 경사 하강법을 이용해서 오차 값을 낮춰준다.(학습)</p>
</li>
</ul>
</li>
</ul>
<br>

<p>1 epochs 에서 일어나는 프로세스 : 데이터 입력 -&gt; 순전파(예측) &gt; 역전파(학습)</p>
<ul>
<li><p>신경망의 학습을 위해서는 경사하강법(손실함수(loss의 미분))을 사용</p>
</li>
<li><p>오차 역전파에서 문제점 발생</p>
<ul>
<li>초기 활성화 함수의 종류 : 계단함수 -&gt; Sigmoid 함수</li>
<li>Sigmoid 함수를 사용한 신경망에서 경사하강법을 적용/성능개선</li>
<li>기울기 소실 문제가 발생 : 오차 역전파를 통해 경사 하강법으로 성능을 개선 시킬때 Sigmoid 함수의 미분 최대값이 0.25<blockquote>
</blockquote>
</li>
<li><blockquote>
<p>컴퓨터가 기울기를 인식하기 못하는 문제가 생겼다!</p>
</blockquote>
</li>
<li><blockquote>
<p>컴퓨터가 학습하는 방법 : 순간적인 기울기를 구해서 기울기가 0이 되는 지점의 가중치를 찾아가는 방법으로 학습</p>
</blockquote>
</li>
<li><blockquote>
<p>기울기를 감지하지 못한다면? : 학습을 진행하지 못하는 문제가 발생(성능개선 X)
<img src="https://velog.velcdn.com/images/songmin_tech/post/85d455ee-6275-493b-a10a-e3fcfe7282f4/image.jpg" alt=""></p>
</blockquote>
</li>
</ul>
</li>
<li><p>기울기 소실문제를 해결하기 위해 Sigmoid 함수의 대체 함수를 찾아보자.</p>
</li>
</ul>
<ol>
<li>tanh : 하이퍼볼릭 탄젠트(tanh)</li>
</ol>
<p>-&gt; 위 아래로 범위를 늘려줘보자/ (Sigmoid 함수의 범위 0~1)
-&gt; 함수의 범위를 늘려서 기울기 소실문제에서 잘 버티지만 결국 형태는 Sigmoid함수와 동일 - 결국 기울기 소실 문제에서 자유로울 수는 없다.</p>
<br>

<ol start="2">
<li>relu</li>
</ol>
<ul>
<li>0보다 작을 때는 값을 0으로 / 0보다 크면 그값을 그대로 사용</li>
<li>기울기 소실 문제를 해결</li>
<li>가장 기초적으로 많이 사용하는 활성화 함수</li>
</ul>
<br>

<ol start="3">
<li>Leaky ReLU / ELU</li>
</ol>
<ul>
<li>ReLU 함수의 파생 함수</li>
</ul>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/ace89f5c-eed2-4b88-ba67-350b878dd301/image.jpg" alt=""></p>
<hr>
<h2 id="--최적화-함수">- 최적화 함수</h2>
<ul>
<li>신경망을 좀 더 효과적으로 학습 시키는 경사하강법을 찾아봅시다.</li>
</ul>
<p>1) 경사하강법</p>
<ul>
<li>비용함수(손실함수, loss)의 기울기를 구해서 기울기가 낮아지는 방향으로 가중치를 이동시키면서 파라미터 값을 최적화 시키는 방법</li>
</ul>
<p>2) 확률적 경사하강법</p>
<ul>
<li>모든 데이터를 연산하는 경사하강법은 컴퓨팅 자원 소모가 높고, 속도가 느리다 -&gt; 단점</li>
<li>일부 데이터만 가지고 경사하강법을 진행해서 자원과 속도를 확보</li>
</ul>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/795bec82-9414-49cc-a172-02f675044d19/image.jpg" alt=""></p>
<p>3) 미니배치 확률적 경사하강법</p>
<ul>
<li>일반적으로 PC 메모리의 한계 및 속도 저하 때문에 대부분의 경우에는 한 epochs에 모든 데이터를 집어 넣기 힘들다.</li>
<li>일반 경사하강법과 확률적 경사하강법의 절충안</li>
<li>데이터를 미니배치로 나눠서 배치별로 경사하강법을 진행</li>
</ul>
<p>4) Momentrm(모멘텀)</p>
<ul>
<li>경사하강법에 관성의 법칙을 적용해서 현재 batch뿐만 아니라 이전 batch에 데이터까지 업데이트에 반영합시다!</li>
<li>가중치를 수정하기 전 이전 학습 데이터 방향까지 참고해서 업데이트를 진행!</li>
<li>경사하강법이 진행되면서 가중치가 잘 업데이트 되었다면 해당 방향으로 더 많이 업데이트</li>
<li>아니라면 방향을 틀어 최적 값에 맞게 유연하게 수정하는 방식</li>
</ul>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/f79c1c82-20de-48cf-a7f9-720da3dde8dd/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/400bdbfa-e134-42b8-b959-9492f37e4148/image.jpg" alt=""></p>
<p>5) 네스테로프 모멘텀(NAG) -&gt; 스탭 방향</p>
<ul>
<li>모멘텀을 개선한 방식
-&gt; 모멘텀 : 여러가지 방향으로 최적 가중치 거리를 계산한 후 최적 값으로 이동
-&gt; 미리 해당방향으로 이동한다(가정) -&gt; 값을 계산하고 -&gt; 실제 업데이트에 반영
-&gt; 불필요한 이동을 더 줄일 수 있다.</li>
</ul>
<br>

<p>6) Adagrad(아다그라드) -&gt; 스탭 사이즈</p>
<ul>
<li>가중치를 업데이트 하면서 학습률을 점차 감소시키는 방식</li>
<li>처음에는 크게 학습하다가 점차 조금씩 학습 시키는 방식</li>
<li>학습을 빠르고 정확하게 할 수 있음.</li>
</ul>
<br>

<p>7) RMSProp -&gt; 스탭 사이즈</p>
<ul>
<li>Adagrad 단점을 해결하기 위해 등장한 최적화 함수</li>
<li>Adagrad : 최적해를 찾기 전에 스탭 사이즈가 줄어서 더이상 최적해를 못 찾는 문제발생</li>
<li>지수 이동 평균을 도입해서 최적해를 끝까지 찾아가도록 만들어준 최적화 함수</li>
<li>지수 이동 평균 : 과거에 모든 기간을 계산 대상으로 놓고 최근 데이터에 더 놓은 가중치를 두는 가중 이동 평균법</li>
</ul>
<br>

<p>8) Adam</p>
<ul>
<li>RMSProp + Momentum</li>
<li>스탭의 사이즈와 방향 둘다 고려해서 최적해를 찾아가자.</li>
<li>최적해를 찾아가기 위해 스텝 사이즈도 적절하게 조절하고 방향도 알맞게 잡아줍시다.</li>
<li>현재 가장 많이 사용하는 최적화 함수다 !</li>
</ul>
<hr>
<h1 id="지금까지-살펴본-신경망은-mlp">지금까지 살펴본 신경망은 MLP</h1>
<hr>
<h2 id="--cnnconvolutional-neuran-network-합성-곱-신경망">- CNN(Convolutional Neuran Network, 합성 곱 신경망)</h2>
<ul>
<li><p>왜? 합성 곱 신경망을 도입하게 되었을까?</p>
<ul>
<li>신경망은 여러 정형/비정형 데이터 모두 사용 가능하다.</li>
<li>MLP(다층퍼셉트론) -&gt; 이미지를 처리할때 픽셀 단위로 학습과 예측을 진행, MLP의 경우 이미지 픽셀의 위치에 민감하게 동작. 같은 이미지라도 사이즈가 위치가 달라지면 예측을 정확하게 못함</li>
</ul>
</li>
<li><p>MLP의 픽셀 위치에 민감하게 동작하는 부분을 개선 시켜서 이미지에서 특징을 추출해서 비교(CNN 작동 방식)</p>
</li>
<li><p>CNN의 구조
특징 추출부(Feature Extractor) + 분류기(Classifier)
특징 추출부 = Conv Layer + Pooling Layer</p>
<ul>
<li>Conv Layer : 돋보기 - 이미지에서 중요한 특성을 더 확대시키고 도드라지게 만들어 주는 층</li>
<li>Pooling Layer : 중요한 특성은 남기고 나머지 특성들을 제외시키는 층</li>
</ul>
</li>
</ul>
<ul>
<li>어떻게 특징을 추출할까?<ul>
<li>입력된 이미지에서 특징을 추출할 수 있는 가중치들이 들어 있는 필터 개념 도입</li>
<li>이미지 전체 영역에 대해 일괄적으로 필터를 사용하는 것 보다 특정 범위에 한정해서 필터를 적용한다면 훨씬 효과적으로 특징을 추출할 수 있을 것이다. 아이디어에서 착안</li>
<li>부분적으로 적용된 필터를 이동시키면서 필터가 적용된 이미지의 일부를 합성 곱 연산을 통해 특징을 추출하는 방식을 사용</li>
<li>필터 내부에 들어 있는 값(파라미터)들은 w(가중치)에 해당 한다.
<img src="https://velog.velcdn.com/images/songmin_tech/post/d6a85d12-8501-466b-a28f-b163368aff3d/image.jpg" alt=""></li>
</ul>
</li>
</ul>
<ul>
<li>컬러 이미지 합성 곱 연산<ul>
<li>이미지의 구조
1) 흑백 이미지 (X, Y, 1(0~255)) -&gt; 합성 곱 연산
2) 컬러 이미지 (X, Y, 3(RGB 채널))
<img src="https://velog.velcdn.com/images/songmin_tech/post/d27a814b-ed42-4358-b7c6-9f17ac0ef732/image.jpg" alt=""></li>
</ul>
</li>
</ul>
<ul>
<li><p>패딩(Padding)</p>
<ul>
<li>필터를 적용할때 마다 이미지의 크기가 줄어드는 효과</li>
<li>필터의 크길 인해 가장자리의 데이터가 부족하기 때문에 입력과 출력 이미지의 크기가 바뀌고 가장자리 데이터가 충분한게 학습되지 않느다.</li>
<li>이를 보완하기 위해 테두리에 0값을 둘러 채워주는 것을 패딩
1) Same : 테두리에 0값을 자동으로 채워준다. - 이미지 입출력이 동일하게 유지된다.
2) Valid : 테두리 사용 안한다.
<img src="https://velog.velcdn.com/images/songmin_tech/post/015efc0d-b1cb-42a8-ae2f-c2d25c1cb545/image.jpg" alt=""></li>
</ul>
</li>
<li><p>축소 샘플링</p>
<ul>
<li>스트라이드(Stride)<ul>
<li>합성공 연산을 수행할때 필터를 얼마나 이동시킬 것인가?</li>
<li>기본 값은 1픽셀씩 건너 뛰면서 합성곱 연산을 수행하는 방법</li>
<li>스트라이드를 지정해서 2픽셀 / 3픽셀씩 건너 뛰면서 합성곱 연산을 수행하는 방법
<img src="https://velog.velcdn.com/images/songmin_tech/post/d8b6563d-0113-4139-ab6a-504bee6ba243/image.jpg" alt=""></li>
</ul>
</li>
</ul>
</li>
</ul>
<ul>
<li>풀링(Pooling)<ul>
<li>CNN에서 합성곱 수행 결과를 모두 넘기지 않는다.</li>
<li>일정 범위 내에서 가장 큰 값 / 평균을 넘기는 방법</li>
<li>Max Poolong : 설정된 지역내에 가장 큰 값만 넘겨주는 것 - 상대적으로 많이 사용</li>
<li>Average Pooling : 설정된 지역 내에 평균 값을 구해서 넘겨주는 것</li>
<li>주의할 점</li>
<li>특정 추출부와 분류기를 연결할때 사이에 Flatten층을 추가</li>
<li>분류로 사용되는 MLP는 1차원 데이터를 받아서 학습</li>
<li><blockquote>
<p>특성이 추출된 이미지를 1차원으로 퍼주는 작업이 필요함 -&gt; Flatten 층이 1차원 변환</p>
</blockquote>
</li>
</ul>
</li>
</ul>
<br>

<ul>
<li><p>전이학습</p>
<ul>
<li><p>다른 데이터 셋으로 이미 학습한 모델을 이용해서 유사한 다른 데이터를 인식하는데 사용하는 기법</p>
</li>
<li><p>잘 학습된 사람의 지식을 그대로 받아와서 문제 해결을 하는 방식</p>
</li>
<li><p>특성 추출 방식</p>
<ul>
<li>CNN의 구조에서 특성 추출부를 이미 학습된 모델로 대체하는 방식</li>
<li>특성추출부만 사용하는 이유는 분류기(MLP)는 우리가 해결하고자 하는 문제에 맞춰서 설정</li>
<li>단 새롭게 분류할 클래스가 사전 학습에 사용된 데이터와 매우 특징이 다르면 특성 추출부의 일부분만 재 사용한다.(미세조정방식)</li>
</ul>
</li>
<li><p>미세 조정 방식</p>
<ul>
<li>사전 학습된 모델의 가중치를 목적에 맞게 전체 또는 일부를 재학습 시키는 방식</li>
<li>특성 추출부의 층들 중 하단부의 층들 몇개는 분류기(MLP)와 함께 새로 학습을 시키는 방식</li>
<li>처음에는 분류기의 파라미터가 랜덤하게 초기화 되어 있는으므로 특성 추출부의 앞 단계를 학습되지 않도록 동결시키고 뒷 간의 일부 계층만 학습이 가능하게 설정한 후 분류기(MLP)와 함께 학습시켜 파라미터를 적당하게 조절해주는 방식</li>
</ul>
</li>
</ul>
</li>
</ul>
<br>

<hr>
<h2 id="--rnn">- RNN</h2>
<p>(Recurrent Neural Network, 순간 신경망)</p>
<ul>
<li>등장 배경<ul>
<li>순서 있는 데이터 / 시간적 개념이 들어간 시계열 데이터를 해결하기 위해 RNN이 고안</li>
<li>문장을 보고 이해한다.(텍스트 데이터) - 각 단어가 정해진 순서대로 입력이 되어야한다는 것</li>
<li>과거에 입력된 데이터와 나중에 입력된 데이터 사이의 관계를 고려</li>
</ul>
</li>
</ul>
<br>

<ul>
<li>일반 신경망과의 차이점<ul>
<li>RNN은 여러개의 데이터가 순서대로 입력되었을때 앞서 입력 받은 데이터의 연산 결과를 잠시 기억해놓는 방식</li>
<li>다음 데이터가 들어오면서 기억된 연산 결과와 함께 연산을 진행하는 방식</li>
<li>앞에서 나온 입력에 대한 결과가 뒤에서 나오는 입력 값에 영향을 주는 구조</li>
<li>비슷한 두 문장이 입력되어도 앞에서 나온 입력 값을 구별해서 출력 값에 반영을 함.</li>
</ul>
</li>
</ul>
<br>

<ul>
<li>활용사례(순차기반 데이터를 처리할때 RNN이 효과적이다)
1) 시계열 데이터
2) 음악 데이터 - 음악(재생시간)
3) 문장(텍스트 데이터) 분석
4) 번역</li>
</ul>
<br>

<ul>
<li>RNN의 단점<ul>
<li>RNN의 기본 활성화 함수 : tanh -&gt; 기울기 소실문제에서 자유롭지 못하다.</li>
<li><blockquote>
<p>순환 횟수가 늘어날 수록 역전파 진행시 기울기가 점차 줄어들어서 학습을 제대로 못한다.</p>
</blockquote>
</li>
<li><blockquote>
<p>시간이 지날수록 이전 과거 데이터를 연산했던 결과값을 잊어버린다.</p>
</blockquote>
</li>
</ul>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/1a6eca4f-7582-44eb-8b04-6927f242bdc1/image.jpg" alt=""></p>
<ul>
<li>RNN의 단점을 해결하기 위해 LSTM 등장!</li>
<li><blockquote>
<p>순환 횟수가 많아져도 과거의 데이터를 기억할 수 있는 방안이 필요</p>
</blockquote>
</li>
<li><blockquote>
<p>데이터를 기억해주는 메모리 셀 -&gt; 기억 공간 추가</p>
</blockquote>
</li>
</ul>
<ul>
<li><p>메모리셀 : 시간 t, 메모리셀 c</p>
</li>
<li><blockquote>
<p>과거에 연산된 데이터부터 현재 시각 t까지 연산된 대부분의 정보 -&gt; c에 저장</p>
</blockquote>
</li>
<li><blockquote>
<p>별도로 저장 : 오차 역전파를 진행할때 c 메모리 셀은 활성화 함수를 통과하지 않음.</p>
</blockquote>
<ul>
<li>미분 했을때 값이 줄어드는 영향을 받지 않는다. -&gt; 기울기 소실 일어나지 않는다.</li>
</ul>
</li>
<li><blockquote>
<p>데이터를 LSTM 계층 내에서만 주고 받고 다른 층으로는 전달하지 않는다.</p>
</blockquote>
<ul>
<li>기울기 소실 문제와 과거 데이터를 잊어버리는 문제를 해결하기 위해 LSTM이 대안으로 등장</li>
</ul>
</li>
</ul>
<hr>
<h2 id="--워드-임베딩">- 워드 임베딩</h2>
<h3 id="자연어">자연어</h3>
<ul>
<li><p>컴퓨터가 효율적으로 자연어 처리를 하기 위한 방법론
자연어 : 무한대의 가짓수가 나온다 -&gt; 어순/단어조합/맞춤법/유사어</p>
<p>-&gt; 무한대의 조합식이 나오는 자연어를 컴퓨터가 잘 이해할 수 있도록 단순화 토큰화나 인코딩이 아닌 컴퓨터가 쉽게 이해할 수 있도록 변환 시켜주는 것
-&gt; 임베딩은 희소표현(원핫 인코딩) -&gt; 밀집표현(실수형태)로 변환 시켜주는 것을 의미
-&gt; 워드 임베딩은 한 단어의 의미를 풍부하게 만들어주는 역활을 한다.
-&gt; 밀집 표현을 사용했을때 단어들의 유사도(cosine 유사도)까지 판단해서 예측에 반영 가능</p>
</li>
</ul>
<br>

<h3 id="코사인-유사도">코사인 유사도</h3>
<ul>
<li>단어와 단어간의 유사한 정도를 표현하는 방법</li>
<li>범위 : -1 ~ 1</li>
<li>코사인 유사도가 1이다 : 단어가 완전 일치하다.</li>
<li>코사인 유사도가 0이다 : 두 단어가 관계가 없다(독립관계)</li>
<li>코사인 유사도가 -1이다 : 단어가 반대되는 의미를 가지고 있다.</li>
<li><blockquote>
<p>코사인 함수 사잇 각
0도 ~ 180도
사잇 각이 0도인 경우 : 단어가 일치하다(코사인 유사도 : 1)
사잇 각이 90도인 경우 : 두 단어가 관계가 없다(독립적인 관계)
사잇 각이 180도인 경우 : 두 단어가 반대되는 의미를 가지고 있다(코사인 유사도 : -1)</p>
</blockquote>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[딥러닝 - 파이토치]]></title>
            <link>https://velog.io/@songmin_tech/%EB%94%A5%EB%9F%AC%EB%8B%9D-%ED%8C%8C%EC%9D%B4%ED%86%A0%EC%B9%98</link>
            <guid>https://velog.io/@songmin_tech/%EB%94%A5%EB%9F%AC%EB%8B%9D-%ED%8C%8C%EC%9D%B4%ED%86%A0%EC%B9%98</guid>
            <pubDate>Thu, 04 Apr 2024 08:15:51 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/songmin_tech/post/967afa5d-6067-4927-b55d-0b5c948f1960/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/e550528e-3f5a-42a8-81b9-c4174b62cc8a/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/368c0d28-b558-4257-913a-d15763d6f023/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/3d8248d2-afc5-41ee-9367-4ed5b56c54d8/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/54494e6e-7ded-4809-b191-ed5baed190f9/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/822f44ab-49b9-41a2-8cea-22e93b308b9a/image.jpg" alt=""></p>
<hr>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/6349e8ec-ffbd-4f50-b121-185061f040ca/image.jpg" alt="">
<img src="https://velog.velcdn.com/images/songmin_tech/post/624e2f62-d053-4830-9f1b-cf8e325d47c8/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/73b3fb18-9aba-43a8-8ae3-0d7ff90c140e/image.jpg" alt="">
<img src="https://velog.velcdn.com/images/songmin_tech/post/77b046f3-06c6-43c4-9bbf-7aef4e820c4d/image.jpg" alt="">
<img src="https://velog.velcdn.com/images/songmin_tech/post/6b468cf2-be8f-4fbb-8a84-07249c088e3d/image.jpg" alt="">
<img src="https://velog.velcdn.com/images/songmin_tech/post/7c95573b-1dd1-4a73-a4fe-6166a19b264d/image.jpg" alt=""></p>
<hr>
<h1 id="실습">실습</h1>
<ul>
<li><a href="https://colab.research.google.com/drive/1rpPlLRHBoM1M3-d_5fex7ZRCzBpp60Wk#scrollTo=06bsOjiO3Sxo">파이토치를 이용한 딥러닝</a>
<img src="https://velog.velcdn.com/images/songmin_tech/post/47d1d7b8-0a18-48cc-979e-7ebf7fc55d3f/image.jpg" alt=""></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[머신러닝 - YoloV7기반 Custom 데이터로 객체 탐지 와 Roboflow]]></title>
            <link>https://velog.io/@songmin_tech/%EB%A8%B8%EC%8B%A0%EB%9F%AC%EB%8B%9D-YoloV7%EA%B8%B0%EB%B0%98-Custom-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%A1%9C-%EA%B0%9D%EC%B2%B4-%ED%83%90%EC%A7%80</link>
            <guid>https://velog.io/@songmin_tech/%EB%A8%B8%EC%8B%A0%EB%9F%AC%EB%8B%9D-YoloV7%EA%B8%B0%EB%B0%98-Custom-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%A1%9C-%EA%B0%9D%EC%B2%B4-%ED%83%90%EC%A7%80</guid>
            <pubDate>Wed, 03 Apr 2024 00:57:20 GMT</pubDate>
            <description><![CDATA[<hr>
<h1 id="yolov">YoloV</h1>
<h2 id="개요">개요.</h2>
<ul>
<li>Yolo버전에 대해 알아보자</li>
<li>객체 탐지 : 컴퓨터 비전과 이미지 처리와 관련된 컴퓨터 기술로서, 디지털 이미지와 비디오에서 관심 객체(예:인간, 건물, 자동차 등)의 위치를 감지하는 작업<ul>
<li>활용 분야 : 얼굴 검출, 보행자 검출, 영상 복구, 비디오 감시, 자율주행 등</li>
</ul>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/47f48efc-ef89-4e31-89cc-2fb92cabb790/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/d988c34d-f38a-4779-986d-faafd9102f8e/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/6fa2448f-3992-4ffc-a0ca-02193b08fb09/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/0e1d707d-abb3-4d78-97e1-e77c30c3d425/image.jpg" alt=""></p>
<hr>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/2fa2f59c-6c7c-41b0-9e95-9f678e717e89/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/4d93dc1c-c92f-44ef-abdc-0bac677ddf71/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/8abd8948-d274-40b7-afab-0beb734c46ce/image.jpg" alt=""></p>
<hr>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/2cd3deb5-78f2-4332-91a2-f0716a2832a4/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/3889a736-ddbd-4a21-a7a0-a73be77d2084/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/ef368dc0-ca0a-455a-a420-3f425e2951ae/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/a48fba71-5b4b-44c7-b337-8393e0a0a796/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/9de9c8f4-773f-4b6a-8c1e-6816831f7f80/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/c26842a2-d7fb-4ae2-b0ab-5c824f6dbebe/image.jpg" alt=""></p>
<ul>
<li>YoloV2</li>
</ul>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/b76f2b94-324e-4b14-97b9-fddcc2c78b52/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/25813f35-8dc8-4c3f-b3e1-57ca4479a7f4/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/8db3d92e-cf95-4658-96a2-19f7d566fdf4/image.jpg" alt=""></p>
<ul>
<li>YoloV3</li>
</ul>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/11676262-2327-4f52-9d21-0dced2f9d8d2/image.jpg" alt=""></p>
<ul>
<li>YoloV4</li>
</ul>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/efb74af4-b7fb-4993-8476-62342d0129c0/image.jpg" alt=""></p>
<ul>
<li>YoloV5</li>
</ul>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/4040ff24-b836-4148-852e-7a36779e1a6e/image.jpg" alt=""></p>
<ul>
<li>YoloV7</li>
</ul>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/84424bc4-0128-46e2-99e2-5ee78d844d55/image.jpg" alt=""></p>
<ul>
<li>YoloV6<ul>
<li>YoloV5를 기반으로 만들어짐</li>
<li>YoloV7 보다 나중에 나옴</li>
</ul>
</li>
</ul>
<ul>
<li>YoloV8</li>
</ul>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/4698c55f-1314-4c6d-8447-198a6c1cdcab/image.jpg" alt=""></p>
<hr>
<h1 id="data-annotation-기법">Data annotation 기법</h1>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/ba324663-4b68-4052-945d-51fb0a1afb50/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/21b5dbc2-3beb-4e21-8182-2a5300e3ebe1/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/96dead45-0ba0-4c24-a9bb-d25144997061/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/860f1e6a-0fb6-45d2-b030-572fead3aa77/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/a4c25f8e-7dc6-4fe8-9545-38caa6f56a73/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/09fb1e1d-a2db-45c1-ace7-01f338ff0238/image.jpg" alt=""></p>
<hr>
<h1 id="roboflow">Roboflow</h1>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/54c30572-36a3-487b-8ea1-d44ebaca006c/image.jpg" alt=""></p>
<ul>
<li>Roboflow 홈페이지 방문</li>
<li>로그인 </li>
<li>무료버전 &gt; workspace 이후 &gt; 스킵 버튼 클릭</li>
</ul>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/00f9477e-471f-49f1-a085-1e9364cf57e6/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/664b35a7-5337-4423-96fd-71a4885efad3/image.jpg" alt=""></p>
<ul>
<li><p>select folder</p>
</li>
<li><p>업로드 된것을 확인</p>
</li>
<li><p>save and 컨티뉴</p>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/77fbd04f-d725-48ed-b49c-0b48904bff79/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/394ccbe3-9d69-4bb4-b3e2-7cc2147c7196/image.jpg" alt=""></p>
<ul>
<li><p>사진 갯수 조정</p>
</li>
<li><p>팀원간 협력 가능
<img src="https://velog.velcdn.com/images/songmin_tech/post/c6769960-dbab-43bd-96b7-3d165dc20fd7/image.jpg" alt=""></p>
</li>
<li><p>첫 사진부터 눌러서 고양이와 강아지 분류</p>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/8f10768d-530b-4524-9650-04faa4f4f664/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/4fc5a0f1-56c3-4f08-b472-7776e637ab20/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/91573467-a07f-4c98-a054-6375ebf4d3af/image.jpg" alt="">
<img src="https://velog.velcdn.com/images/songmin_tech/post/f2fd731a-857b-447c-98bf-c05e5055f5a4/image.jpg" alt="">
<img src="https://velog.velcdn.com/images/songmin_tech/post/492700f0-12b8-4ad7-bf5a-f40e84c44590/image.jpg" alt="">
<img src="https://velog.velcdn.com/images/songmin_tech/post/93f5c9fe-8033-402c-b112-0e3f7f76919f/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/d63b17bc-3def-43b4-b72f-ba95e1f6c36b/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/b2efde9b-8e91-4eb1-978f-ca148e55f1d2/image.png" alt=""></p>
<hr>
<h1 id="실습">실습</h1>
<p><a href="https://colab.research.google.com/drive/18hQW7Oyhs3eYRalk-jIWZQ5z5G5nVxwk#scrollTo=Df0CiGi2wiqV">YoloV7기반 Custom 데이터로 객체 탐지</a></p>
<hr>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/951fc7c0-c86c-4fe6-ab5c-51061f20d85d/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/44337908-f592-4be4-a636-6fed15289520/image.jpg" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[머신러닝 - 워드 임베딩]]></title>
            <link>https://velog.io/@songmin_tech/%EB%A8%B8%EC%8B%A0%EB%9F%AC%EB%8B%9D-%EC%9B%8C%EB%93%9C-%EC%9E%84%EB%B2%A0%EB%94%A9</link>
            <guid>https://velog.io/@songmin_tech/%EB%A8%B8%EC%8B%A0%EB%9F%AC%EB%8B%9D-%EC%9B%8C%EB%93%9C-%EC%9E%84%EB%B2%A0%EB%94%A9</guid>
            <pubDate>Thu, 28 Mar 2024 03:45:11 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/songmin_tech/post/92b10e63-4616-4d09-adbc-12979c064d1b/image.jpg" alt=""></p>
<hr>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/9ea26366-2fae-4f19-ae23-5f7ac9d8035e/image.jpg" alt="">
<img src="https://velog.velcdn.com/images/songmin_tech/post/bb2e46ae-4f28-4174-a621-9d8324aae1f4/image.jpg" alt="">
<img src="https://velog.velcdn.com/images/songmin_tech/post/6bc1a69d-59f8-4ce0-9ee3-f72e3de71b78/image.jpg" alt=""></p>
<hr>
<h1 id="실습">실습</h1>
<ul>
<li><a href="https://colab.research.google.com/drive/16KFMH-62LXM2ndcOUELubF0LmUKsuTXP#scrollTo=dGRLjIqJ6YXL">로이터 뉴스 분류하기</a></li>
</ul>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/844e5d35-1328-4e22-9661-deee37d8b3dd/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/671b1b36-309b-44aa-af52-32a839b5abe8/image.jpg" alt=""></p>
<hr>
<h1 id="키위-라이브러리">키위 라이브러리</h1>
<pre><code>!pip install kiwipiepy</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[머신러닝 - NLP 토큰화(자연어처리)]]></title>
            <link>https://velog.io/@songmin_tech/%EB%A8%B8%EC%8B%A0%EB%9F%AC%EB%8B%9D-%ED%86%A0%ED%81%B0%ED%99%94%EC%9E%90%EC%97%B0%EC%96%B4%EC%B2%98%EB%A6%AC</link>
            <guid>https://velog.io/@songmin_tech/%EB%A8%B8%EC%8B%A0%EB%9F%AC%EB%8B%9D-%ED%86%A0%ED%81%B0%ED%99%94%EC%9E%90%EC%97%B0%EC%96%B4%EC%B2%98%EB%A6%AC</guid>
            <pubDate>Thu, 28 Mar 2024 00:15:51 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/songmin_tech/post/dce3a3e3-ce44-41b2-b042-277b0f553a4e/image.jpg" alt=""></p>
<hr>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/ad67c991-9905-496a-83f4-53e45cc854ca/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/1749b580-7a05-4871-9fad-2b7e7dfd922d/image.jpg" alt="">
<img src="https://velog.velcdn.com/images/songmin_tech/post/aaf256da-4229-4bc9-a2d8-77aec1a5b253/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/b9e67edf-d71e-4f8e-b0fb-ed03b9294c44/image.jpg" alt=""></p>
<p>---<br><img src="https://velog.velcdn.com/images/songmin_tech/post/24f3f885-279a-4298-a2dd-2ab27a6236b3/image.jpg" alt="">
<img src="https://velog.velcdn.com/images/songmin_tech/post/99f5d66e-a5a3-4fa4-88ee-04f426e085a6/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/f2eef1f2-f0b2-4ef4-af94-9b0fa5335a89/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/4163aa46-fab6-4b64-8299-0d6e1e6411fd/image.jpg" alt=""></p>
<hr>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/b0d0ba5c-435a-4b19-8327-5fc46b9113ad/image.jpg" alt="">
<img src="https://velog.velcdn.com/images/songmin_tech/post/6a1caa72-e682-4f95-ba91-a0807679b0dc/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/8f6cb738-2204-48e6-8f56-9203126c5900/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/72a2b3c0-65e0-46cd-a977-2e60542065bf/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/6628c863-c626-4fca-8678-4c8962cf3eb5/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/6dad6634-9850-4310-bffa-dcc17cf044db/image.jpg" alt=""></p>
<hr>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/fdc604d0-d3e7-4a85-8694-c8518bfd370d/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/54da1160-6575-46e4-8553-6bf5c7bf7592/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/72849372-28de-4324-a954-d3f6090769d0/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/4f9f0386-3a21-43a1-a152-1002b257b80b/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/bb2d207c-0521-4ec7-b42d-a8516106d12e/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/6ee0cbc3-8d86-4577-8f19-f20e7eaa3453/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/65256d0f-ccb2-4a6d-a0c4-322a6d3a5f35/image.jpg" alt=""></p>
<hr>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/d40d0022-4a08-4425-ae43-d141d0f8b266/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/a6894bf9-9ec1-4707-abc7-31ff26ecec06/image.jpg" alt=""></p>
<hr>
<h1 id="실습">실습</h1>
<ul>
<li><a href="https://colab.research.google.com/drive/1w_nXSSuhZawkmP1it1gkcE3hOFx2Oblg#scrollTo=cb2GWJcjpek7">네이버 영화리뷰 감성분석(konlpy)</a></li>
</ul>
<hr>
]]></description>
        </item>
        <item>
            <title><![CDATA[딥러닝 - CNN 소리데이터 학습]]></title>
            <link>https://velog.io/@songmin_tech/%EB%94%A5%EB%9F%AC%EB%8B%9D-CNN-%EC%86%8C%EB%A6%AC%EB%8D%B0%EC%9D%B4%ED%84%B0-%ED%95%99%EC%8A%B5</link>
            <guid>https://velog.io/@songmin_tech/%EB%94%A5%EB%9F%AC%EB%8B%9D-CNN-%EC%86%8C%EB%A6%AC%EB%8D%B0%EC%9D%B4%ED%84%B0-%ED%95%99%EC%8A%B5</guid>
            <pubDate>Tue, 26 Mar 2024 02:21:00 GMT</pubDate>
            <description><![CDATA[<hr>
<h1 id="실습">실습</h1>
<ul>
<li><a href="https://colab.research.google.com/drive/1Un8gssCBB5bHquD47bS7EFZb7gCKo4x9#scrollTo=vaR3c9QDGhcL">CNN 소리데이터 학습</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[최종 프로젝트!]]></title>
            <link>https://velog.io/@songmin_tech/%EC%B5%9C%EC%A2%85-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8</link>
            <guid>https://velog.io/@songmin_tech/%EC%B5%9C%EC%A2%85-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8</guid>
            <pubDate>Mon, 25 Mar 2024 05:50:57 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/songmin_tech/post/927309ce-f17d-4dda-935f-40b83969ef20/image.jpg" alt=""></p>
<hr>
<h1 id="최종-프로젝트">최종 프로젝트</h1>
<h2 id="개요">개요</h2>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/01acb179-8987-4c9e-9063-39733d373095/image.jpg" alt=""></p>
<h2 id="프로젝트-프로세스">프로젝트 프로세스</h2>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/917ed897-373d-4e8d-b517-bf961fb10984/image.jpg" alt=""></p>
<hr>
<h2 id="과제">과제</h2>
<ul>
<li>3개, 4월 1일 16:00까지 작성하여 제출</li>
<li>약식 기획서 제출 양식 아래 빨간글씨 참조</li>
</ul>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/5434c617-06f9-40dc-8511-2c5611b0d30e/image.jpg" alt=""></p>
<br>

<h3 id="자료조사-및-약식-기획서-작성">자료조사 및 약식 기획서 작성</h3>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/1521439a-52ae-4367-be00-09b8c51a147d/image.jpg" alt=""></p>
<h2 id="주의사항">주의사항</h2>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/ed682ff2-f4c0-4782-a396-fa289dd7c15e/image.jpg" alt=""></p>
<ul>
<li>멘토링 일지 시트를 매일 쓰기.</li>
</ul>
<hr>
<h1 id="기획-멘토링">기획 멘토링</h1>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/0dde4c34-c59e-4330-8c5b-59f9a9e31019/image.jpg" alt="">
<img src="https://velog.velcdn.com/images/songmin_tech/post/05719bdd-b80a-4074-a2de-67202b541aab/image.jpg" alt=""></p>
<p>자기소개는 개인으로 간략하게(무슨 기능을 하였는지 파트가 무엇인지)
<img src="https://velog.velcdn.com/images/songmin_tech/post/cae3b32a-192f-4ce6-837e-c76139649f37/image.jpg" alt=""></p>
<hr>
<h1 id="서비스-멘토링">서비스 멘토링</h1>
<p>멘토링 이후 완성된 기획서 작성해야함</p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/c17aaa5b-77dc-401e-a7d9-fe2f47ccec52/image.jpg" alt=""></p>
<hr>
<h1 id="기술-멘토링">기술 멘토링</h1>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/2e156807-fe21-450f-a3a4-dcb30275ebf7/image.jpg" alt=""></p>
<ul>
<li>빅데이터 기획서 추가됨</li>
</ul>
<hr>
<h1 id="기획-발표">기획 발표</h1>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/29d0d742-b701-4dfe-8cb9-16c29c0622e1/image.jpg" alt=""></p>
<hr>
<h1 id="산출물">산출물</h1>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/0b831fe5-7d60-469d-9bc7-e16daf17d8d0/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/2d1601dd-15f0-4b03-b617-cafe73ae9f2a/image.jpg" alt=""></p>
<hr>
<h1 id="ui--ux">UI / UX</h1>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/a084d5c1-28e9-4ef3-9dd5-bf22e4588ad7/image.jpg" alt=""></p>
<hr>
<p><img src="https://velog.velcdn.com/images/songmin_tech/post/95b17369-4bdf-4877-ac2d-cb3d22c959d1/image.jpg" alt=""></p>
<ul>
<li>프로젝트 진행 및 최종 발표</li>
</ul>
<hr>
<h1 id="주제-공개">주제 공개!</h1>
<ul>
<li><a href="https://smhrd.dooray.com/share/pages/OPwxLft8QcKlIzxXS8Az5Q/3766765267144252603">실전 프로젝트 게시판(교육기간 끝나면 사라짐)</a></li>
</ul>
]]></description>
        </item>
    </channel>
</rss>