<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>surusuu_.log</title>
        <link>https://velog.io/</link>
        <description></description>
        <lastBuildDate>Wed, 01 Jun 2022 07:01:53 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>surusuu_.log</title>
            <url>https://velog.velcdn.com/images/surusuu_/profile/5691216e-060c-49f7-a10d-22793f0a1f08/image.jpeg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. surusuu_.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/surusuu_" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[알고리즘] Dynamic Programming]]></title>
            <link>https://velog.io/@surusuu_/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-Dynamic-Programming</link>
            <guid>https://velog.io/@surusuu_/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-Dynamic-Programming</guid>
            <pubDate>Wed, 01 Jun 2022 07:01:53 GMT</pubDate>
            <description><![CDATA[<h1 id="dp란">DP란?</h1>
<ul>
<li>메모리를 적절히 사용하여 수행 시간 효율성을 비약적으로 향상시키는 방법!</li>
<li><strong>이미 계산된 결과는 별도의 메모리 영역에 저장</strong>하여 다시 계산하지 않도록 함</li>
<li>탑다운과 보텀업으로 구성됌</li>
</ul>
<h4 id="문제가-다음의-조건을-만족할-때-사용할-수-있음">&gt; 문제가 다음의 조건을 만족할 때 사용할 수 있음</h4>
<ol>
<li>최적 부분 구조: 큰문제를 작은 문제로 나눌 수 있으며 작은 문제의 답을 모아서 큰 문제를 해결 가능</li>
<li>중복되는 문제: 동일한 작은 문제를 반복적으로 해결해야 함</li>
</ol>
<h1 id="dp방법">DP방법</h1>
<h3 id="--메모이제이션">- 메모이제이션</h3>
<p>한 번 계산한 결과를 메모리 공간에 메모하는 기법
값을 기록해 놓는다는 점에서 <strong>캐싱</strong>이라고도 함</p>
<h4 id="1-탑다운">1. 탑다운</h4>
<pre><code>하향식</code></pre><h4 id="2-보텀업">2. 보텀업</h4>
<pre><code>상향식
전형적인 형태
결과 저장용 리스트 = DP테이블</code></pre><h1 id="dp활용-예시">DP활용 예시</h1>
<h3 id="--피보나치-수열">- 피보나치 수열</h3>
<p>1,1,2,3,5,8,13,21,34,55,89,...</p>
<p>점화식: An = An-1 + An-2, A1=1, A2=1</p>
<pre><code class="language-java">public static long[] d = new long[100];
public static void main(String[] args){
    d[1]=1;
    d[2]=1;
    int n=50;  //50번째 피보나치 수를 계산

    for(int i=3; i&lt;=n; i++){
        d[i] = d[i-1]+d[i-2];
    }

    System.out.println(d[n]);  //실행결과:12586269025
}</code></pre>
<p><img src="https://velog.velcdn.com/images/surusuu_/post/962a9333-c8e3-4f96-8f4f-a5c83a9a0328/image.png" alt=""></p>
<h1 id="dp문제-예시">DP문제 예시</h1>
<h3 id="문제">&gt; 문제</h3>
<p><img src="https://velog.velcdn.com/images/surusuu_/post/86267a27-0b35-4c67-a869-0b64290c2699/image.png" alt="">
<img src="https://velog.velcdn.com/images/surusuu_/post/d1545761-7d15-4fe1-83d4-d2b9cb79d7d8/image.png" alt="">
<img src="https://velog.velcdn.com/images/surusuu_/post/7b1be88f-199c-4408-b8d5-561af9c9d8ae/image.png" alt=""></p>
<h3 id="해결-아이디어">&gt; 해결 아이디어</h3>
<p><img src="https://velog.velcdn.com/images/surusuu_/post/418fac64-b6ac-4feb-84f8-b8af071045c5/image.png" alt="">
<img src="https://velog.velcdn.com/images/surusuu_/post/099f1cd8-f5a2-4a75-9371-a4f58e40f1ec/image.png" alt="">
<img src="https://velog.velcdn.com/images/surusuu_/post/4af568e3-54e3-4970-b05c-2a93289dc63d/image.png" alt=""></p>
<pre><code class="language-java">public static int[] d = new int[100];    //DP테이블 초기화
public static void main(String[] args){
    Scanner sc = new Scanner(System.in);

    //정수 n을 입력받기
    int n = sc.nextInt();

    //모든 식량 정보 입력받기
    int[] arr = new int[n];
    for(int i=0; i&lt;arr.length; i++){
        arr[i]=sc.nextInt();
    }

    //DP진행(보텀업)
    d[0]=arr[0];
    d[1]=Math.max(arr[0],arr[1]);
    for(int i=2; i&lt;n; i++){
        d[i]=Math.max(d[i-1],d[i-2]+arr[i]);
    }

    //계산된 결과 출력
    System.out.println(d[n-1]);
}
</code></pre>
<h1 id="참고">참고</h1>
<hr>
<ul>
<li>유튜브 (유코테2021 강의 몰아보기) 6. 다이나믹 프로그래밍</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[알고리즘] 이진탐색]]></title>
            <link>https://velog.io/@surusuu_/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EC%9D%B4%EC%A7%84%ED%83%90%EC%83%89</link>
            <guid>https://velog.io/@surusuu_/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EC%9D%B4%EC%A7%84%ED%83%90%EC%83%89</guid>
            <pubDate>Mon, 30 May 2022 13:29:18 GMT</pubDate>
            <description><![CDATA[<h1 id="이진탐색">이진탐색</h1>
<ul>
<li><p>정렬되어 있는 리스트에서 <strong>탐색 범위를 절반씩 좁혀가며</strong> 데이터를 탐색하는 방법</p>
</li>
<li><p>시작점,끝점,중간점을 이용하여 탐색 범위를 설정한다.</p>
</li>
<li><p>이진탐색 하기 전 먼저 배열정렬을 꼭 해주어야 한다.
<img src="https://velog.velcdn.com/images/surusuu_/post/dd79e92d-15d3-4f31-ab1b-82afa22dee2b/image.png" alt="">
<img src="https://velog.velcdn.com/images/surusuu_/post/ec1986db-c359-444e-99b7-0d23e9a33e5d/image.png" alt="">
<img src="https://velog.velcdn.com/images/surusuu_/post/7087ddf4-7018-44a5-8283-7a5a2384457e/image.png" alt="">
<img src="https://velog.velcdn.com/images/surusuu_/post/cfeb57d1-ad66-4de1-871d-72530ac996a2/image.png" alt=""></p>
<pre><code class="language-java">while(start&lt;=end){
  int mid = (start+end)/2;

  //찾은 경우 중간점 인덱스 반환
  if(arr[mid]==target) return mid;
  //중간점의 값보다 찾고자 하는 값이 작은 경우 왼쪽 확인
  else if(arr[mid]&gt;target) end = mid-1;
  //중간점의 값보다 찾고자 하는 값이 큰 경우 오른쪽 확인
  else start = mid+1;
}
return -1;</code></pre>
</li>
</ul>
<hr>
<h1 id="참고">참고</h1>
<ul>
<li>유튜브 (유코테2021 강의 몰아보기) 5. 이진 탐색</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[알고리즘] DFS & BFS]]></title>
            <link>https://velog.io/@surusuu_/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-DFS-BFS</link>
            <guid>https://velog.io/@surusuu_/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-DFS-BFS</guid>
            <pubDate>Wed, 25 May 2022 07:13:00 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><strong>배경지식</strong></p>
</blockquote>
<h1 id="stack">Stack</h1>
<ul>
<li>선입후출의 자료구조<pre><code class="language-java">Stack&lt;Integer&gt; s = new Stack&lt;&gt;();
</code></pre>
</li>
</ul>
<p>s.push(5);    //삽입
s.push(4);    //삽입
s.pop();    //제거</p>
<p>while(!s.empty()){
    System.out.print(s.peek() + &quot;&quot;);    //최상단값 출력
    s.pop();
}</p>
<p>//실행결과
5</p>
<pre><code>
# Queue
- 선입선출의 자료구조
- 입구와 출구가 모두 뚫려 있는 터널과 같은 형태
```java
Queue&lt;Integer&gt; q = new LinkedList&lt;&gt;();

q.offer(5);    //삽입
q.offer(4);    //삽입
q.poll();    //제거

while(!q.isEmpty()){
    System.out.print(q.poll() + &quot;&quot;);
}

//실행결과
4</code></pre><h1 id="재귀함수">재귀함수</h1>
<ul>
<li>자기 자신을 다시 호출하는 함수</li>
<li>재귀 함수의 종료 조건을 반드시 명시해야 함</li>
</ul>
<p>활용 1) 최대공약수 계산 : 유클리드 호제법</p>
<pre><code>유클리드 호제법이란?
두 자연수 A,B에 대하여 (A&gt;B) A를 B로 나눈 나머지를 R이라고 하자.
이때 A와 B의 최대공약수는 B와 R의 최대공약수와 같다!</code></pre><pre><code class="language-java">static int gcd(int a, int b) {
    if(a%b==0) {
        return b;
    }
    return gcd(b,a%b);
}</code></pre>
<p>활용 2) 최소공배수 계산</p>
<pre><code>최소공배수 = 두수의 곱 / 두수의 최대공약수</code></pre><pre><code class="language-java">static int lcm(int a,int b) {
    return a*b/gcd(a,b);
}</code></pre>
<blockquote>
<p><strong>DFS &amp; BFS</strong></p>
</blockquote>
<h1 id="dfs">DFS</h1>
<ul>
<li>깊이 우선 탐색 / 깊은 부분을 우선적으로 탐색하는 알고리즘</li>
<li>스택 자료구조 혹은 재귀함수를 이용</li>
</ul>
<ol>
<li>탐색 시작 노드를 스택에 삽입하고 방문처리.</li>
<li>스택의 최상단 노드에 방문하지 않은 인접한 노드가 하나라도 있으면 그 노드를 스택에 넣고 방문처리. 방문하지 않은 인접노드가 없으면 스택에서 최상단 노드를 꺼냄.</li>
<li>더 이상 2번이 과정을 수행할 수 없을 때까지 반복.</li>
</ol>
<p><img src="https://velog.velcdn.com/images/surusuu_/post/72697bf1-f40a-4276-b823-926919828d90/image.png" alt="">
<img src="https://velog.velcdn.com/images/surusuu_/post/1ae1c2c0-d60f-4c3b-b90e-a341ba01a512/image.png" alt="">
<img src="https://velog.velcdn.com/images/surusuu_/post/b3a3b7cc-ffca-44d3-96d1-749ccd41df26/image.png" alt="">
<img src="https://velog.velcdn.com/images/surusuu_/post/8e4824b4-acd6-449a-95f1-1e0e377abd9e/image.png" alt="">
<img src="https://velog.velcdn.com/images/surusuu_/post/8712e2ce-314b-4cc0-9320-3ff5ac2cbd63/image.png" alt="">
<img src="https://velog.velcdn.com/images/surusuu_/post/d901fcbd-40ce-4119-b019-268d0778ae55/image.png" alt=""></p>
<h1 id="bfs">BFS</h1>
<ul>
<li>너비 우선 탐색 / 가까운 노드부터 우선적으로 탐색하는 알고리즘</li>
<li>큐 자료구조 이용</li>
</ul>
<ol>
<li>탐색 시작 노드를 큐에 삽입하고 방문처리.</li>
<li>큐에서 노드를 꺼낸 뒤에 해당 노드의 인접 노드 중에서 방문하지 않은 노드를 모두 큐에 삽입하고 방문처리.</li>
<li>더 이상 2번의 과정을 수행할 수 없을 때까지 반복.</li>
</ol>
<p><img src="https://velog.velcdn.com/images/surusuu_/post/2f8c2dac-b23b-4322-9264-5e284f295136/image.png" alt="">
<img src="https://velog.velcdn.com/images/surusuu_/post/d76091fb-ff47-4457-9f12-db9275e6a435/image.png" alt="">
<img src="https://velog.velcdn.com/images/surusuu_/post/3e6ec5a1-f5ad-47d4-ab81-949ad81ec480/image.png" alt="">
<img src="https://velog.velcdn.com/images/surusuu_/post/5768c0c9-47c3-4751-93c3-da55bd1ab22a/image.png" alt="">
<img src="https://velog.velcdn.com/images/surusuu_/post/afd49193-f24a-407f-bbbb-b267f03a5f11/image.png" alt="">
<img src="https://velog.velcdn.com/images/surusuu_/post/cd2317d5-0406-472a-bf90-5c11123b979c/image.png" alt=""></p>
<hr>
<h1 id="참고">참고</h1>
<ul>
<li>유튜브 (유코테2021 강의 몰아보기) 3. DFS&amp;BFS</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Git] pull request하는 방법]]></title>
            <link>https://velog.io/@surusuu_/Git-pull-request%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95</link>
            <guid>https://velog.io/@surusuu_/Git-pull-request%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95</guid>
            <pubDate>Tue, 24 May 2022 04:09:55 GMT</pubDate>
            <description><![CDATA[<ol>
<li>원하는 사람의 github에 가서 fork 버튼 클릭</li>
<li>fork로 생성한 본인 저장소에서 download code 버튼 클릭 후, url 복사 </li>
<li>자신의 터미널에서 home directory에, <code>git clone repo</code><pre><code> * repo: 복사한 url</code></pre></li>
<li>ls를 하면 clone한 폴더가 나오고, 그 폴더로 들어가서, <code>git branch branch_name</code><pre><code> * branch_name: 자신이 만들고 싶은 branch명을 입력</code></pre></li>
<li><code>git checkout branch_name</code> </li>
<li>파일추가/수정등을한후에, <code>git add file_name</code> =&gt; <code>git commit</code></li>
<li><code>git push repo branch_name</code></li>
<li>fork한 사람의 github에 가서 compare&amp;pull request버튼 클릭 후, 메세지 보내고 create pull request클릭</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[[오픈소스] 프로젝트]]></title>
            <link>https://velog.io/@surusuu_/%EC%98%A4%ED%94%88%EC%86%8C%EC%8A%A4-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8</link>
            <guid>https://velog.io/@surusuu_/%EC%98%A4%ED%94%88%EC%86%8C%EC%8A%A4-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8</guid>
            <pubDate>Tue, 24 May 2022 04:09:29 GMT</pubDate>
            <description><![CDATA[<h3 id="1-오픈소스에-대한-소개">1) 오픈소스에 대한 소개</h3>
<p>오늘날 AR과 VR은 우리와 밀접한 관계를 갖고 있다.
그래서 &quot;model-viewer&quot;라는 web component를 사용해서 web상에 3D model을 띄우는 프로젝트를 할 것이다.</p>
<p>아래는 프로젝트를 하기위해 준비되어야 하는 것들이다.</p>
<p>1) 웹 브라우저 ( ex. chrome,firefox,safari 등.. )
2) Node.js, text editor, glitch
3) HTML,CSS,JavaScript에 대한 기본적인 지식</p>
<p>위의 3가지가 준비되었다면 시작해보자!</p>
<h3 id="2-오픈소스-설치">2) 오픈소스 설치</h3>
<h4 id="1-glitch에-접근하기">1. glitch에 접근하기</h4>
<p>다음의 링크를 누르면 glitch에 접속할 수 있다.</p>
<p><a href="https://glitch.com/edit/#!/remix/googlecodelabs-model-viewer-codelab"><img src="https://images.velog.io/images/surusu/post/88f5c097-d683-470b-bf82-d8144d1188c7/image.png" alt=""></a>
glitch에서 프로젝트를 호스트하고 코드변화를 확인 할 수 있다.</p>
<h4 id="2-서버연결코드다운하기">2. 서버연결&amp;코드다운하기</h4>
<p>우리는 local web page에 접근하기 위해서 Node.js를 설치해야한다.
아래의 링크를 눌러 설치한다.
<a href="https://nodejs.org/en/"><img src="https://images.velog.io/images/surusu/post/5418134b-fb41-40cd-baee-51bb9c5ad2e8/image.png" alt="(https://nodejs.org/en/)"></a>
Node.js 설치 후, command창에 다음의 명령문을 실행한다.</p>
<pre><code>npm install -g serve</code></pre><p>코드를 다운로드한다.</p>
<pre><code>git clone https://github.com/googlecodelabs/model-viewer-codelab.git</code></pre><p>다운로드 한 경로에서 서버를 실행시킨다
<img src="https://images.velog.io/images/surusu/post/1a1ef5c3-1e25-4358-99ec-624954a8dc07/image.png" alt="">
<a href="http://localhost:5000">http://localhost:5000</a> 에 접속하면 서버에 연결된 것을 확인 할 수 있다.
<img src="https://images.velog.io/images/surusu/post/671a19c2-dc2b-45e4-ab21-791c73559aaf/image.png" alt=""></p>
<h4 id="3-indexhtml-수정하기">3. index.html 수정하기</h4>
<p>glitch에 들어가면, 빨간 박스에 보여지는 것과 같이, git으로 clone한 것들이 연동되어 있는 것을 볼 수 있다.
<img src="https://images.velog.io/images/surusu/post/02ab334b-5860-49d1-8856-e3d6343ffa65/0.png" alt=""></p>
<p>index.html에서,
<strong>3-1. model-viewer library를 추가하기</strong>
body 끝에 다음의 코드를 삽입한다. 
webXR API가 없기 때문에 아직은 웹상에 아무런 변화가 없고 debtools의 consol창에 가보면 에러가 나는 것을 확인할 수 있다.</p>
<pre><code>&lt;!-- 💁 Include both scripts below to support all browsers! --&gt;

&lt;!-- Loads &lt;model-viewer&gt; for modern browsers: --&gt;
&lt;script type=&quot;module&quot;
    src=&quot;https://unpkg.com/@google/model-viewer/dist/model-viewer.js&quot;&gt;
&lt;/script&gt;

&lt;!-- Loads &lt;model-viewer&gt; for old browsers like IE11: --&gt;
&lt;script nomodule
    src=&quot;https://unpkg.com/@google/model-viewer/dist/model-viewer-legacy.js&quot;&gt;
&lt;/script&gt;</code></pre><p><strong>3-2. polyfills 추가하기</strong> 
( *polyfills:  해당 환경의 수단 만 사용하여 이전 환경에 새로운 API를 제공 하는 라이브러리 )
head 부분에 다음의 코드를 삽입한다.</p>
<pre><code>&lt;!-- The following libraries and polyfills are recommended to maximize browser support --&gt;
&lt;!-- NOTE: you must adjust the paths as appropriate for your project --&gt;

&lt;!-- 🚨 REQUIRED: Web Components polyfill to support Edge and Firefox &lt; 63 --&gt;
&lt;script src=&quot;https://unpkg.com/@webcomponents/webcomponentsjs@2.1.3/webcomponents-loader.js&quot;&gt;&lt;/script&gt;

&lt;!-- 💁 OPTIONAL: Intersection Observer polyfill for better performance in Safari and IE11 --&gt;
&lt;script src=&quot;https://unpkg.com/intersection-observer@0.5.1/intersection-observer.js&quot;&gt;&lt;/script&gt;

&lt;!-- 💁 OPTIONAL: Resize Observer polyfill improves resize behavior in non-Chrome browsers --&gt;
&lt;script src=&quot;https://unpkg.com/resize-observer-polyfill@1.5.1/dist/ResizeObserver.js&quot;&gt;&lt;/script&gt;

&lt;!-- 💁 OPTIONAL: Fullscreen polyfill is required for experimental AR features in Canary --&gt;
&lt;!--&lt;script src=&quot;https://unpkg.com/fullscreen-polyfill@1.0.2/dist/fullscreen.polyfill.js&quot;&gt;&lt;/script&gt;--&gt;

&lt;!-- 💁 OPTIONAL: Include prismatic.js for Magic Leap support --&gt;
&lt;!--&lt;script src=&quot;https://unpkg.com/@magicleap/prismatic@0.18.2/prismatic.min.js&quot;&gt;&lt;/script&gt;--&gt;</code></pre><p><strong>3-3. model-viewer 태그 추가하기</strong>
기존 p태그를 지우고 model-viewer 태그를 삽입한다.</p>
<pre><code>&lt;model-viewer src=&quot;third_party/Astronaut/Astronaut.glb&quot;
              alt=&quot;A 3D model of an astronaut&quot;&gt;
&lt;/model-viewer&gt;</code></pre><p>다음의 단계를 잘 따라왔으면,
web page에 3D model이 생성된 것을 볼 수 있다 !!!</p>
<h3 id="3-오픈소스-활용-및-후기">3) 오픈소스 활용 및 후기</h3>
<p><img src="https://images.velog.io/images/surusu/post/75b19737-31c4-4164-8375-70732643fcee/ezgif.com-video-to-gif.gif" alt="">
오픈 소스를 활용하기 위해서 추가적인 기능을 넣기로 했다.</p>
<p>1) 회전하는 기능</p>
<pre><code>&lt;model-viewer src=&quot;third_party/Astronaut/Astronaut.glb&quot;
              auto-rotate camera-controls
              alt=&quot;A 3D model of an astronaut&quot;&gt;
&lt;/model-viewer&gt;</code></pre><p>2) ar기능
 ARCore&#39;s Scene Viewer장치로 직접 눈으로 3d모델을 보기 가능</p>
<pre><code>&lt;model-viewer src=&quot;third_party/Astronaut/Astronaut.glb&quot;
              ar
              auto-rotate camera-controls
              alt=&quot;A 3D model of an astronaut&quot;&gt;
&lt;/model-viewer&gt;</code></pre><p>3) 카메라 각도 조절기능</p>
<pre><code>&lt;model-viewer src=&quot;third_party/Astronaut/Astronaut.glb&quot;
              ar
              auto-rotate camera-controls
              camera-orbit=&quot;-20deg 75deg 2m&quot;
              alt=&quot;A 3D model of an astronaut&quot;&gt;
&lt;/model-viewer&gt;</code></pre><p>다음과 같이 여러 기능들을 추가해서 다양하고 재밌게 표현해 볼 수 있다.</p>
<p>오픈소스를 사용해보면서,</p>
<p>1) 이전에 알지 못했던 새로운 기능을 알아가는 것이 재미있다.
2) 각 오픈소스에 맞는 환경을 만들어 주기위해서 스스로 알아가야 하는 부분들이 있다.
3) 오픈소스들을 서로 공유하면서 발전도 많이 될 것 같다.</p>
<p>기회가 된다면 다음에도 오픈소스를 활용하여 여러 재미있는 프로젝트를 도전해보고 싶다!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[SpringBoot] Heroku에 프로젝트 올리는 방법]]></title>
            <link>https://velog.io/@surusuu_/SpringBoot-Heroku%EC%97%90-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EC%98%AC%EB%A6%AC%EB%8A%94-%EB%B0%A9%EB%B2%95</link>
            <guid>https://velog.io/@surusuu_/SpringBoot-Heroku%EC%97%90-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EC%98%AC%EB%A6%AC%EB%8A%94-%EB%B0%A9%EB%B2%95</guid>
            <pubDate>Tue, 24 May 2022 04:08:23 GMT</pubDate>
            <description><![CDATA[<h3 id="1-pomxml에--build-안에--plugins-안에-아래-코드-넣어주고">1. pom.xml에 &lt; build &gt;안에, &lt; plugins &gt;안에 아래 코드 넣어주고</h3>
<pre><code>    &lt;plugin&gt;
        &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
        &lt;artifactId&gt;maven-compiler-plugin&lt;/artifactId&gt;
        &lt;version&gt;3.5.1&lt;/version&gt;
        &lt;configuration&gt;
            &lt;source&gt;1.8&lt;/source&gt;
            &lt;target&gt;1.8&lt;/target&gt;
        &lt;/configuration&gt;
    &lt;/plugin&gt;</code></pre><h3 id="2-터미널-열어서">2. 터미널 열어서</h3>
<p>(1)  heroku -v 로 헤로쿠 설치 되어있는지 확인
(2) heroku login 로 헤로쿠 로그인
(3) cd (경로) 로 스프링부트 프로젝트로 이동(프로젝트 이름이 demo이면 demo dir.까지 이동)
(4) git init
(5) git add .
(6) git commit -m &quot;남기고픈 메세지&quot;
(7) heroku create 를 하면 헤로쿠 앱 하나가 만들어짐
(8) git remote -v 로 생성된 헤로쿠 앱인지 확인
(9) git push heroku master
(10) heroku open 하면 새 창이 뜨면서 연결된 것을 확인</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[직방 분석] 경쟁제품과의 장단점 비교]]></title>
            <link>https://velog.io/@surusuu_/%EC%A7%81%EB%B0%A9-%EB%B6%84%EC%84%9D-%EA%B2%BD%EC%9F%81%EC%A0%9C%ED%92%88%EA%B3%BC%EC%9D%98-%EC%9E%A5%EB%8B%A8%EC%A0%90-%EB%B9%84%EA%B5%90</link>
            <guid>https://velog.io/@surusuu_/%EC%A7%81%EB%B0%A9-%EB%B6%84%EC%84%9D-%EA%B2%BD%EC%9F%81%EC%A0%9C%ED%92%88%EA%B3%BC%EC%9D%98-%EC%9E%A5%EB%8B%A8%EC%A0%90-%EB%B9%84%EA%B5%90</guid>
            <pubDate>Tue, 24 May 2022 04:07:37 GMT</pubDate>
            <description><![CDATA[<p><img src="https://images.velog.io/images/surusu/post/3bf2f830-f5ad-4b9b-9f0d-7a8f5a27e318/%E1%84%8C%E1%85%B5%E1%86%A8%E1%84%87%E1%85%A1%E1%86%BCvs%E1%84%83%E1%85%A1%E1%84%87%E1%85%A1%E1%86%BC.jpg" alt=""></p>
<p>이번 포스트는 직방의 경쟁제품인 다방과 장단점을 다양한 측면으로 비교하여 더 상세하게 분석해 볼 것이다.</p>
<hr>
<h2 id="1-사용자-측면">1. 사용자 측면</h2>
<blockquote>
<p>1-1. 기본 정보
1-2. 사용자 평가</p>
</blockquote>
<h3 id="1-1-기본-정보">1-1. 기본 정보</h3>
<blockquote>
<p><img src="https://images.velog.io/images/surusu/post/89ee9a1b-cce1-40ad-ac06-4ef1ab1971d1/jikbang.jpg" alt="">
직방은 <strong>주식회사 직방에서 자체적으로 개발하고 2012년 1월부터 서비스를 시작한 대한민국의 최초 애플리케이션 서비스</strong>이다. 2017년 4월 경에 2000만 다운로드를 돌파하고 점유율도 59%를 기록하였다. 사용자가 공시가격, 위치, 매물의 양을 파악할 수 있고 <strong>처음 사용하는 사용자가 쉽게 사용할 수 있는 UI 디자인을 보유</strong>하고 있다. 2019년 6월 경에는 골드만삭스PIA와 아알토스벤처스, 스톤브릿지캐피탈, DS자산운용 등 다수의 투자자로부터 약 1600억원의 투자를 유치하였고, 호갱노노, 우주 등 부동산 관련 업체들을 인수하면서 <strong>빅데이터 기반 부동산 시장을 개편을 목표</strong>로 하고 있다.</p>
</blockquote>
<blockquote>
<p><img src="https://images.velog.io/images/surusu/post/b4d260f0-89cd-4dc7-81d0-591b5af6ded6/%E1%84%83%E1%85%A1%E1%84%87%E1%85%A1%E1%86%BC.jpg" alt="">
다방은 Station3에서 개발하고 2013년 7월부터 서비스를 시작하였으며 <strong>현재 최대 매물을 보유하고 있는 부동산 어플리케이션으로 성장</strong>하였다. 초반에는 임대 중심 중개 위주의 서비스를 제공하였지만 현재는 신축 분양 정보 서비스까지 제공하고 있으며 1~2인 가구를 집중 공략하여 해당 매물을 다량으로 보유하여 1인 가구의 비중이 증가하고 있는 현재 시점에서 다방의 성장도 비약적으로 증가하는 추세이다. 다방이 보유하고 있는 누적 매물은 약 50만 개로 초반 매물 수가 900여 개였던 점을 감안하면 매물량이 554% 가량 증가한 셈이다. <strong>분양 정보관, 청약 가점 계산 서비스 등 사용자의 요구, 편의에 맞추어서 서비스를 지속적으로 개편 중</strong>이다.</p>
</blockquote>
<h3 id="1-2-사용자-평가">1-2. 사용자 평가</h3>
<blockquote>
<p><strong>애플스토어 리뷰</strong>
<img src="https://images.velog.io/images/surusu/post/cf46a24d-3152-44e8-9b33-3ea69be9d42b/%E1%84%80%E1%85%B3%E1%84%85%E1%85%B5%E1%86%B71.png" alt=""></p>
</blockquote>
<ul>
<li><strong>직방</strong>
직방은 총 2709개의 평가와 총점 2.6점을 기록하고 있다. 애플스토어 기준 평가의 수가 <strong>다방의 10배 이상을 기록</strong>하고 있는데, 상대적으로 먼저 서비스를 시작하였고 이로 인한 높은 인지도의 영향을 받은 것으로 보인다. 하지만 평가 내용은 좋지 못한 편이다. 허위 매물에 대한 대처 부족과 사용자가 원하는 옵션을 편리하게 검색할 수 있도록 도와주는 기능의 부족이 원인이다. </li>
<li><strong>다방</strong>
다방은 총 225개의 평가와 총점  2.9점을 기록하고 있다. <strong>직방과 비교하였을 때 현저히 떨어지는 수</strong>이다. 평가의 내용은 준수한 편이다. 이로 미루어 보아 다방은 늦게 서비스를 시작하고 초반에 난항을 겪었으나 최근에 다양한 부동산 업체들과의 협업으로 사용자 측면 서비스가 대폭 개선된 것같다. 그러나 직방과 마찬가지로 허위 매물 대처에 대한 불만은 존재하는 것으로 보인다.</li>
</ul>
<hr>
<h2 id="2-uiux-측면">2. UI/UX 측면</h2>
<blockquote>
<p>2-1. 시작 화면
2-2. 지도 설정
2-3. 맞춤 필터
2-4. 추가 기능</p>
</blockquote>
<h3 id="2-1-시작-화면">2-1. 시작 화면</h3>
<blockquote>
<p><img src="https://images.velog.io/images/surusu/post/feb40561-4ace-42f8-836b-c115db1a1f30/%E1%84%80%E1%85%B3%E1%84%85%E1%85%B5%E1%86%B71.png" alt=""></p>
</blockquote>
<ul>
<li><strong>직방</strong>
앱의 첫 시작화면에 큰 카테고리를 가진 아이콘들을 두어, <strong>앱을 처음 접하는 사용자들도 원하는 매매의 종류를 빠르게 바로 찾을 수 있게 구성</strong>하였다.</li>
<li><strong>다방</strong>
검색창에 검색형식을 파란 글씨로 예시를 보여주어 사용자들이 원하는 지역의 매매종류를 검색하도록 하였다. <strong>처음 접하는 사용자들의 입장으로 볼 때, 직방보다 다소 검색하는 데 시간이 걸릴 것으로 예상</strong>된다.</li>
</ul>
<h3 id="2-2-지도-설정">2-2. 지도 설정</h3>
<blockquote>
<p><img src="https://images.velog.io/images/surusu/post/57b24e0e-878f-4a4c-8894-5d0246733ea5/%E1%84%80%E1%85%B3%E1%84%85%E1%85%B5%E1%86%B71.png" alt=""></p>
</blockquote>
<ul>
<li><strong>직방</strong>
지도에 지역별로 매물 개수를 숫자로만 표시함으로써 사용자가 매물 가능 개수를 한눈에 인식할 수 있게 하였다.
다방과 달리 지역명과 함께 표시가 되어 있지 않아서, 새로운 지역에서 집을 찾아야 하는 사람들은 <strong>구체적인 지역표시가 없는 직방의 매물표시로 인하여 불편함을 겪을 것으로 예상</strong>된다.</li>
<li><strong>다방</strong></li>
<li><em>지도에 상세 지역명과 함께 매물 개수를 숫자로 표시하여, 사용자가 원하는 지역에서 쉽게 매물을 찾을 수 있게 하였다*</em>.
지역을 선택하면 지역크기를 색으로 칠하여 보기 편리하고, 해당지역을 확대했을 때 더 상세한 지역의 매물 개수를 표시해 두어 사용자가 정확하게 자신이 원하는 지역에 있는 매물을 찾을 수 있게 하였다.</li>
</ul>
<h3 id="2-3-맞춤-필터">2-3. 맞춤 필터</h3>
<blockquote>
<p><img src="https://images.velog.io/images/surusu/post/1e4f1ec5-c95a-4cde-a909-f8b681689e83/%E1%84%80%E1%85%B3%E1%84%85%E1%85%B5%E1%86%B71.png" alt=""></p>
</blockquote>
<ul>
<li><strong>직방</strong>
사용자들의 경험을 더 풍부하게 하기 위해 다양한 맞춤필터 설정기능을 제공하나, 다방에 비해 <strong>맞춤필터 기능이 상세하지 않아</strong> <strong>사용자들의 경험을 극대화하기엔 다소 부족</strong>하다.</li>
<li><strong>다방</strong>
다방도 다양한 맞춤필터 설정기능을 제공하고 <strong>추가필터 기능도 제공</strong>하여 <strong>사용자들의 경험을 극대화</strong>하였다.
전세자금대출여부를 설정, 거래종류 설정 등 세부적인 설정도 가능하게 하여 사용자의 검색에 대한 편의를 높였다.</li>
</ul>
<h3 id="2-4-추가-기능">2-4. 추가 기능</h3>
<blockquote>
<p><strong>위치 및 주변 시설에 대한 정보</strong>
<img src="https://images.velog.io/images/surusu/post/5490662e-7486-4d05-9167-8c75f9fd6047/%E1%84%80%E1%85%B3%E1%84%85%E1%85%B5%E1%86%B71.png" alt=""></p>
</blockquote>
<ul>
<li><strong>직방</strong>
아파트 매물정보에 ‘현장투어’기능을 추가하여 <strong>VR을 통해</strong> 만들어 사용자들이 현장에 직접 가지 않고도 영상을 보면서 <strong>주변시설을 보다 현장감있게 확인</strong>할 수 있다.</li>
<li><strong>다방</strong>
아파트 매물정보에 구글의 지도 API를 통해 제공되는 <strong>로드뷰를 추가</strong>하였다. 직방이 사용하고 있는 VR 기능과 비교하였을 때, <strong>사용자들이 현장확인</strong>을 하기에는 시야각이나 도로 상황과 같은 부분에서 <strong>부족함</strong>이 있다.</li>
</ul>
<hr>
<h2 id="3-개발자-측면">3. 개발자 측면</h2>
<blockquote>
<p>3-1. 사이트맵 및 주요 기능
3-2. 데이터베이스 분석
3-3. 출시 플랫폼</p>
</blockquote>
<h3 id="3-1-사이트맵-및-주요-기능">3-1. 사이트맵 및 주요 기능</h3>
<p><img src="https://images.velog.io/images/surusu/post/92354576-a196-485d-a17f-0fa38f4ef9a9/%E1%84%80%E1%85%B3%E1%84%85%E1%85%B5%E1%86%B71.png" alt="">
사이트맵이 어떻게 구성되어 있는지 분석하여 이를 통해 어떠한 기능들을 지원하는지 조사해 보았다. 위의 사진은 각 어플리케이션의 메인 인터페이스이다.</p>
<blockquote>
<ul>
<li><strong>직방</strong>
홈 화면<blockquote>
<ul>
<li>아파트<blockquote>
<p>매매/전세, 매매/월세
신축 분양
인구 흐름
우리집 내놓기
최신 뉴스
관심 아파트
헛걸음 보상 신청</p>
</blockquote>
</li>
<li>빌라, 투룸+<blockquote>
<p>지도로 빌라 찾기
지하철역으로 찾기
중개사무소에 집 내놓기
최근 본 빌라
최근 본 신축 빌라
찜한 빌라
헛걸음 보상 신청
최신 뉴스</p>
</blockquote>
</li>
<li>원룸<blockquote>
<p>지도로 방 찾기
지하철역으로 찾기
중개사무소에 집 내놓기
최근 본 방
찜한 방
헛걸음 보상 신청
최신 뉴스</p>
</blockquote>
</li>
<li>오피스텔<blockquote>
<p>원룸과 동일</p>
</blockquote>
</li>
<li>상가, 점포 창업 및 사무실 이사<blockquote>
<p>지도로 상가 찾기
업종으로 찾기
상가 내놓기
최근 본 상가
찜한 상가</p>
</blockquote>
</li>
<li>더 보기(각 항목 페이지에서 접근)<blockquote>
<p>개인 정보
최근 본 방
찜한 방
문의한 매물
중개사무소에 집 내놓기
헛걸음 보상 신청
등록번호 조회
문의하기
중개사무소 가입 신청</p>
</blockquote>
</li>
</ul>
</blockquote>
</li>
</ul>
</blockquote>
<blockquote>
<ul>
<li><strong>다방</strong>
홈 화면<blockquote>
<ul>
<li>검색<blockquote>
<p>관심지역 모든 방
분양 정보
추천 콘텐츠</p>
</blockquote>
</li>
<li>관심 목록<blockquote>
<p>최근 본 방
최근 본 단지
찜한 방
찜한 단지
문의한 방
연락한 부동산</p>
</blockquote>
</li>
<li>지도<blockquote>
<p>검색 필터
매물 표시된 지도
전체 방 및 중개사무소 정보</p>
</blockquote>
</li>
<li>분양<blockquote>
<p>분양정보 모두보기
분양 뉴스
분양 일정
테마 분양
분양 가이드</p>
</blockquote>
</li>
<li>더보기<blockquote>
<ul>
<li>회원 정보<blockquote>
<p>기본정보
알림
방 내놓기
내가 쓴 리뷰
연락한 부동산</p>
</blockquote>
</li>
<li>매물번호 조회</li>
<li>자주 묻는 질문</li>
<li>이벤트</li>
<li>공지사항</li>
<li>1:1 문의</li>
<li>이용약관, 개인정보처리방침</li>
</ul>
</blockquote>
</li>
</ul>
</blockquote>
</li>
</ul>
</blockquote>
<h3 id="3-2-데이터-베이스-분석">3-2. 데이터 베이스 분석</h3>
<p>어플리케이션을 직접 사용해보면서 내부에서 직접 정보를 찾는 방식으로 분석하였다. 크게 회원에 대한 관리와 매물에 대한 관리로 나누어 데이터베이스를 분석해 보았다. 아래 내용은 필자가 어플리케이션에 직접적으로 보여지는 정보들과 추측을 토대로 분석한 것이므로 테이블 구성이나 정보 누락 등의 오류가 존재한다.</p>
<h4 id="3-2-1-회원관리">3-2-1. 회원관리</h4>
<p><img src="https://images.velog.io/images/surusu/post/bec78eab-23f1-4c9d-9720-2897cadfe588/%E1%84%80%E1%85%B3%E1%84%85%E1%85%B5%E1%86%B71.png" alt=""></p>
<blockquote>
<p><strong>회원관리</strong></p>
</blockquote>
<ul>
<li><strong>직방</strong><blockquote>
<blockquote>
<ul>
<li>이름, 비밀번호, 핸드폰, 이메일</li>
<li>최근 본 방, 찜한 방</li>
<li>문의한 매물</li>
<li>내놓은 매물(+)</li>
<li>알림</li>
</ul>
</blockquote>
</blockquote>
</li>
<li><strong>다방</strong><blockquote>
<blockquote>
<ul>
<li>이름, 핸드폰, 이메일, 사진</li>
<li>최근 본 방, 지역</li>
<li>찜한 방, 지역</li>
<li>문의한 방, 연락한 부동산</li>
<li>내놓은 매물(+)</li>
<li>리뷰(+), 알림</li>
</ul>
</blockquote>
</blockquote>
</li>
</ul>
<h4 id="3-2-2등록관리">3-2-2.등록관리</h4>
<p><img src="https://images.velog.io/images/surusu/post/aa8a0373-0b4f-4db2-b0eb-76636d93bcd6/%E1%84%80%E1%85%B3%E1%84%85%E1%85%B5%E1%86%B71.png" alt=""></p>
<blockquote>
<p><strong>등록관리</strong></p>
</blockquote>
<ul>
<li><strong>직방</strong><blockquote>
<blockquote>
<ul>
<li>매물 정보(등록번호, 사진, 주소, 층, 면적, 구조, 주차, 엘리베이터, 입주 가능일, 사진, 상세 설명)</li>
<li>가격 정보(거래 유형, 보증금, 관리비, 가격)</li>
<li>옵션 정보(에어컨, 냉장고, 세탁기, 가스레인지, 침대, 옷장, 싱크대 등)</li>
<li>관리비 정보(수도세, 인터넷, 티비 등)</li>
<li>담당자 정보(전화번호, 설명, 관리 매물 목록)</li>
</ul>
</blockquote>
</blockquote>
</li>
<li><strong>다방</strong><blockquote>
<blockquote>
<ul>
<li>매물 정보(등록번호, 사진, 주소, 방종류, 층, 면적, 난방종류, 빌트인 여부, 엘리베이터, 반려동물, 베란다, 전세자금대출가능, 입주 가능일, 상세 설명)</li>
<li>가격정보(거래 유형, 보증금, 관리비, 주차, 단기임대, 가격)</li>
<li>옵션 정보(에어컨, 세탁기, 전자레인지, 전자도어락, 인덕션, 가스레인지, 냉장고, 신발장, 티비, 옷장 등)</li>
<li>보안/안전시설 정보(공동현관, CCTV, 인터폰 등)</li>
<li>관리비 정보(수도세, 인터넷, 티비, 청소비 등)</li>
<li>다방면 스코어(가격 점수, 관리비 점수, 옵션 점수, 편의시설 점수, 교통 점수)</li>
<li>담당자 정보(전화번호, 설명, 관리 매물 목록)</li>
</ul>
</blockquote>
</blockquote>
</li>
</ul>
<p>사소한 부분까지 세분화하여 비교하지 않는 이상 기본적으로 비슷한 정보들을 저장하고 있다. <strong>필자의 눈에 가장 중요한 차이점은 점수에 대한 정보</strong>인 듯 하다. <strong>다방은 각 매물마다 5가지 항목에 점수를 부여</strong>하여 그 정보를 저장한다. 이후 주변 지역 평균과 비교하여 그래프로 사용자에게 보여주어 소비에 도움을 준다.</p>
<h3 id="3-3-출시-플랫폼">3-3. 출시 플랫폼</h3>
<blockquote>
<ul>
<li>*<em>직방 *</em>
Android, IOS</li>
</ul>
</blockquote>
<ul>
<li><strong>다방</strong>
Android, IOS</li>
</ul>
<hr>
<h2 id="4-경영자-측면">4. 경영자 측면</h2>
<blockquote>
<p>4-1. 수익 비교
4-2. 사용량 비교
4-3. 설치 순위</p>
</blockquote>
<h3 id="4-1-수익비교">4-1. 수익비교</h3>
<blockquote>
<p><img src="https://images.velog.io/images/surusu/post/691f637a-7e72-4a6f-85a2-02422a3f7649/%E1%84%80%E1%85%B3%E1%84%85%E1%85%B5%E1%86%B71.png" alt=""></p>
</blockquote>
<ul>
<li><strong>직방</strong></li>
<li><em>직방의 매출*</em>은 2016년부터 2019년까지 이용자 증가에 따라 회원 중개사무소 수가 확대됨으로 <strong>꾸준한 상승세</strong>를 보인다.
그러나 2019년에는 영업이익에서 41억원의 적자를 보였다. 직방에서는 그 이유를 매출 확대보다 플랫폼으로써의 가치를 높이는 데 주력한 결과라고 한다. 직방은 <strong>앞으로 M&amp;A를 통해서 2022년까지 월간 활성 사용자 수 1200만명을 달성하여 플랫폼의 가치를 확대</strong>시키고자 한다.</li>
<li><strong>다방</strong></li>
<li><em>다방의 매출*</em>은 2017년까지 적자를 기록하다가 <strong>2018년부터 흑자를 기록</strong>하기 시작했다. 초반에는 다방 이용자들의 허위매물에 대한 불만이 많았으나 현재는 해당 문제가 개선되어 이용자의 증가와 누적 매물 조회 수도 증가하고 있다.
다방에서 <strong>앞으로 &#39;부동산 AI 분석&#39; 서비스를 개시하여 부동산 거래사고 제로에 도전</strong>한다고 한다.</li>
</ul>
<h3 id="4-2-사용량-비교">4-2. 사용량 비교</h3>
<blockquote>
<p><img src="https://images.velog.io/images/surusu/post/3dfc4ba7-ff3d-439f-a144-d49fe404bef4/%E1%84%80%E1%85%B3%E1%84%85%E1%85%B5%E1%86%B71.png" alt="">
위 데이터는 2020년 1월 기준이다.</p>
</blockquote>
<ul>
<li><strong>직방</strong>
앱 설치자 중 <strong>실제 사용자는 약 160만명</strong>이다.
설치자 중 약 <strong>42%가 실제 사용하는 것</strong>으로 보아 직방에 대한 사용자들의 신뢰도가 높은 것을 추측할 수 있다. 다방에 비해서 허위매물에 대한 불만 접수가 많음에도 불구하고 위와 같은 데이터를 보이는 이유는 대한민국에 <strong>처음 출시된 부동산 어플리케이션이기에 그동안 쌓아 온 인지도 때문</strong>으로 생각된다.</li>
<li><strong>다방</strong>
앱 설치자 중 <strong>실제 사용자는 약 65만명</strong>으로 직방보다 적다.
설치자 중 약 <strong>35%가 실제 사용중</strong>이며 직방에 비해 다방에 대한 사용자들의 신뢰도가 낮은 것을 알 수 있다. 하지만** 최근 다방의 추세로 미루어 보면 현재보다 신뢰도와 실 사용자 비율 면에서 크게 성장할 것으로 추측**된다.</li>
</ul>
<h3 id="4-3-설치-순위비교">4-3. 설치 순위비교</h3>
<blockquote>
<p><img src="https://images.velog.io/images/surusu/post/2072a09a-9c51-4051-9e8e-64dc6ab3b7ad/%E1%84%80%E1%85%B3%E1%84%85%E1%85%B5%E1%86%B71.png" alt="">
위 데이터는 2020년 3월 기준이다.</p>
</blockquote>
<h2 id="부록">부록</h2>
<hr>
<h3 id="출처">출처</h3>
<p>한스경제_한국스포츠경제(<a href="http://www.sporbiz.co.kr">http://www.sporbiz.co.kr</a>)
Platum(<a href="https://platum.kr/archives/136162">https://platum.kr/archives/136162</a>)
여성소비자신문(<a href="http://www.wsobi.com/news/articleView.html?idxno=95570">http://www.wsobi.com/news/articleView.html?idxno=95570</a>)
ZDNetKorea(<a href="https://www.zdnet.co.kr/view/?no=20190919083356">https://www.zdnet.co.kr/view/?no=20190919083356</a>)
App Store</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[직방 분석] 소프트웨어 개선안]]></title>
            <link>https://velog.io/@surusuu_/%EC%A7%81%EB%B0%A9-%EB%B6%84%EC%84%9D-%EC%86%8C%ED%94%84%ED%8A%B8%EC%9B%A8%EC%96%B4-%EA%B0%9C%EC%84%A0%EC%95%88</link>
            <guid>https://velog.io/@surusuu_/%EC%A7%81%EB%B0%A9-%EB%B6%84%EC%84%9D-%EC%86%8C%ED%94%84%ED%8A%B8%EC%9B%A8%EC%96%B4-%EA%B0%9C%EC%84%A0%EC%95%88</guid>
            <pubDate>Tue, 24 May 2022 04:06:58 GMT</pubDate>
            <description><![CDATA[<p><img src="https://images.velog.io/images/surusu/post/e9711292-923f-4bdf-9402-cfebee583031/jikbang.jpg" alt=""></p>
<p>이번 포스트에서는 직방의 문제점 3가지를 분석하고 그에 대한 개선안 3가지를 제시한다. 마지막으로 직방의 가치를 높일 추가적인 아이디어 3가지를 제시하려 한다.</p>
<hr>
<h2 id="1-직방-문제점-3가지">1. 직방 문제점 3가지</h2>
<blockquote>
<p>1-1. 지하철 역으로 찾기 기능의 문제점
1-2. 5개로 나누어진 메인 UI의 문제점
1-3. 개인 페이지의 구조적 문제점과 기능적 문제점</p>
</blockquote>
<h3 id="1-1-지하철-역으로-찾기-기능의-문제점">1-1. 지하철 역으로 찾기 기능의 문제점</h3>
<p><img src="https://images.velog.io/images/surusu/post/b95d30ed-05e5-4de3-bb36-8ffedab8f1c6/%E1%84%80%E1%85%B3%E1%84%85%E1%85%B5%E1%86%B71.png" alt=""></p>
<ul>
<li>‘지도로 찾기’ 기능을 통해 매물을 찾을 시 지도 내에서 지역, 지하철 역으로 검색할 수 있는 기능이 이미 존재함</li>
</ul>
<p><img src="https://images.velog.io/images/surusu/post/e76201c0-d433-483a-b144-526045c88882/%E1%84%80%E1%85%B3%E1%84%85%E1%85%B5%E1%86%B72.png" alt=""></p>
<ul>
<li>‘지하철역 찾기’로 들어가게 되면 지하철역을 검색하고 도보 5, 10, 15분거리로 나누어서 검색하여 매물을 검색하도록 구현해 놓음</li>
<li>검색된 매물은 지도가 아닌 리스트 형식으로 나열되어 있음. 지도를 확인하고 싶으면 상세정보로 들어가야 함</li>
<li>즉, ‘지도로 찾기’ 기능에서 지하철역을 검색하여 매물을 확인하는 것이 위치 파악 측면에서 더 효과적이고 편리한 것으로 보임</li>
</ul>
<h3 id="1-2-5개로-나누어진-메인-ui의-문제점">1-2. 5개로 나누어진 메인 UI의 문제점</h3>
<p><img src="https://images.velog.io/images/surusu/post/84534a3c-66f0-4742-b967-017c9aa64fd7/%E1%84%80%E1%85%B3%E1%84%85%E1%85%B5%E1%86%B73.png" alt=""></p>
<ul>
<li>메인 페이지는 아파트, 빌라 및 투룸, 원룸, 오피스텔, 상가 및 점포까지 5개의 카테고리로 나누어져 있고 카테고리 별로 별도의 페이지가 존재함</li>
<li>소비자의 입장에서 예를 들어 원룸과 투룸 사이에서 고민하고 있는 상황이 있을 수 있는데 두 가지를 함께 검색하고 싶으면 ‘메인 &gt; 투룸 &gt; 메인 &gt; 원룸’과 같은 경로로 페이지를 이동해야 하므로 불편함</li>
<li>또한 각 카테고리 페이지에 있는 헛걸음 보상 신청이나 최신 뉴스 정보는 아파트와 상가 및 점포를 제외한 모든 카테고리가 동일하기 때문에 데이터 표현에 있어서 경제성이 떨어짐</li>
</ul>
<h3 id="1-3-개인-페이지의-구조적-문제점과-기능적-문제점">1-3. 개인 페이지의 구조적 문제점과 기능적 문제점</h3>
<p><img src="https://images.velog.io/images/surusu/post/ab54a04e-ee99-40a6-826b-e6c191cb6d54/%E1%84%80%E1%85%B3%E1%84%85%E1%85%B5%E1%86%B74.png" alt=""></p>
<ul>
<li>개인 페이지에 접근하려면 카테고리 중 하나를 선택하여 해당 페이지에 접근 후 개인정보를 확인할 수 있음</li>
<li>확인할 수 있는 정보들이 카테고리에 따라 다른 정보들(최근 본 방, 찜한 방 등)과 모든 카테고리에서 중복되는 정보들로 뒤섞여 있음</li>
<li>공지사항이나 사람들이 자주하는 질문들을 확인할 수 없고 개인 문의만 가능</li>
<li>리뷰와 같이 사용자들이 평가에 참여할 수 있는 기능이 부족</li>
</ul>
<hr>
<h2 id="2-직방-개선안-3가지">2. 직방 개선안 3가지</h2>
<blockquote>
<p>2-1. 지하철 역으로 찾기 기능의 문제점에 대한 개선안
2-2. 5개로 나누어진 메인 UI의 문제점에 대한 개선안
2-3. 개인 페이지의 구조적 문제점과 기능적 문제점에 대한 개선안</p>
</blockquote>
<h3 id="2-1-지하철-역으로-찾기-기능의-문제점에-대한-개선안">2-1. 지하철 역으로 찾기 기능의 문제점에 대한 개선안</h3>
<p><img src="https://images.velog.io/images/surusu/post/e70c4715-3585-491e-b03d-ced568eea6c1/%E1%84%80%E1%85%B3%E1%84%85%E1%85%B5%E1%86%B75.png" alt=""></p>
<ul>
<li>지하철 역으로 찾기 기능의 문제점은 지도 상 표시가 아닌 사진과 텍스트를 포함한 리스트 형태로 매물을 보여주기 때문에 위치 비교가 어렵다는 것</li>
<li>그에 대한 개선안으로 위와 같이 사진과 텍스트를 나열하되 나열 순서에 대한 기준을 제공하는 것을 생각함</li>
<li>지하철 역과 가까운 순서대로 매물들을 나열하면 지도가 없어도 상대적인 거리를 대략적으로 파악할 수 있기 때문에 효과적인 방법이다.</li>
<li>최근에 올라온 매물, 혹은 평가가 좋은 매물 순서대로 나열할 수 있도록 기능을 추가하여 사용자가 나열 순서를 선택하게 하는 방향도 고려해볼 수 있다.</li>
</ul>
<h3 id="2-2-5개로-나누어진-메인-ui의-문제점에-대한-개선안">2-2. 5개로 나누어진 메인 UI의 문제점에 대한 개선안</h3>
<p><img src="https://images.velog.io/images/surusu/post/66c6cf34-9159-404a-aa1b-643db938662a/%E1%84%80%E1%85%B3%E1%84%85%E1%85%B5%E1%86%B78.png" alt=""></p>
<ul>
<li>매물의 종류(카테고리)를 메인 페이지에서 가장 먼저 선택하도록 구성하게 되면 불필요한 페이지 이동이 잦아지며 필요한 페이지에 직접 접근하기가 어려워진다.</li>
<li>각 카테고리를 살펴보면 아파트의 경우 매매와 신축분양 두 가지가 주요 기능이고 나머지 카테고리는 지도 검색, 지하철 검색이 주요 기능이다.</li>
<li>따라서 아파트만 따로 분리시키고 지도 검색, 지하철 검색 등의 기능들을 메인 UI에서 바로 접근이 가능하도록 개선하고자 한다.</li>
<li>또한 자주 중복되는 기능들인 최신 뉴스나 헛걸음 보상 신청과 같은 기능들을 한 페이지에 모아 이 페이지 역시 메인 UI에서 바로 접근이 가능하도록 개선하고자 한다.</li>
<li>위와 같이 개선을 진행하게 되면 사용자가 여러 종류의 매물을 보다 쉽게 비교할 수 있고 찾고자 하는 기능을 보다 쉽게 찾을 수 있을 것이다.</li>
</ul>
<h3 id="2-3-개인-페이지의-구조적-문제점과-기능적-문제점에-대한-개선안">2-3. 개인 페이지의 구조적 문제점과 기능적 문제점에 대한 개선안</h3>
<p><img src="https://images.velog.io/images/surusu/post/d767da0e-9e05-4f3c-87eb-4e5fcb803022/%E1%84%80%E1%85%B3%E1%84%85%E1%85%B5%E1%86%B79.png" alt=""></p>
<ul>
<li>앞서 언급한 내용에 따르면 메인 UI에서 접근할 수 있는 페이지는 총 5개이다. 이 중에 개인 페이지는 포함되지 않는다.</li>
<li>하지만 개인 페이지는 사용자들에게 많은 편의(최근 본 매물, 찜한 매물, 문의사항 등)를 제공할 수 있기 때문에 사용자의 접근이 잦을 것으로 예상된다.</li>
<li>따라서 앞서 언급했던 메인 UI 개선 시, 개인 페이지도 바로 접근할 수 있는 방향으로 개선하고자 한다.</li>
<li>공지 사항이나 사람들이 자주 질문했던 질문들을 모아서 보여주는 페이지도 개인 페이지에 추가되어야 한다고 생각한다. 기존 문의하기 기능은 문의를 보내면 입력한 메일로 답신을 받는 구조로 되어 있는데 위와 같은 페이지를 만들면 문의 사항에 대해 빠르게 답변을 받을 수 있고 불필요한 중복 문의를 줄일 수 있을 것이다.</li>
<li>개인 페이지에 사용자들이 거래한 매물이나 공인중개사에 대한 평가를 점수화 하는 기능을 추가하고자 한다. 이를 통해 사용자들이 거래를 할 때 선택에 도움이 될 것으로 예상된다. (다방 어플의 다방면 스코어 예시)</li>
</ul>
<hr>
<h2 id="3-직방-추가-아이디어-3가지">3. 직방 추가 아이디어 3가지</h2>
<blockquote>
<p>3-1. 공인중개사에 대한 리뷰서비스
3-2. 쉐어하우스,고시원,하숙집 중개서비스
3-3. 룸메이트/하우스메이트를 찾는 커뮤니티 형성</p>
</blockquote>
<h3 id="3-1-공인중개사에-대한-리뷰서비스">3-1. 공인중개사에 대한 리뷰서비스</h3>
<p><img src="https://images.velog.io/images/surusu/post/3dd2a706-54f1-4f19-b9c9-6835df4b9127/%E1%84%80%E1%85%B3%E1%84%85%E1%85%B5%E1%86%B710.png" alt=""></p>
<ul>
<li>직방의 단점이 허위매물이 많은 것이다. 그래서 공인중개사에 대한 리뷰란을 생성하면, 해당 공인중개사에 대한 리뷰를 본 사용자들이 조금 더 안심하고 매물계약을 체결할 수 있을 것이다.</li>
</ul>
<h3 id="3-2-쉐어하우스고시원하숙집-중개서비스">3-2. 쉐어하우스,고시원,하숙집 중개서비스</h3>
<p><img src="https://images.velog.io/images/surusu/post/17d5fd08-59f2-48f3-9f58-b3f2927796fe/%E1%84%80%E1%85%B3%E1%84%85%E1%85%B5%E1%86%B712.png" alt=""></p>
<ul>
<li>타어플(피터팬의 좋은 방 구하기)에 의하면, 쉐어하우스, 고시원,하숙집 중개서비스를 할 수 있는 커뮤니티가 존재한다. 요즘 젊은이들은 원룸을 찾기보다 간단하게 이러한 곳에 머물고 싶어하는 사람들도 많기 때문에, 이런 장을 직방에서도 형성해 준다면 더 많은 사람들에게 사랑받을 수 있을 것이다.</li>
</ul>
<h3 id="3-3-룸메이트하우스메이트를-찾는-커뮤니티-형성">3-3. 룸메이트/하우스메이트를 찾는 커뮤니티 형성</h3>
<p><img src="https://images.velog.io/images/surusu/post/cd8d575c-7131-4ab5-aa67-ff538b7fc089/%E1%84%80%E1%85%B3%E1%84%85%E1%85%B5%E1%86%B713.png" alt=""></p>
<ul>
<li>타어플(피터팬의 좋은 방 구하기)에 의하면, 룸메이트/하우스메이트를 찾은 커뮤니티가 형성되어 있다. 현재도 오픈채팅방을 통해서 모르는 사람들과 서로 방을 양도하는 것과 같이, 직방앱내에서도 여자/남자란을 구분해주어 그 안에서 서로 방을 양도하거나,룸메이트/하우스메이트를 찾는 커뮤니티 장을 형성해주면 사용자들이 훨신 더 편리함을 느낄 것이다. 추가적으로 실명인증제 등을 도입하여 서로에 대한 사실확인도 필요할 것으로 예상된다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[직방 분석] 소프트웨어 선택배경과 특징]]></title>
            <link>https://velog.io/@surusuu_/%EC%A7%81%EB%B0%A9-%EB%B6%84%EC%84%9D-%EC%86%8C%ED%94%84%ED%8A%B8%EC%9B%A8%EC%96%B4-%EC%84%A0%ED%83%9D%EB%B0%B0%EA%B2%BD%EA%B3%BC-%ED%8A%B9%EC%A7%95</link>
            <guid>https://velog.io/@surusuu_/%EC%A7%81%EB%B0%A9-%EB%B6%84%EC%84%9D-%EC%86%8C%ED%94%84%ED%8A%B8%EC%9B%A8%EC%96%B4-%EC%84%A0%ED%83%9D%EB%B0%B0%EA%B2%BD%EA%B3%BC-%ED%8A%B9%EC%A7%95</guid>
            <pubDate>Tue, 24 May 2022 04:06:33 GMT</pubDate>
            <description><![CDATA[<p><img src="https://images.velog.io/images/surusu/post/17c0a2ba-ae36-43fb-8d0b-f47f4489e783/jikbang.jpg" alt=""></p>
<p>이번 포스트는 직방분석을 선택하게 된 배경과 그 특징에 대해 소개하고자 한다.</p>
<hr>
<h2 id="1-소프트웨어-선택배경">1. 소프트웨어 선택배경</h2>
<p>직방은 국내 1세대 프롭테크 기업이자, 온라인 부동산 플랫폼 시작에서 1위를 달리고 있다. 
그래서 직방이 어떤 특징으로 소비자의 마음을 사로잡았는지에 대해 궁금하여 직방분석을 선택하게 되었다. 
( * 프롭테크는 Property+Technology의 약자로서 부동산 서비스 산업을 말한다. )</p>
<hr>
<h2 id="2-소프트웨어-특징">2. 소프트웨어 특징</h2>
<blockquote>
<p>2-1. 간편한 회원가입
2-2. 국내 최대 규모
2-3. 매물 검색
2-4. 편의를 위한 부가기능
2-5. 기타 제공되는 서비스</p>
</blockquote>
<h3 id="2-1-간편한-회원가입">2-1. 간편한 회원가입</h3>
<p>회원가입 절차가 별도로 존재하지 않고 카카오톡에 존재하는 회원 정보로 가입이 가능</p>
<h3 id="2-2-국내-최대-규모">2-2. 국내 최대 규모</h3>
<p>전국 공인중개사무소 5000여 곳과 제휴하고 있고, 해당 어플리케이션의 누적 다운로드 건수는 420만건</p>
<h3 id="2-3-매물-검색">2-3. 매물 검색</h3>
<ul>
<li>아파트/ 빌라, 투룸+ / 원룸 / 오피스텔 / 상가, 점포 등 카테고리 별로 나누어져 있어 처음 어플리케이션을 사용하는 사람도 원하는 정보를 쉽게 찾을 수 있음</li>
<li>사용자가 요구하는 정보에 대한 맞춤 필터(보증금,월세,구조 등)를 사용하여 검색에 소요되는 시간을 줄임</li>
<li>지도, 지하철 역을 통해서 빠른 위치 파악을 도움</li>
</ul>
<h3 id="2-4-편의를-위한-부가기능">2-4. 편의를 위한 부가기능</h3>
<ul>
<li>주변 시설이나 현장을 좀 더 현실에 가깝게 확인할 수 있도록 VR기능을 제공</li>
<li>찜 기능을 사용하여, 이후에 찜한 매물을 쉽게 찾고 열람할 수 있도록 도움</li>
<li>집 내놓기 기능을 통하여 모든 중개사에 한 번에 매물을 내놓을 수 있음</li>
<li>실제 거주 경험이 있는 사용자들의 현실적인 후기를 통해 사용자의 선택을 돕고 안전성을 높임</li>
</ul>
<h3 id="2-5-기타-제공되는-서비스">2-5. 기타 제공되는 서비스</h3>
<ul>
<li>헛걸음 보상제도를 시행하여 허위매물을 발견시, 소정의 보상을 해주는 서비스 제공</li>
<li>해당 어플리케이션 사용자들 중 매월 8명에게 월세 지원금을 제공 해주는 월세 지원 제도를 시행</li>
<li>안심 중개사 5계명을 어기면 안심중개사 자격을 일정 기간 박탈함으로써 허위 매물에 대한 제재를 강화시키는 안심중개사 제도 시행</li>
</ul>
<h2 id="부록">부록</h2>
<hr>
<h3 id="출처">출처</h3>
<p><a href="https://brunch.co.kr/@andysik/61">https://brunch.co.kr/@andysik/61</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[백준/JAVA] 1260번]]></title>
            <link>https://velog.io/@surusuu_/%EB%B0%B1%EC%A4%80java-1260%EB%B2%88</link>
            <guid>https://velog.io/@surusuu_/%EB%B0%B1%EC%A4%80java-1260%EB%B2%88</guid>
            <pubDate>Tue, 24 May 2022 04:04:45 GMT</pubDate>
            <description><![CDATA[<h2 id="dfs와-bfs">DFS와 BFS</h2>
<p><a href="https://www.acmicpc.net/problem/1260">1260번으로 이동</a></p>
<p><img src="https://images.velog.io/images/surusu/post/c4a4497f-d1ae-48ff-b2a2-c73adf4094bd/image.png" alt=""></p>
<blockquote>
<p>DFS와 BFS를 구하기 위해</p>
</blockquote>
<ul>
<li>DFS: 깊이 우선 탐색 / BFS: 너비 우선 탐색 </li>
<li>그래프를 표현하기 위해서 인접행렬 graph[][] 사용</li>
<li>방문한 노드인지 확인하기 위해 check[] 사용</li>
<li>재귀함수를 사용해 DFS 구현</li>
<li>큐를 사용해 BFS 구현</li>
</ul>
<h4 id="코드-리뷰">코드 리뷰</h4>
<pre><code>import java.util.*;
import java.io.*;

public class Main {
  public static int N,M,V;
  public static int[][] graph;
  public static boolean[] check;

  public static void main(String[] args) throws Exception {

  Scanner sc = new Scanner(System.in);

  N = sc.nextInt();
  M = sc.nextInt();
  V = sc.nextInt();

  graph = new int[N+1][N+1];
  check = new boolean[N+1];

  for(int i=0; i&lt;M; i++){
    int x = sc.nextInt();
    int y = sc.nextInt();

    // 입력받은 간선들의 위치는 1로 fix해줌 
    graph[x][y] = 1;
    graph[y][x] = 1;
  }

  dfs(V);
  System.out.println();
  Arrays.fill(check,false);
  bfs(V);
  }

  public static void dfs(int start){
    //시작점은 방문되었으니 true로 변환
    check[start] = true;
    System.out.print(start + &quot; &quot;);

    for(int i=1; i&lt;N+1; i++){
      // 만약에 시작점과 연결된 곳이 1이고, check[i]가 false이면 아직 방문하지 않은 노드이므로 
      // dfs(i)로 불러주면, 그것과 연결된 점이 시작점이 되므로 dfs를 구현가능

      if(graph[start][i]==1 &amp;&amp; !check[i])
        dfs(i);
    }
  }

  public static void bfs(int start){
    Queue&lt;Integer&gt; q = new LinkedList&lt;&gt;();
    q.offer(start);
    check[start] = true;

    while(!q.isEmpty()){
      int vertex = q.poll();
      System.out.print(vertex + &quot; &quot;);

      for(int i=1; i&lt;N+1; i++){
        // 시작점과 연결된 노드가 1이고 Check[i]가 false이면, for문을 통해서 시작점과 연결된 모든 점들을 
        // 큐에 담고 check[i]는 True로 바꿔준다.

        if(graph[vertex][i]==1 &amp;&amp; !check[i]){
          q.offer(i);
          check[i] = true;
        }

      }

    } 

  }
}</code></pre><hr>
<h4 id="참고한-url">참고한 URL</h4>
<p><a href="https://leveloper.tistory.com/35">https://leveloper.tistory.com/35</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[백준/C] 9020번]]></title>
            <link>https://velog.io/@surusuu_/%EB%B0%B1%EC%A4%80C-9020%EB%B2%88</link>
            <guid>https://velog.io/@surusuu_/%EB%B0%B1%EC%A4%80C-9020%EB%B2%88</guid>
            <pubDate>Tue, 24 May 2022 04:04:18 GMT</pubDate>
            <description><![CDATA[<h3 id="q-문제">Q) 문제</h3>
<p>1보다 큰 자연수 중에서  1과 자기 자신을 제외한 약수가 없는 자연수를 소수라고 한다. 예를 들어, 5는 1과 5를 제외한 약수가 없기 때문에 소수이다. 하지만, 6은 6 = 2 × 3 이기 때문에 소수가 아니다.</p>
<p>골드바흐의 추측은 유명한 정수론의 미해결 문제로, 2보다 큰 모든 짝수는 두 소수의 합으로 나타낼 수 있다는 것이다. 이러한 수를 골드바흐 수라고 한다. 또, 짝수를 두 소수의 합으로 나타내는 표현을 그 수의 골드바흐 파티션이라고 한다. 예를 들면, 4 = 2 + 2, 6 = 3 + 3, 8 = 3 + 5, 10 = 5 + 5, 12 = 5 + 7, 14 = 3 + 11, 14 = 7 + 7이다. 10000보다 작거나 같은 모든 짝수 n에 대한 골드바흐 파티션은 존재한다.</p>
<p>2보다 큰 짝수 n이 주어졌을 때, n의 골드바흐 파티션을 출력하는 프로그램을 작성하시오. 만약 가능한 n의 골드바흐 파티션이 여러 가지인 경우에는 두 소수의 차이가 가장 작은 것을 출력한다.</p>
<ul>
<li><p>입력
첫째 줄에 테스트 케이스의 개수 T가 주어진다. 각 테스트 케이스는 한 줄로 이루어져 있고 짝수 n이 주어진다.</p>
</li>
<li><p>출력
각 테스트 케이스에 대해서 주어진 n의 골드바흐 파티션을 출력한다. 출력하는 소수는 작은 것부터 먼저 출력하며, 공백으로 구분한다.</p>
</li>
</ul>
<table>
<thead>
<tr>
<th>입력</th>
<th>출력</th>
</tr>
</thead>
<tbody><tr>
<td>3</td>
<td></td>
</tr>
<tr>
<td>8</td>
<td>3 5</td>
</tr>
<tr>
<td>10</td>
<td>5 5</td>
</tr>
<tr>
<td>16</td>
<td>5 11</td>
</tr>
</tbody></table>
<h3 id="a-알고리즘">A) 알고리즘</h3>
<blockquote>
<p>에스토테네스의 체 알고리즘을 사용해 입력받은 값의 소수들을 모두 구한 뒤, 입력받은 값의 절반부터 인덱스를 시작하여 늘려가면 차이가 적은 두 소수를 구할 수 있게 된다.</p>
</blockquote>
<p>예) N = 8일 경우</p>
<table>
<thead>
<tr>
<th>Index</th>
<th>소수 판별</th>
</tr>
</thead>
<tbody><tr>
<td>0</td>
<td>0</td>
</tr>
<tr>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>2</td>
<td>0</td>
</tr>
<tr>
<td>3</td>
<td>0</td>
</tr>
<tr>
<td>4</td>
<td>1</td>
</tr>
<tr>
<td>5</td>
<td>0</td>
</tr>
<tr>
<td>6</td>
<td>1</td>
</tr>
<tr>
<td>7</td>
<td>0</td>
</tr>
<tr>
<td>8</td>
<td>1</td>
</tr>
</tbody></table>
<p>index를 2/N부터 시작하여 소수 인지 아닌지를 판별해나간다.
(4,4)일 경우 1이기 때문에 넘어가고 (3,5)일 경우 모두 0으로 소수 이기 때문에 이것이 결과로 출력된다.</p>
<hr>
<ul>
<li>c언어<pre><code>#include &lt;stdio.h&gt;
</code></pre></li>
</ul>
<p>int main()
{
  int T;
  int N;
  int arr[20000] = {0,1};</p>
<p>  //테스트 케이스 갯수 입력받기
  scanf(&quot;%d&quot;, &amp;T);</p>
<p>  for(int l=0; l&lt;T; l++){
    scanf(&quot;%d&quot;, &amp;N);</p>
<pre><code>//N내의 소수들 구하기
for(int i=2; i&lt;=N; i++){
  for(int j=2; i*j&lt;=N; j++){
    arr[i*j]=1;
  }
}
//index를 N/2부터 시작
for(int m=N/2; m&gt;0; m--){
  if(arr[m]!=1 &amp;&amp; arr[N-m]!=1){
    printf(&quot;%d %d\n&quot;,m,N-m);
    break; 
  }
}</code></pre><p>  }</p>
<p>  return 0;
}
```</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[백준/C] 1929번]]></title>
            <link>https://velog.io/@surusuu_/%EB%B0%B1%EC%A4%80C-1929%EB%B2%88</link>
            <guid>https://velog.io/@surusuu_/%EB%B0%B1%EC%A4%80C-1929%EB%B2%88</guid>
            <pubDate>Tue, 24 May 2022 04:03:54 GMT</pubDate>
            <description><![CDATA[<h3 id="q-첫째-줄에-자연수-m과-n이-빈-칸을-사이에-두고-주어진다-1-≤-m-≤-n-≤-1000000-m이상-n이하의-소수가-하나-이상-있는-입력이-주어지고-그-사이의-소수를-한-줄씩-출력해라">Q) 첫째 줄에 자연수 M과 N이 빈 칸을 사이에 두고 주어진다. (1 ≤ M ≤ N ≤ 1,000,000) M이상 N이하의 소수가 하나 이상 있는 입력이 주어지고 그 사이의 소수를 한 줄씩 출력해라.</h3>
<table>
<thead>
<tr>
<th>입력</th>
<th>출력</th>
</tr>
</thead>
<tbody><tr>
<td>3 16</td>
<td>3</td>
</tr>
<tr>
<td></td>
<td>5</td>
</tr>
<tr>
<td></td>
<td>7</td>
</tr>
<tr>
<td></td>
<td>11</td>
</tr>
<tr>
<td></td>
<td>13</td>
</tr>
</tbody></table>
<h3 id="a-알고리즘">A) 알고리즘</h3>
<blockquote>
<p>[ 소수 구하는 최적의 알고리즘 ] </p>
</blockquote>
<ul>
<li><p>에라스토테네스의 체
2부터 소수를 구하고자 하는 모든 수를 나열한 뒤, 특정 수의 배수들을 제거해 나가는 알고리즘</p>
</li>
<li><p>c언어</p>
<pre><code>#include &quot;stdio.h&quot;
</code></pre></li>
</ul>
<p>int main()
{
  int M, N;
  //index로 소수 판별 - 소수면 0, 소수가 아니면 1 채우기
  //arr[1]=1로 채움
  int arr[1000001] = {0,1};
  scanf(&quot;%d %d&quot;, &amp;M, &amp;N);</p>
<p>  //N까지 i<em>j로 특정 수의 배수를 찾고 그 수는 1로 채움
  for(int i=2; i&lt;=N; i++){
    for(int j=2; i</em>j&lt;=N; j++){
      arr[i*j]=1;
    }
  } </p>
<p>  for(int k=M; k&lt;=N; k++){
    //값이 0인 위치만 출력
    if(!arr[k]){
      printf(&quot;%d\n&quot;,k);
    }
  }</p>
<p>  return 0;
}
```</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[백준/C] 4153번]]></title>
            <link>https://velog.io/@surusuu_/%EB%B0%B1%EC%A4%80C-4153%EB%B2%88-08a8ouxw</link>
            <guid>https://velog.io/@surusuu_/%EB%B0%B1%EC%A4%80C-4153%EB%B2%88-08a8ouxw</guid>
            <pubDate>Tue, 24 May 2022 04:01:50 GMT</pubDate>
            <description><![CDATA[<h3 id="q-과거-이집트인들은-각-변들의-길이가-3-4-5인-삼각형이-직각-삼각형인것을-알아냈다-주어진-세변의-길이로-삼각형이-직각인지-아닌지-구분하시오">Q) 과거 이집트인들은 각 변들의 길이가 3, 4, 5인 삼각형이 직각 삼각형인것을 알아냈다. 주어진 세변의 길이로 삼각형이 직각인지 아닌지 구분하시오.</h3>
<p>[ 예제 ]
입력은 여러개의 테스트케이스로 주어지며 마지막줄에는 0 0 0이 입력된다.
각 입력에 대해 직각 삼각형이 맞다면 &quot;right&quot;, 아니라면 &quot;wrong&quot;을 출력한다.</p>
<table>
<thead>
<tr>
<th>입력</th>
<th>출력</th>
</tr>
</thead>
<tbody><tr>
<td>6 8 10</td>
<td>right</td>
</tr>
<tr>
<td>25 52 60</td>
<td>wrong</td>
</tr>
<tr>
<td>5 12 13</td>
<td>right</td>
</tr>
<tr>
<td>0 0 0</td>
<td></td>
</tr>
</tbody></table>
<h3 id="a-알고리즘">A) 알고리즘</h3>
<blockquote>
<p>[ 직각삼각형 판단하는 공식 ]
가장 긴변^2 = 가장 짧은 변^2 + 나머지 변^2</p>
</blockquote>
<ul>
<li><p>c언어</p>
<pre><code>int n1, n2, n3;
while(1){
  int l1, l2, l3;  
  scanf(&quot;%d %d %d&quot;, &amp;n1, &amp;n2, &amp;n3); 
  if(n1 == 0 &amp;&amp; n2 == 0 &amp;&amp; n3 == 0) break; //세 수가 0일 때, 루프를 끝낼 수 있게 조건문 사용

  //각 변의 제곱을 미리 저장해 놈
  l1 = n1*n1; 
  l2 = n2*n2;
  l3 = n3*n3;

  if(l1==l2+l3 || l2==l1+l3 || l3==l1+l2){ //OR을 통하여 각 변에 대하여 판단함
    printf(&quot;right\n&quot;);
  }
  else{
    printf(&quot;wrong\n&quot;);
  }
} //무한루프 문을 통해 여러 줄을 입력받게 함
return 0;</code></pre></li>
</ul>
<blockquote>
<ul>
<li>comment
scanf 여러 줄 받는 것에 어려움을 겪음</li>
</ul>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[백준/C] 1085번]]></title>
            <link>https://velog.io/@surusuu_/%EB%B0%B1%EC%A4%80C-1085%EB%B2%88</link>
            <guid>https://velog.io/@surusuu_/%EB%B0%B1%EC%A4%80C-1085%EB%B2%88</guid>
            <pubDate>Tue, 24 May 2022 04:01:25 GMT</pubDate>
            <description><![CDATA[<h3 id="q-한수는-지금-x-y에-있다-직사각형의-왼쪽-아래-꼭짓점은-0-0에-있고-오른쪽-위-꼭짓점은-w-h에-있다-직사각형의-경계선까지-가는-거리의-최솟값을-구하는-프로그램을-작성하시오">Q) 한수는 지금 (x, y)에 있다. 직사각형의 왼쪽 아래 꼭짓점은 (0, 0)에 있고, 오른쪽 위 꼭짓점은 (w, h)에 있다. 직사각형의 경계선까지 가는 거리의 최솟값을 구하는 프로그램을 작성하시오.</h3>
<table>
<thead>
<tr>
<th>입력</th>
<th>출력</th>
</tr>
</thead>
<tbody><tr>
<td>6 2 10 3</td>
<td>1</td>
</tr>
</tbody></table>
<h3 id="a-알고리즘">A) 알고리즘</h3>
<blockquote>
<p>(x,y)에서 네변까지의 거리는 x, y, |w-x|, |h-y| 이다.
따라서 네 수를 배열에 넣은 후, 배열 내에서 가장 작은 수를 찾는 알고리즘을 통하여 결과값을 찾을 수 있다.</p>
</blockquote>
<ul>
<li>c에서 절댓값 구하는 함수: abs() </li>
</ul>
<blockquote>
<p>[ 배열 내에서 가장 작은 수를 찾는 알고리즘 ]</p>
</blockquote>
<ul>
<li>c언어 
int min = arr[0];
for(int i=0; i&lt;sizeof(arr)/sizeof(int); i++){
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(arr[i] &lt;= min)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;min = arr[i];
}</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[백준/C] 3009번]]></title>
            <link>https://velog.io/@surusuu_/%EB%B0%B1%EC%A4%80C-3009%EB%B2%88-v8dnw1w7</link>
            <guid>https://velog.io/@surusuu_/%EB%B0%B1%EC%A4%80C-3009%EB%B2%88-v8dnw1w7</guid>
            <pubDate>Tue, 24 May 2022 04:01:03 GMT</pubDate>
            <description><![CDATA[<h3 id="q-세-점이-주어졌을-때-축에-평행한-직사각형을-만들기-위해서-필요한-네-번째-점을-찾는-프로그램을-작성하시오">Q) 세 점이 주어졌을 때, 축에 평행한 직사각형을 만들기 위해서 필요한 네 번째 점을 찾는 프로그램을 작성하시오.</h3>
<table>
<thead>
<tr>
<th>입력</th>
<th>출력</th>
</tr>
</thead>
<tbody><tr>
<td>30 20</td>
<td>30 10</td>
</tr>
<tr>
<td>10 10</td>
<td></td>
</tr>
<tr>
<td>10 20</td>
<td></td>
</tr>
</tbody></table>
<h3 id="a-알고리즘">A) 알고리즘</h3>
<p>(x1, y1) (x2,y2) (x3,y3)가 있고 (x4,y4)를 구하고 싶을 때,</p>
<blockquote>
<p>if ( x1 = x2 ) 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&amp;nbsp{ x4 = x3 }
else if ( x1 = x3 ) 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&amp;nbsp{ x4 = x2 }
else { x4 = x1 }</p>
</blockquote>
<p>y4도 동일한 알고리즘으로 구현하면 됌!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[React] Redux / MobX]]></title>
            <link>https://velog.io/@surusuu_/React-Redux-MobX</link>
            <guid>https://velog.io/@surusuu_/React-Redux-MobX</guid>
            <pubDate>Tue, 24 May 2022 03:59:58 GMT</pubDate>
            <description><![CDATA[<h3 id="redux">&gt; Redux</h3>
<ol>
<li>상태 관리 코드를 분리할 수 있음</li>
<li>미들웨어를 활용한 다양한 기능 추가(ex.redux-saga)</li>
<li>SSR시 데이터 전달이 간편(SSR:server-side-Randering)</li>
<li>리액트 콘텍스트보다 효율적인 렌더링 가능</li>
</ol>
<ul>
<li><p>리덕스 사용 방법
상단에 import { createStore } from &#39;redux&#39;; / import { Provider, useSelector, useDispatch } from &#39;react-redux&#39;; 삽입</p>
</li>
<li><p>리덕스 구조
<img src="https://images.velog.io/images/surusu/post/0bdb6718-df2d-4083-8234-03cda3b4c2b3/image.png" alt="">
: 리듀서의 반환값은 새로운 상태값
: 간단하고 직관적인 구조</p>
</li>
<li><p>액션
: 액션크리에이터를 만들어서 사용
store.dispatch();
<img src="https://images.velog.io/images/surusu/post/d036e6b0-75a7-4524-b76a-496d996c2cfa/image.png" alt=""></p>
</li>
<li><p>미들웨어
<img src="https://images.velog.io/images/surusu/post/34577837-fd25-4de1-97d0-473ebdd9c561/image.png" alt="">
: 마지막 미들웨어에서 리듀서를 호출</p>
</li>
<li><p>리듀서
<img src="https://images.velog.io/images/surusu/post/068553aa-b940-4319-ba9b-d9faa8c7c1bc/image.png" alt=""></p>
</li>
<li><p>스토어
<img src="https://images.velog.io/images/surusu/post/3ed10bda-88c3-4d72-851f-ef98966ab890/image.png" alt=""></p>
</li>
</ul>
<p>=&gt; useSelector()
=&gt; useDispatch() - 거의 변하지는 않음</p>
<p>=&gt; reselect()</p>
<h3 id="mobx">&gt; MobX</h3>
<ol>
<li>객체지향 느낌</li>
<li>데코레이터(자바 어노테이션과 유사)제공하기 때문에 깔끔한 코드 생성</li>
<li>캡슐화: state를 메소드 통해서만 변경할 수 있도록 private하게 관리할 수 있음</li>
</ol>
<p><img src="https://images.velog.io/images/surusu/post/6b31c781-1c29-4b4f-a891-93a8c4649433/image.png" alt=""></p>
<ol>
<li>State: 어플리케이션의 데이터 상태</li>
<li>Derivations: 어플리케이션으로부터 자동으로 계산되는 모든 값.(파생 값)</li>
<li>Reaction: 값을 생성하지 않는 함수. I/O와 연관된 작업들. 적당할 때에 자동으로 DOM을 업데이트하게 해주고 네트워크 요청을 하도록 해줌</li>
<li>Action: action은 state를 변경하는 모든 것 </li>
</ol>
<ul>
<li><p>사용법
: mobx, mobx-react 라이브러리 설치
커멘드에 npm  i mobx mobx-react 입력</p>
</li>
<li><p>MobX기본 사용함수</p>
<pre><code>import React, {Component} from &#39;react&#39;;
import {decorate, observable, action, computed} from &#39;mobx&#39;;
import {observer} from &#39;mobx-react&#39;;</code></pre></li>
<li><p>Store구축
: obervable
object로 만들어주는 것 = state model을 만든 것</p>
</li>
</ul>
<hr/>

<h3 id="참고">&gt; 참고</h3>
<p><a href="https://medium.com/@jsh901220/mobx-%EC%B2%98%EC%9D%8C-%EC%8B%9C%EC%9E%91%ED%95%B4%EB%B3%B4%EA%B8%B0-a768f4aaa73e">https://medium.com/@jsh901220/mobx-%EC%B2%98%EC%9D%8C-%EC%8B%9C%EC%9E%91%ED%95%B4%EB%B3%B4%EA%B8%B0-a768f4aaa73e</a></p>
<p><a href="https://helloinyong.tistory.com/175">https://helloinyong.tistory.com/175</a></p>
<p><a href="https://www.howdy-mj.me/mobx/mobx6-intro/">https://www.howdy-mj.me/mobx/mobx6-intro/</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[React] 인프런강의(섹션4,5)]]></title>
            <link>https://velog.io/@surusuu_/React%EC%9D%B8%ED%94%84%EB%9F%B0%EA%B0%95%EC%9D%98%EC%84%B9%EC%85%9845</link>
            <guid>https://velog.io/@surusuu_/React%EC%9D%B8%ED%94%84%EB%9F%B0%EA%B0%95%EC%9D%98%EC%84%B9%EC%85%9845</guid>
            <pubDate>Tue, 24 May 2022 03:59:33 GMT</pubDate>
            <description><![CDATA[<h3 id="섹션4---1">&gt; 섹션4 - 1</h3>
<p>상위 컴포넌트 =&gt; 하위 컴포넌트 데이터 전달할 때 속성값 사용하지만 하위 컴포넌트가 많을 경우 속성값을 사용하면 불편해서 &quot;context&quot;라는 것을 사용함</p>
<ul>
<li>사용방법
상단에 { createContext } import<pre><code>import logo from &#39;./logo.svg&#39;;
import &#39;./App.css&#39;;
import React,{createContext, useState} from &#39;react&#39;;
</code></pre></li>
</ul>
<p>const UserContext = createContext(&quot;unknown&quot;);</p>
<p>export default function App(){
  const [name, setName] = useState(&quot;mike&quot;);
  return(
    <div>
      &lt;UserContext.Provider value={name}&gt;
        <div>상단메뉴</div>
        <Profile/>
        <div>하단메뉴</div>
        &lt;input type=&quot;text&quot; value={name} onChange={e=&gt;setName(e.target.value)}/&gt;
      &lt;/UserContext.Provider&gt;
    </div>
  );
}</p>
<p>const Profile = React.memo(function (){
  return (
    <div>
      <Greeting/>
      {/* ... */}
    </div>
  );
});</p>
<p>function Greeting(){
  return (
    &lt;UserContext.Consumer&gt;
      {username =&gt; <p>{<code>${username}님 안녕하세요.</code>}</p>}
    &lt;/UserContext.Consumer&gt;
  );
}</p>
<pre><code>
위의 function Greeting(){}을 useContext훅을 사용해서 다음과 같이 표현</code></pre><p>function Greeting(){
  const username = useContext(UserContext);
  return <p>{<code>${username}님 안녕하세요.</code>}</p>
}</p>
<pre><code>
### &gt; 섹션4 - 2
ref속성값을 사용하면 자식요소에 접근가능
상단에 useRef import

- inputRef.current.focus(); 자동으로 커서</code></pre><p>import logo from &#39;./logo.svg&#39;;
import &#39;./App.css&#39;;
import React,{useRef,useEffect} from &#39;react&#39;;</p>
<p>export default function App(){
  const inputRef = useRef();
  useEffect(()=&gt;{
    inputRef.current.focus();
  }, []);</p>
<p>  return(
    <div>
      <input type="text" ref={inputRef}/>
      <button>저장</button>
    </div>
  );
}</p>
<pre><code>
- forwordRef함수

- 문자를 입력할 때 , 컴포넌트가 계속 렌더링 되는데 새로운 함수가 렌더링 되면서 inital text가 계속 ref속성값으로 들어가서 키보드 값이 안먹히는 것임 =&gt; useCallback()훅의 메모자이션 기능으로 해결 가능

- 접근하는 돔의 요소가 많을 경우</code></pre><p>import logo from &#39;./logo.svg&#39;;
import &#39;./App.css&#39;;
import React,{useContext, crateContext, useRef,useState,useEffect} from &#39;react&#39;;</p>
<p>export default function App(){
  const boxListRef = useRef({});
  function onClick(){
    let maxRight = 0;
    let maxId = &#39;&#39;;
    for(const box of BOX_LIST){
      const ref = boxListRef.current[box.id];
      if(ref){
        const rect = ref.getBoundingClientRect();
        if(maxRight &lt; rect.right){
          maxRight = rect.right;
          maxId = box.id;
        }
      }
    }
   alert(<code>오른쪽 끝 요소는 ${maxId}입니다.</code>);
  }</p>
<p>  return(
    <div>
      &lt;div
        style={{
          display: &#39;flex&#39;,
          flexWrap: &#39;wrap&#39;,
          width: &#39;100vw&#39;,
          height: &#39;100%&#39;,
        }}
      &gt;
        {BOX_LIST.map(item =&gt; (
          &lt;div
            key={item.id}
            ref={ref=&gt;{boxListRef.current[item.id]=ref}}
            style={{
              flex:&#39;0 0 auto&#39;,
              width: item.width,
              height: 100,
              backgroundColor: &#39;yellow&#39;,
              border: &#39;solid 1px red&#39;,
            }}
          &gt;{<code>box_${item.id}</code>}</div>
        ))}
      </div>
      <button onClick={onClick}>오른쪽 끝 요소는?</button><br>    </div>
  );
}</p>
<p>const BOX_LIST = [
  { id: 1, width: 70 },
  { id: 2, width: 100 },
  { id: 3, width: 20 },
  { id: 4, width: 30 },
  { id: 5, width: 40 },
  { id: 6, width: 80 },
  { id: 7, width: 90 },
];</p>
<pre><code>
### &gt; 섹션4 - 3
- 리액트 내장 훅
![](https://images.velog.io/images/surusu/post/82d9abf1-d75d-4353-9d37-69c42b76f9a6/image.png)

- useRef: 이전 값을 기억하고 싶을 때
- useMemo
: const value = useMemo(()=&gt;runExpensiveJob(v1,v2),[v1,v2]); 두번째 배열은 의존성 배열, 의존성 배열이 변경될때만 함수가 실행됌
- useCallback: 불필요한 렌더링을 막아줌, 의존성 배열로 관리
- useReducer
: 상태값을 변경할 때 사용
: const [state, dispatch] = useReducer(reducer,INITIAL_STATE);
: 현재 상태값과 액션이 입력이 되고 액션을 보고 상태값을 어떻게 할지 결정함
: dispatch()로 객체 형식으로 부르면 useReducer에서 state를 변경함
- useImparativeHandle: ref속성값을 받아서 첫번재 매개변수로 넣음 두번째 매개변수로 함수를 입력
- useLayoutEffect: useEffect와 비슷하나, 부수효과 함수에서 연산을 많이 하면 브라우저가 먹통이 될 수도 있으니 주의. 조건에 따라 렌더링하고 싶을 때 사용. 실제 돔에 반영된 후에 함수가 실행됌 
- useDebugValue: 커스텀 훅을 만들어 사용할 때, 리액트 개발자 도구에 좀 더 풍부한 정보를 제공해줌. 디버깅할 때 편리함. -&gt; 리액트 개발자 도구에서 확인 가능

### &gt; 섹션5 - 1
- 컴포넌트 파일 작성법
함수의 PropType 속성의 타입값을 입력정보 작성가능
명명된 매개변수 사용하는게 좋음
MyComponent.propTypes = {};
export default function MyComponent(prop1, prop2){}
큰 객체를 정의할 때는 컴포넌트 외부에서 사용하는게 좋음(성능상)

- 훅끼리 모아서 관리보다 연관된 코드끼리 모아서 관리하는 것이 편함

### &gt; 섹션5 - 2
- prop-types 패키지로 속성값 타입 정보 입력하는 방법
: 타입이 왜 중요할까? 정적타입언어를 사용하는 것이 좋음. 

- prop-types 패키지 사용하는 이유
: 패키지로 사전에 타입오류를 잡을 수 있고, 타입정의 자체가 중요한 문서가 될 수 있음.

- propTypes.number / .oneOf([]) / .func() / .instanceOf() / .string / .objectOf / .isRequired(필수로사용해야하는것)

### &gt; 섹션5 - 3
- 조건부 렌더링
{isLogin ? `${name}님 안녕하세요.` : &#39;권한이 없습니다.&#39;}: 삼항연산자

변수가 number,string일 경우, 확실히 boolean타입으로 바꿔줘야함. 변수 앞에 !! 두개 붙여주면 됌.</code></pre><p>function GreetingA({isLogin, name}){
    if(isLogin){
        return <p>{<code>${name}님 안녕하세요.</code>}</p>
    } else {
        return <p>권한이 없습니다.</p>
    }
}</p>
<p>function GreetingB({isLogin,name}){
    return <p>{isLogin ? <code>${name}님 안녕하세요.</code> : &#39;권한이 없습니다.&#39;}</p>
}</p>
<p>function GreetingC({isEvent, isLogin, name, cash }){
    return (
        <div>
            저희 사이트에 방문해주셔서 감사합니다.
            {isEvent &amp;&amp; (
                <div> 
                    <p>오늘 이벤트 놓치지 마세요.</p>
                    <button onClick={onClickEvent}>이벤트 참여하기</button>
                </div>
            )}
            {!isEvent &amp;&amp; isLogin &amp;&amp; cash &lt;= 10000 &amp;&amp; (
                <div>
                    <p>{name}님 안녕하세요.</p>
                    <p>현재 보유하신 금액은 {cash}원 입니다.</p>
                </div><br>            )}
        </div>
    );
}</p>
<pre><code>
### &gt; 섹션5 - 4
- 컴포넌트 코드의 재사용성과 가독성 높이기
: 관심사별로 분리하기(리팩토링)

component폴더: 속성값이나 상태값이 없는 파일, 재사용성이 높은 파일들
container폴더: 재사용성이 없는 파일들

App.js에서는 여러페이지를 라우팅하는 걸로(컴포넌트를 부르면서)

### &gt; 섹션5 - 5
- 의존성 배열을 관리하는 방법
: 끝에 빈 배열을 넣고, 매개변수 넣는것도 조심

- 의존성 배열에 필요한 매개변수를 넣지 않았을 때 발생하는 문제점
: 오래된 변수를 사용하게 되겠음 

- 부수효과 안에 있는 함수를 밖에서 사용하고 싶을 땐?
: 함수를 밖으로 꺼내고 의존성 배열에 함수를 입력해야 함. 

### &gt; 섹션5 - 6
: 부수효과 함수내에서 함수의 실행시점을 조절할 수 있음
setInterval(), clearInterval()

- useReducer
: 값을 변경하는 로직을 여기에 작성

### &gt; 섹션5 - 7
- 성능을 최적화하는 방법1(렌더링)
*component(Data) -&gt; 가상돔과 비교 -&gt; 실제 돔에 반영

- React.memo는 속성값 비교함수를 통해서 컴포넌트 렌더링 과정을 생략할 수 있음
=&gt; App.js</code></pre><p>import &#39;./App.css&#39;;
import React,{ useState } from &#39;react&#39;;
import MyComponent from &#39;./MyComponents&#39;</p>
<p>export default function App(){
  const [value1, setValue1] = useState(0);
  const [value2, setValue2] = useState(0);</p>
<p>  return(
    <div>
      <p> 실전 리액트 </p>
      &lt;button onClick = { () =&gt; setValue1(value1+1)}&gt; value1 증가 </button>
      &lt;button onClick = { () =&gt; setValue2(value2+1)}&gt; value2 증가 </button>
      <MyComponent value1={value1} value2={value2}/>
    </div>
  );</p>
<p>}</p>
<pre><code>=&gt; MyComponents.js</code></pre><p>import React,{ useState } from &#39;react&#39;;</p>
<p>function MyComponents({ value1, value2 }) {
    return (
        <div>
            <p>{<code>value1: ${value1}</code>}</p>
            <p>{<code>value2: ${value2}</code>}</p>
        </div>
    );
}</p>
<p>function isEqual(prevProps, nextProps) {
    return prevProps.value1 == nextProps.value1;
}</p>
<p>export default React.memo(MyComponents, isEqual);</p>
<pre><code>
- 상태값을 불변객체로 관리하면 성능에 도움이 됌
불변객체로 만드는것: 새로운 객체로 만든다는 뜻
setFruits([...fruits, newFruit]);
preProps.todos === nextProps.todos 이렇게 비교가능해짐.

### &gt; 섹션5 - 8
- 성능을 최적화하는 방법2

### &gt; 섹션5 - 9
- 성능을 최적화하는 방법3</code></pre><p>import &#39;./App.css&#39;;
import React,{ useState, useEffect } from &#39;react&#39;;</p>
<p>export default function App(){
  const [flag, setFlag] = useState(true);
  useEffect(()=&gt;{
    setTimeout(()=&gt;setFlag(prev =&gt; !prev), 1000);
  })</p>
<p>  if(flag){
    return(
      <div>
        <p>사과</p>
        <p>바나나</p>
      </div>
    );
  }
  else{
    return(
      <div>
        <p>사과</p>
        <p>바나나</p>
        <p>파인애플</p>
      </div>
    );
  }</p>
<p>}</p>
<p>```
이렇게 하면, 어떤값이 변경됬는지 알 수 없는데, 태그에 key값을 추가하면 리액트는 같은 Key를 갖는 요소끼리만 비교를 한다.
key속성값은 id와 비슷하 느낌. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[React] 인프런강의(섹션1,2)]]></title>
            <link>https://velog.io/@surusuu_/React-%EC%9D%B8%ED%94%84%EB%9F%B0%EA%B0%95%EC%9D%98%EC%84%B9%EC%85%9812</link>
            <guid>https://velog.io/@surusuu_/React-%EC%9D%B8%ED%94%84%EB%9F%B0%EA%B0%95%EC%9D%98%EC%84%B9%EC%85%9812</guid>
            <pubDate>Tue, 24 May 2022 03:58:39 GMT</pubDate>
            <description><![CDATA[<h3 id="섹션1---1">&gt; 섹션1 - 1</h3>
<ul>
<li>리액트란?
자동으로 업데이트 되는 UI
render함수는 순수 함수로 작성
state는 불변 변수로 관리</li>
</ul>
<h3 id="섹션1---34">&gt; 섹션1 - 3,4</h3>
<ul>
<li>라이브러리
=&gt; 웹팩(WebPack) VS 바벨(Babel)
WebPack: 의존성을 분석해 여러 모듈을 하나의 파일로 묶어주는 역할 / 모듈 시스템(ESM,CommonJS)을 사용하기 위해서
Babel: 코드 변환기. 최신 js문법을 구형 브라우저에서도 쓸 수 있도록 코드 자체를 변환시킨다.</li>
</ul>
<h3 id="섹션1---5">&gt; 섹션1 - 5</h3>
<ul>
<li>리액트 환경 설정(create-react-app/CRA)
=&gt; 리액트 개발환경을 직접 구축하려면 많은 지식과 시간이 필요..
=&gt; 페이스북에서 관리하는 공식 툴
=&gt; npx create-react-app {app 이름} 을 통해 react web app을 setup할 수 있음
=&gt; cra는 서버사이드 렌더링을 지원하지 않음
=&gt; Next.js는 서버사이드 렌더링 지원</li>
</ul>
<h3 id="섹션1---7">&gt; 섹션1 - 7</h3>
<ul>
<li>CSS작성방법</li>
</ul>
<ol>
<li><p>CSS파일
: 상단에 import ./파일명.css
: 이름충돌 유의</p>
</li>
<li><p>CSS모듈
: 상단에 import ./파일명.module.css 객체형식으로 받아서 속성으로 입력하면 됌
: 이름충돌 문제 없음</p>
</li>
<li><p>Sass
: npm install node-sass 설치
: 파일형식은 .scss</p>
</li>
<li><p>css-in-js
: js파일 안에서 css를 사용하는 방법
: npm install styled-components 설치</p>
</li>
</ol>
<h3 id="섹션1---8">&gt; 섹션1 - 8</h3>
<ul>
<li><p>단일 페이지 애플리케이션(SPA)
: 클라이언트가 초기요청 서버가 html을 내려주고 페이지 전환이 있을땐, 필요할 때마다 데이터를 요청해서 받아오고 라우팅 처리로 가능</p>
</li>
<li><p>SPA 브라우저 API
: pushState, replaceState함수
: popState함수</p>
</li>
</ul>
<hr/>

<p><strong>- SPA 브라우저 만들기</strong>
=&gt; App.js</p>
<pre><code>function App(){
  const [pageName, setPageName] = useState(&#39;&#39;);
  useEffect(()=&gt;{
    window.onpopstate = function (event) {
      console.log(`location: ${document.location}, state: ${event.state}`);
      setPageName(event.state);
    };
  }, []);
  function onClick1(){
    const pageName = &#39;page1&#39;;
    window.history.pushState(pageName,&#39;&#39;,&#39;/page1&#39;);
    setPageName(pageName);
  }
  function onClick2(){
    const pageName = &#39;page2&#39;;
    window.history.pushState(pageName,&#39;&#39;,&#39;/page2&#39;);
    setPageName(pageName);
  }
  return (
    &lt;div&gt;
      &lt;button onClick={onClick1}&gt;
        page1
      &lt;/button&gt;
      &lt;button onClick={onClick2}&gt;
        page1
      &lt;/button&gt;
      {!pageName &amp;&amp; &lt;Home/&gt;}
      {pageName === &#39;page1&#39; &amp;&amp; &lt;Page1/&gt;}
      {pageName === &#39;page2&#39; &amp;&amp; &lt;Page2/&gt;}
    &lt;/div&gt;
  );
}

function Home(){
  return &lt;h2&gt; 여기는 홈페이지입니다. &lt;/h2&gt;
}
function Page1(){
  return &lt;h2&gt; 여기는 Page1입니다.&lt;/h2&gt;
}
function Page2(){
  return &lt;h2&gt; 여기는 Page2입니다.&lt;/h2&gt;
}</code></pre><hr/>

<p><strong>- SPA로 동작하는 웹사이트 만들기</strong>
: npm install react-router-dom 설치
: route태그를 통해서 3가지 component가 렌더링됌
: exact부분은 url형식을 지정해줌</p>
<p>=&gt; App.js</p>
<pre><code>import logo from &#39;./logo.svg&#39;;
import &#39;./App.css&#39;;
import React, {useState , useEffect} from &#39;react&#39;;
import reactDom from &#39;react-dom&#39;;
import { BrowserRouter } from &#39;react-router-dom&#39;;
import { Route, Link } from &#39;react-router-dom&#39;;
import Rooms from &#39;./Rooms&#39;

function App(){
  return (
    &lt;BrowserRouter&gt;
      &lt;div style={{padding: 20, border: &#39;5px solid gray &#39;}}&gt;
        &lt;Link to=&quot;/&quot;&gt;홈&lt;/Link&gt;
        &lt;br/&gt;
        &lt;Link to=&quot;/photo&quot;&gt;사진&lt;/Link&gt;
        &lt;br/&gt;
        &lt;Link to=&quot;/rooms&quot;&gt;방 소개&lt;/Link&gt;
        &lt;br/&gt;
        &lt;Route exact path=&quot;/&quot; component={Home}/&gt;
        &lt;Route exact path=&quot;/photo&quot; component={Photo}/&gt;
        &lt;Route exact path=&quot;/rooms&quot; component={Rooms}/&gt;
      &lt;/div&gt;
    &lt;/BrowserRouter&gt;
  );
}

function Home(){
  return &lt;h2&gt; 여기는 홈페이지입니다. &lt;/h2&gt;
}
function Photo(){
  return &lt;h2&gt; 여기서 사진을 감상해보세요.&lt;/h2&gt;
}

export default App;</code></pre><p>=&gt; Rooms.js</p>
<pre><code>import React from &#39;react&#39;;
import { Route, Link } from &#39;react-router-dom&#39;;

export default function Rooms({match}){
    return(
        &lt;div&gt;
            &lt;h2&gt; 여기는 방을 소개하는 페이지. &lt;/h2&gt;
            &lt;Link to={`${match.url}/bludRoom`}&gt;파란 방입니다.&lt;/Link&gt;
            &lt;br/&gt;
            &lt;Link to={`${match.url}/greenRoom`}&gt;초록 방입니다.&lt;/Link&gt;
            &lt;br/&gt;
            &lt;Route path={`${match.url}/:roomId`} component={Room}/&gt;
            &lt;Route
                exact
                path={match.url}
                render={()=&gt;&lt;h3&gt;방을 선택해 주세요.&lt;/h3&gt;}
            /&gt;
            &lt;br/&gt;
        &lt;/div&gt;
    );
}

function Room({match}){
    return &lt;h2&gt;{`${match.params.roomId} 방을 선택했습니다.`}&lt;/h2&gt;
}</code></pre><h3 id="섹션2---1">&gt; 섹션2 - 1</h3>
<p>: [...arr]은 array의 모든 요소를 나열해주는 것과 같음 
: 리액트는 데이터를 기반으로 UI가 어떤 모습인지를 기술해줌
: UI의 모습이 한눈에 그려짐(추상화 단계가 높아 비즈니스 로직에 더 집중할 수 있음)</p>
<ul>
<li>TodoList 만들기
=&gt; App.js<pre><code>import logo from &#39;./logo.svg&#39;;
import &#39;./App.css&#39;;
import React, {useState , useEffect} from &#39;react&#39;;
import reactDom from &#39;react-dom&#39;;
import { BrowserRouter } from &#39;react-router-dom&#39;;
import { Route, Link } from &#39;react-router-dom&#39;;
import Rooms from &#39;./Rooms&#39;
import { current } from &#39;immer&#39;;
</code></pre></li>
</ul>
<p>export default function App(){
  const [todoList, setTodoList] = useState([]);
  const [currentId, setCurrentId] = useState(1);
  const [desc, setDesc] = useState(&#39;&#39;);
  const [showOdd, setShowOdd] = useState(false);
  function onAdd(){
    const todo = { id: currentId, desc };
    setCurrentId(currentId+1);
    setTodoList([...todoList, todo]);
  }
  function onDelete(e){
    const id = Number(e.target.dataset.id);
    const newTodoList = todoList.filter(todo =&gt; todo.id !== id)
    setTodoList(newTodoList);
  }
  function onSaveToServer(){</p>
<p>  }
  return (
    <div>
      <h3>할 일 목록</h3>
      <ul>
        {todoList.filter((_,index)=&gt; showOdd ? index%2 == 0: true ).map(todo =&gt; (
          <li key={todo.id}>
            <span>{todo.desc}</span>
            <button data-id={todo.id} onClick={onDelete}>
              삭제
            </button>
          </li>
        ))}
        &lt;input type=&quot;text&quot; value={desc} onChange={e=&gt;{setDesc(e.target.value)}}/&gt;
        <button onClick={onAdd}>추가</button>
        &lt;button onClick={()=&gt; setShowOdd(!showOdd)}&gt;
          홀수 아이템만 보기 on/off<br>        </button>
        <button onClick={onSaveToServer}>서버에 저장</button>
      </ul>
    </div>
  );
}</p>
<pre><code>
### &gt; 섹션2 - 2
UI컴포넌트에서 데이터 다루는 법 
- UI데이터를 속성이나 상태값으로 관리함
- 리액트가 값의 변경을 알려면 상태값으로 관리해야 함
- 상태값: useState
- 속성값: 부모컴포넌트가 렌더링될 때마다 자식컴포넌트도 렌더링
- 속성값이 변경될 때만 렌더링 하기 위해서 React.memo를 사용하면 됌
- 속성값은 불변 변수
- 상태값도 불변 변수로 관리하기 위해 객체 형식으로
- 객체를 불변 변수로 하기 위해서는 전개연산자를 이용

=&gt;App.js</code></pre><p>import logo from &#39;./logo.svg&#39;;
import &#39;./App.css&#39;;
import React, {useState , useEffect} from &#39;react&#39;;
import reactDom from &#39;react-dom&#39;;
import { BrowserRouter } from &#39;react-router-dom&#39;;
import { Route, Link } from &#39;react-router-dom&#39;;
import Rooms from &#39;./Rooms&#39;
import { current } from &#39;immer&#39;;
import Counter from &#39;./Counter&#39;;</p>
<p>export default function App(){
  const [color, setColor] = useState(&#39;red&#39;);
  function onClick(){
    setColor(&#39;blue&#39;);
  }
  return(
    <div>
      <Counter/>
      <Counter/>
      <button style={{backgroundColor:color}} onClick={onClick}>
      좋아요
      </button>
    </div></p>
<p>  );
}</p>
<pre><code>
=&gt;Title.js</code></pre><p>import React, { memo } from &#39;react&#39;;</p>
<p>function Title({title}){
    return <p> {title} </p>
}</p>
<p>export default React.memo(Title);</p>
<pre><code>
=&gt;Counter.js</code></pre><p>import React, {useState} from &#39;react&#39;;
import Title from &#39;./Title&#39;;</p>
<p>export default function Counter() {
    const [count, setCount] = useState({value:0,value1:1,value2:2});
    function onClick(){
        setCount({...count, value:count.value+1});
    }
    return (
        <div>
            &lt;Title title={<code>현재 카운트: ${count.value}</code>}/&gt;
            <button onClick={onClick}>증가</button>
        </div>
    );
}</p>
<pre><code>
### &gt; 섹션2 - 3
- 컴포넌트가 반환할 수 있는 값
- 배열로 반환할 때는 리액트 요소가 항상 key를 갖고 있어야 함
- fragment: 여러개 요소를 반환할 때 유용함 (= &lt;/&gt;, &lt;&gt; )</code></pre><p>return(
    &lt;React.Fragment&gt;
      <p>안녕</p>
      <p>하세요.</p>
    &lt;/React.Fragment&gt;
  );</p>
<pre><code>- react portal: react portal을 사용하기 위해서 react-dom에 있는 함수를 사용해야 함 =&gt; reactDom.createPortal()

### &gt; 섹션2 - 4
- 리액트 요소와 가상돔
- 컴포넌트가 삭제: unmount / 컴포넌트가 생성: mount

### &gt; 섹션2 - 5
하나의 화면을 표현하기 위해서 여러 리액트 요소가 트리구조로 구성
화면 구성은 &quot;랜더단계 -&gt; 커밋단계&quot; 를 거침
(렌더단계: 가상돔 / 커밋단계: 실제돔)

### &gt; 섹션2 - 6
리액트 훅(Hook)은 컴포넌트에 기능을 추가할 때 사용하는 함수
컴포넌트에 상태값을 추가, 자식요소에 접근과 같은 기능을 사용하고 싶을 때 훅을 사용
훅이 나오면서 클래스형 컴포넌트는 더이상 사용안해도 되는 상황

- 대표 훅
1. useState: 상태값 추가
2. useEffect: 부수효과 처리(외부의 상태를 변경하는 것:서버API를 등록,이벤트 헨들러 등록)

- useState
비동기, 배치로 처리
여러상태값을 관리할 때는 useState보다는 useReducer가 더 적합

- useEffect
렌더링 결과가 실제 돔에 반영되고 비동기로 호출이 됌
*외부함수는 의존성 배열에 입력할 필요없지만, 지역함수는 부수효과 내부에서 사용했다면 의존성 배열에 입력해줘야 됌.

=&gt; App.js</code></pre><p>import logo from &#39;./logo.svg&#39;;
import &#39;./App.css&#39;;
import React, {useState , useEffect} from &#39;react&#39;;
import ReactDOM from &#39;react-dom&#39;;
import { BrowserRouter } from &#39;react-router-dom&#39;;
import { Route, Link } from &#39;react-router-dom&#39;;
import Rooms from &#39;./Rooms&#39;
import { current } from &#39;immer&#39;;
import Counter from &#39;./Counter&#39;;</p>
<p>console.log(
  <a key="key1" style={{width:100}} href="http://google.com">
        click here
  </a>,
)
export default function App(){
  const [count, setCount ] = useState(0);
  function onClick() {
    ReactDOM.unstable_batchedUpdates(()=&gt;{
      setCount(v =&gt; v+1);
      setCount(v =&gt; v+1);
    });
  }
  useEffect(()=&gt;{
    window.addEventListener(&#39;click&#39;,onClick);
    return ()=&gt;window.removeEventListener(&#39;click&#39;,onClick);
  });
  console.log(&#39;render canceled&#39;);
  return(
    <div>
      <h2>{count}</h2>
      <button onClick={onClick}>증가</button>
    </div>
  );
}</p>
<pre><code>
### &gt; 섹션2 - 7
훅은 재사용성이 좋음
커스텀 훅 만들어보기!

=&gt; App.js</code></pre><p>import logo from &#39;./logo.svg&#39;;
import &#39;./App.css&#39;;
import React from &#39;react&#39;;
import Profile from &#39;./Profile&#39;;</p>
<p>export default function App(){
  return <Profile/>;
}</p>
<pre><code>
=&gt; Profile.js</code></pre><p>import React,{useState, useEffect} from &#39;react&#39;;
import useUser from &#39;./useUser&#39;;</p>
<p>export default function Profile({userId}){
    const user = useUser(userId);
    return(
        <div>
            {!user&amp;&amp;<p>사용자 정보를 가져오는 중...</p>}
            {user&amp;&amp;(
                &lt;&gt;
                    <p>{<code>name is ${user.name}</code>}</p>
                    <p>{<code>age is ${user.age}</code>}</p>
                &lt;/&gt;
            )}
        </div>
    );
}</p>
<pre><code>
=&gt; useUser.js</code></pre><p>import React,{useState, useEffect} from &#39;react&#39;;</p>
<p>export default function useUser(userId){
    const [user, setUser] = useState(null);
    useEffect(()=&gt;{
        getUserApi(userId).then(data=&gt;setUser(data));
    }, [userId]);
    return user;
}</p>
<p>const USER1 = { name: &quot;mike&quot;, age: 23 };
const USER2 = { name: &quot;jane&quot;, age: 41 };
function getUserApi(userId){
    return new Promise(res =&gt; {
        setTimeout(()=&gt;{
            res(userId % 2 ? USER1 : USER2);
            }, 500);
        }
    );
}</p>
<pre><code>
&lt;hr/&gt;

- 현직에서 사용할 훅은 ???
useMounted 훅을 만들어보자</code></pre><p>import React,{useState, useEffect} from &#39;react&#39;;</p>
<p>export default function useWindowWidth(){
    const [mounted, setMounted] = useState(false);
    useEffect(()=&gt;{
        setMounted(true);
    }, []);
    return mounted
}</p>
<p>```</p>
<h3 id="섹션2---8">&gt; 섹션2 - 8</h3>
<ul>
<li>훅 사용시 규칙</li>
</ul>
<ol>
<li>하나의 컴포넌트에서 훅을 <strong>호출하는 순서는 항상 같아야 한다.</strong></li>
<li>훅은 함수형 컴포넌트 또는 커스텀 훅 안에서만 호출되어야 한다.</li>
<li>if문/for문/함수 안에서 훅을 사용하면 안된다.</li>
<li>훅이 사용된 위치정보를 기반으로 훅은 데이터를 관리한다.</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[[React] CodingApple - React강의]]></title>
            <link>https://velog.io/@surusuu_/CodingApple-React%EA%B0%95%EC%9D%98</link>
            <guid>https://velog.io/@surusuu_/CodingApple-React%EA%B0%95%EC%9D%98</guid>
            <pubDate>Tue, 24 May 2022 03:56:04 GMT</pubDate>
            <description><![CDATA[<p>1강
Node.js를 설치한 이유
: create-react-app라이브러리 사용하기 위해(npm으로 설치가능)</p>
<p>npm
: 라이브러리를 쉽게 설치하게 도와주는 툴</p>
<p>메인페이지는 App.js
public -&gt; index.html에 app.js를 박아넣는데 index.js에 박아넣는 명령을 함</p>
<p>node_modules
: 설치된 모든 라이브러리들이 모아놓아져 있는 곳</p>
<p>Src
: 소스코드 보관함</p>
<p>package.json
: 설치된 모든 라이브러리명 + 버전 적혀있음</p>
<p>2강
HTML처럼 생긴 JSX
index.js의 .getElementById(&#39;root&#39;)를 통해서 app.js가 렌더링되는 것을 알 수 있음
class-&gt; className</p>
<p>리액트를 쓰는이유: 데이터바인딩이 쉬움
데이터바인딩이란?
{ 변수명,함수() }
이미지를 넣고 싶을땐, import 변수 from 주소 하고 img태그 src에 { 변수 }를 넣으면 이미지를 로드할 수 있음
style속성 넣고 싶을땐 style={object 자료형으로 만든 스타일}
css속성명 사용할때 -(대쉬)가 붙는것들은 camel표기법으로 바꿔서 적어야함</p>
<p>3강
state
데이터는</p>
<ol>
<li>변수에 보관</li>
<li>state에 보관</li>
</ol>
<p>[사용방법]
상단에 {useState} import하기</p>
<p>ES6 destructuring문법
var [a,b] = [10, 100] =&gt; a=10 b=100</p>
<p>state는 변수대신 사용하는 공간
let [state데이터,state데이터변경함수] = useState(&#39;남자코트추천&#39;);</p>
<p>웹이 앱처럼 동작하게 만들고 싶어서 useState사용
새로고침 없이도 자동 재렌더링 된다는 장점
자주바뀌는 중요한 데이터는 state로 저장해서 사용하기</p>
<p>4강
터미널에 뜨는 warning(노란색)</p>
<p>eslint가 잡아주는 문법 체크사항 : 상단에 /eslint-disable/ 해놓으면 안뜸
이벤트 리스너 onClick
onClick = { 함수() } / { () =&gt; { 실행할 내용} }</p>
<p>state변경방법: state데이터 변경함수를 사용하자!
실행할 내용에 state데이터변경함수(변경할내용) 을 작성하면 됌</p>
<p>5강
원본 state수정할 수 없음
var newArray = 를 통해 기존 array를 일단 복사
var newArray = array 하면 복사가 아닌 값 공유 형식임 (reference data type검색하면 자세하게 알 수 있음)</p>
<p>deep copy 하는 법
var newArray = [...array] (ES6 신문법)</p>
<p>state변경 방법</p>
<p>일단 기존 state카피본 만듦
카피본에 수정사항 반영
변경함수()에 집어넣기
6강
react는 페이지 전환을 위해 라우터 사용</p>
<p>component란?
HTML을 한단어로 줄여서 쓸 수 있는 방법</p>
<p>HOW?
새로운 function을 만들어서 function Modal(){ return() }
축약을 원하는 HTMl덩어리를 집어넣으면 됌
원하는 곳에서 &lt;함수명/&gt;</p>
<p>component유의사항</p>
<p>이름은 대괄호! 첫문자는 대문자!
return()안에 있는건 태그하나로 묶어야 함
div연달아 못쓰는데 쓰려는 방법은</p>
<ol>
<li>큰 div안에 여러 div를 넣기
div와 div사이에 &lt;/&gt; 넣기
component장점</li>
</ol>
<p>관리하기가 편함
어떤걸 component로 만들면 좋을까?</p>
<p>반복 출현하는 HTML덩어리들
자주 변경되는 HTML덩어리들
다른 페이지 만들때도 컴포넌트로 만듦
단점은, state쓸 때 복잡해짐</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[React] 프로젝트 시작하기]]></title>
            <link>https://velog.io/@surusuu_/React-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EC%8B%9C%EC%9E%91%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@surusuu_/React-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EC%8B%9C%EC%9E%91%ED%95%98%EA%B8%B0</guid>
            <pubDate>Tue, 24 May 2022 03:55:27 GMT</pubDate>
            <description><![CDATA[<h3 id="1-환경세팅">1. 환경세팅</h3>
<h4 id="1-1-nodejs-설치">1-1. Node.js 설치</h4>
<p>Node.js는 리액트와 관련된 라이브러리들의 손쉬운 설치를 위해 필요한 node의 패키지 매니저 npm/yarn을 위해 필요하다. 
<a href="https://nodejs.org/ko/">https://nodejs.org/ko/</a></p>
<h4 id="1-2-yarnnpm-설치">1-2. yarn/npm 설치</h4>
<p>npm 은 Node.js 를 설치하게 될 때 같이 딸려오는 패키지 매니저 도구이다. 
yarn 은 조금 개선된 버전의 npm 이다.
프로젝트에서 사용되는 라이브러리를 설치하고 해당 라이브러리들의 버전 관리를 하게 될 때 사용한다.
우리가 yarn 을 사용하는 이유는, 더 나은 속도, 더 나은 캐싱 시스템을 사용하기 위함이다.</p>
<blockquote>
<pre><code>//git bash
brew install yarn</code></pre></blockquote>
<pre><code>
#### 1-3. create-react-app 설치 및 사용
create-react-app은, 리액트 앱을 만들어주는 도구이다.
&gt; ```
yarn global add create-react-app</code></pre><ul>
<li>macOS 유저여서 nvm 을 통하여 Node.js 를 설치했다면 yarn global 설치가 제대로 작동하기 위해선 다음 명령어를 사전에 입력해야 한다. ( 윈도우는 상관없음 )<pre><code>echo &#39;export PATH=&quot;$(yarn global bin):$PATH&quot;&#39; &gt;&gt; ~/.bash_profile</code></pre></li>
</ul>
<h4 id="1-4-사용">1-4. 사용</h4>
<p>사용하기 위해서 다음 명령어 입력</p>
<blockquote>
<pre><code>create-react-app hello-react //프로젝트 폴더 생성
cd hello-react //생성한 폴더로 이동
yarn start //실행</code></pre></blockquote>
<p>```</p>
<p>정상적으로 실행이 되면, 아래와 같은 웹페이지가 뜬다.
<img src="https://images.velog.io/images/surusu/post/2680e268-c363-4ff1-a11c-d737bb6a70ac/image.png" alt=""></p>
<hr>
<h4 id="참고url">참고URL</h4>
<p><a href="https://velopert.com/3621">https://velopert.com/3621</a></p>
]]></description>
        </item>
    </channel>
</rss>