<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>elena_park.log</title>
        <link>https://velog.io/</link>
        <description>Front-end 개발자입니다.</description>
        <lastBuildDate>Thu, 08 Dec 2022 06:36:07 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>elena_park.log</title>
            <url>https://images.velog.io/images/elena_park/profile/cc85153e-38d4-41c3-98b9-e3edcf765546/10055714915.jpg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. elena_park.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/elena_park" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[피자 나눠 먹기(2)]]></title>
            <link>https://velog.io/@elena_park/%ED%94%BC%EC%9E%90-%EB%82%98%EB%88%A0-%EB%A8%B9%EA%B8%B02</link>
            <guid>https://velog.io/@elena_park/%ED%94%BC%EC%9E%90-%EB%82%98%EB%88%A0-%EB%A8%B9%EA%B8%B02</guid>
            <pubDate>Thu, 08 Dec 2022 06:36:07 GMT</pubDate>
            <description><![CDATA[<p>문제 설명</p>
<p>피자 조각은 6조각일때 주어지는 정수 n명이 피자를 하나도 남기지 않고 모두 같은 수의 피자조각을 먹어야할 경우 최소로 시켜야하는 피자는 몇판인가? </p>
<p>풀이 과정</p>
<p>기본 조각수 (6조각)와 주어진 n으로 모두가 한조각씩 먹으면서도 피자가 남지 않게 하는 최소한의 조각수를 구하면(즉, 최소공배수) 최소 피자 판 수를 구할 수 있다.</p>
<ol>
<li>최소공배수는 두 수의 곱을 두 수의 최대공약수로 나눈 값으로 나타낼 수 있다.</li>
<li>1번의 과정을 위해 유클리드 호제법을 이용하여 최대공약수를 구한다.</li>
</ol>
<pre><code>// 최대 공약수 구하기
function getGCD(num1,num2) {
    // recursive way
    if(num2 === 0) {
        return num1;
    }
    return getGCD(num2, num1 % num2)
}

function solution(person) {
    const pieces = 6;
    const GCD = getGCD(pieces,person)
    // 최소공배수 구하기
    const LCM = (person*pieces) / GCD;

    return LCM / pieces;
}

</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[원티드 프리온보딩 프론트엔드 인턴십]참가 에세이 - 박성은]]></title>
            <link>https://velog.io/@elena_park/%EC%9B%90%ED%8B%B0%EB%93%9C-%ED%94%84%EB%A6%AC%EC%98%A8%EB%B3%B4%EB%94%A9-%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EC%9D%B8%ED%84%B4%EC%8B%AD%EC%B0%B8%EA%B0%80-%EC%97%90%EC%84%B8%EC%9D%B4-%EB%B0%95%EC%84%B1%EC%9D%80</link>
            <guid>https://velog.io/@elena_park/%EC%9B%90%ED%8B%B0%EB%93%9C-%ED%94%84%EB%A6%AC%EC%98%A8%EB%B3%B4%EB%94%A9-%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EC%9D%B8%ED%84%B4%EC%8B%AD%EC%B0%B8%EA%B0%80-%EC%97%90%EC%84%B8%EC%9D%B4-%EB%B0%95%EC%84%B1%EC%9D%80</guid>
            <pubDate>Wed, 07 Dec 2022 09:08:12 GMT</pubDate>
            <description><![CDATA[<p>이직 준비 중 이번 2022 하반기 원티드 프리온보딩 프론트엔드 인턴십에 참여하게 되었다. 이 글은 지원 과정 중 하나인 숏 에세이 작성 과정에 대한 포스트이다. </p>
<h3 id="1-최종합격까지-몇-개-이상의-이력서-작성이-필요할까">1. 최종합격까지 몇 개 이상의 이력서 작성이 필요할까?</h3>
<p> 이번 프리온보딩 인턴십을 참여하게될 경우 인턴십 종료 후 1개월 이내에 참가기업 포함 최소 20개 이상의 기업에 입사지원을 해야한다. 개인적인 생각이지만 이는 인턴십 종료 직후 취업 준비에 바로 스퍼트를 내게 하기 위한 장치로 생각된다.</p>
<h3 id="2-프리온보딩-인턴십에서-숏에세이-작성제도를-시행하는-목적">2. 프리온보딩 인턴십에서 숏에세이 작성제도를 시행하는 목적</h3>
<p> 인턴십 진행 전, 참여자가 숏에세이를 작성하면서 이 과정이 진행되는 목적과 취지를 생각해보는 시간을 가짐으로써 조금 더 의식적으로 과정에 참여할 수 있도록 하기 위해서라고 생각한다. 사람들이 이러한 과정을 신청할 때 초반에는 적극적으로 참여하지만 많은 경우에 중도에 포기하거나 느슨해지는 경향이 있다. 그러한 경향에 대해 경계를 하는 것이 이 인턴십 과정을 참여하는 데 있어 중요한 마음가짐 중 하나일 것이다.  </p>
<p> 또한 지원하고 싶은 참가기업에 대해 알아보면서 해당 기업이 어떤 사업 분야를 가지며 어떤 인재를 채용하고자 하는지 (인재상 및 개발팀에서 채용하는 자격요건) 등 인턴십 사전에 주요 기업의 정보를 인지하도록 하기 위해서도 있다고 생각한다. </p>
<h3 id="3-지원하고-싶은-참가기업">3. 지원하고 싶은 참가기업</h3>
<p>젠스타메이트,피아스페이스,주식회사 이노야드,다니다,(주)아티슨앤오션 등이 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[분수의 덧셈 ]]></title>
            <link>https://velog.io/@elena_park/%EB%B6%84%EC%88%98%EC%9D%98-%EB%8D%A7%EC%85%88-feat.-%EC%B5%9C%EB%8C%80%EA%B3%B5%EC%95%BD%EC%88%98-%EC%B5%9C%EC%86%8C%EA%B3%B5%EB%B0%B0%EC%88%98</link>
            <guid>https://velog.io/@elena_park/%EB%B6%84%EC%88%98%EC%9D%98-%EB%8D%A7%EC%85%88-feat.-%EC%B5%9C%EB%8C%80%EA%B3%B5%EC%95%BD%EC%88%98-%EC%B5%9C%EC%86%8C%EA%B3%B5%EB%B0%B0%EC%88%98</guid>
            <pubDate>Sat, 26 Nov 2022 18:30:11 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/elena_park/post/4859c65e-5262-47d1-8c54-cdc6d0ef26fd/image.png" alt=""></p>
<p>문제 설명</p>
<ol>
<li>주어지는 매개변수중 denum1, num1은 분자1/분모1, denum2, num2는 분자2/분모2를 뜻한다.</li>
<li>두 분수를 더한 값을 <strong>기약분수</strong>로 나타냈을 때 분자와 분모를 순서대로 담은 배열을 리턴한다.</li>
</ol>
<p>풀이 과정</p>
<ol>
<li>통분 과정을 거치기 위해 두 분모(num1, num2)의 최소공배수를 구한다.</li>
<li>최소공배수는 두 수의 곱을 두 수의 최대공약수로 나눈 값으로 나타낼 수 있다.</li>
<li>2번의 과정을 위해 유클리드 호제법을 이용하여 최대공약수를 구한다.</li>
<li>이렇게 구한 최소공배수는 곧 통분한 분모의 값과 같으므로, 분모를 제외한 각 분자에 최소공배수를 분모의 값으로 나눈 값을 곱해준다. </li>
<li>문제의 조건대로 기약분수를 만들어주기 위해 구한 분자, 분모로 새로운 최대공약수를 구한다.</li>
<li>분자, 분모를 5의 최대공약수로 나눈 값을 리턴한다.</li>
</ol>
<hr>
<ol>
<li>실패한 답변 : 기약분수로 만들어주는 과정을 넣지 않아 실패하는 케이스가 있었다.
<img src="https://velog.velcdn.com/images/elena_park/post/fc9a4441-6902-4720-8374-1100add3cd38/image.png" alt=""></li>
</ol>
<ol start="2">
<li>성공한 답변 
<img src="https://velog.velcdn.com/images/elena_park/post/452fc681-10c5-4540-99e9-d4baa9a635ce/image.png" alt=""></li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[소인수분해 하기]]></title>
            <link>https://velog.io/@elena_park/%EC%86%8C%EC%9D%B8%EC%88%98%EB%B6%84%ED%95%B4-%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@elena_park/%EC%86%8C%EC%9D%B8%EC%88%98%EB%B6%84%ED%95%B4-%ED%95%98%EA%B8%B0</guid>
            <pubDate>Sat, 26 Nov 2022 15:52:05 GMT</pubDate>
            <description><![CDATA[<p>주어진 n인 자연수를 소수(1과 자기자신만 약수로 가지는 수)가 나올 때까지 계속 소수로 나누기</p>
<p><img src="https://velog.velcdn.com/images/elena_park/post/45bc65f3-da03-4f91-9f21-a30b4ba5c87b/image.png" alt=""></p>
<pre><code>function solution(n) {
    // 인수를 담을 배열 생성
    const factors =[];
    // 주어지는 자연수를 temp에 저장
    let temp = n;
    for(let i = 2; i &lt;= n; i++) {
        while(temp % i === 0) {
            // 업데이트되는 몫을 temp에 저장
            temp = temp / i
            // 나누는 인수를 배열에 저장
            factors.push(i)
        }
        // 몫이 1이 되면 반복문을 빠져나옴
        if(temp === 1) break;
    }

    // 중복을 제거하여 리턴
    return [...new Set(factors)];
}</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[합성수 찾기 ]]></title>
            <link>https://velog.io/@elena_park/%ED%95%A9%EC%84%B1%EC%88%98-%EC%B0%BE%EA%B8%B0</link>
            <guid>https://velog.io/@elena_park/%ED%95%A9%EC%84%B1%EC%88%98-%EC%B0%BE%EA%B8%B0</guid>
            <pubDate>Sat, 26 Nov 2022 12:59:07 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/elena_park/post/18d13c4a-a405-4bad-8f6a-0eb1ce159ebc/image.png" alt=""></p>
<ol>
<li>소인수분해 방법으로 찾기 : 시간복잡도 - O(n2)</li>
</ol>
<p>소수 : 1과 자기 자신만을 약수로 가지는 수
약수 : 어떤 수를 나누어 떨어지게 하는 수 (나머지가 0인 수)</p>
<p>즉, 소수는 1과 자기 자신만을 나눌때만 나머지가 0이 되는 수이며
합성수는 1과 자기 자신만이 아닌 그 사잇수로도 나머지가 0이 되는 수로, 약수가 여러개인 수이다.</p>
<pre><code>function solution(n) {
    let compositeNumbers = [];
   for(let i = 2; i &lt;=n; i++) {
       for(let j = 2; j &lt; i; j++ ) {
           if(i % j === 0) {
    // 1과 i 자기 자신을 제외한 나머지수를 i로 나눌때도 나누어 떨어지면 합성수이다
               compositeNumbers.push(i)
               break;
           }
       }
   }

    return compositeNumbers.length;
}</code></pre><ol start="2">
<li>에라토스테네스의 체를 이용하여 찾기 : 시간복잡도 - O(nlogn)</li>
</ol>
<pre><code>
// 에라토스테네스의 체

function solution(n) {
    const filledArray = new Array(n+1).fill(1)
    //  0 1 2 3 4 5 6 7 8 9 10 -&gt; index
    // [1,1,1,1,1,1,1,1,1,1,1] =&gt; 시작
    // [1,1,1,1,0,1,0,1,0,1,0] =&gt; i는 2일 때
    // [1,1,1,1,0,1,0,1,0,0,0] =&gt; i는 3일 때
    // ...

    for(let i=2; i&lt;= n; i++) {
        if(filledArray[i]) {
            for(let j=2; i*j &lt;=n; j++) {
                if(filledArray[i*j]) {
                filledArray[i*j] = 0;             
                }
            }
        }
    }
    return filledArray.filter(num =&gt; num === 0).length
}</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[배열 내 최빈도값 구하기]]></title>
            <link>https://velog.io/@elena_park/%EB%B0%B0%EC%97%B4-%EB%82%B4-%EC%B5%9C%EB%B9%88%EB%8F%84%EA%B0%92-%EA%B5%AC%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@elena_park/%EB%B0%B0%EC%97%B4-%EB%82%B4-%EC%B5%9C%EB%B9%88%EB%8F%84%EA%B0%92-%EA%B5%AC%ED%95%98%EA%B8%B0</guid>
            <pubDate>Tue, 19 Oct 2021 13:17:36 GMT</pubDate>
            <description><![CDATA[<h3 id="문제">문제</h3>
<p>Array that contains products&#39; price
Please selected the most commonly used price as the output 
-input: [500, 200, 300, 400, 500, 600, 400, 500]
-output: 500</p>
<h3 id="풀이">풀이</h3>
<pre><code>function getCommonlyUsedPrice(array){  
  const counts = array.reduce((a, b)=&gt;{ 
    a[b] = (a[b] || 0) + 1; 
  // 기존에 key로 저장된게 없다면, 0으로 세팅해주고,
  // 기존에 key로 저장된게 있다면, 기존 value에 1을 더한다.
    return a; 
  }, {});

  const keys = Object.keys(counts); 
  let x = keys[0];   
  keys.forEach((val)=&gt;{ 
    if(counts[val] &gt; counts[x]){ 
      x = val; 
    } 
  }); 
  return x; 
}

getCommonlyUsedPrice([500, 200, 300, 400, 500, 600, 400, 500]); // 500 



</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[git archive 명령어로 소스코드 압축하기 ]]></title>
            <link>https://velog.io/@elena_park/git-archive-%EB%AA%85%EB%A0%B9%EC%96%B4%EB%A1%9C-%EC%86%8C%EC%8A%A4%EC%BD%94%EB%93%9C-%EC%95%95%EC%B6%95%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@elena_park/git-archive-%EB%AA%85%EB%A0%B9%EC%96%B4%EB%A1%9C-%EC%86%8C%EC%8A%A4%EC%BD%94%EB%93%9C-%EC%95%95%EC%B6%95%ED%95%98%EA%B8%B0</guid>
            <pubDate>Sun, 20 Jun 2021 17:00:10 GMT</pubDate>
            <description><![CDATA[<p>취업 준비를 하면서 생각보다 많은 곳에서 기술과제를 요청하는 것을 알게 됐다.
보통 깃허브 링크를 요청하거나 파일을 압축해서 메일로 회신을 요청하는 경우가 많은 것 같다.</p>
<p>나는 아래의 명령어로 .git 파일과 node_modules폴더를 제외한 나머지 코드들을 압축했다. 
생각보다 간단했지만 기록 차원에서 남겨두고자 한다.</p>
<pre><code>git archive --format=zip master -o Master.zip</code></pre><p><strong>해석</strong>
git archive --format=zip(zip형태로) master(master브랜치를) -o Master.zip의 이름으로 압축시키겠다는 의미.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[후기] 위코드 2차 프로젝트 후기 (여기어때 클론 프로젝트)]]></title>
            <link>https://velog.io/@elena_park/%ED%9B%84%EA%B8%B0-%EC%9C%84%EC%BD%94%EB%93%9C-2%EC%B0%A8-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%ED%9B%84%EA%B8%B0-%EC%97%AC%EA%B8%B0%EC%96%B4%EB%95%8C-%ED%81%B4%EB%A1%A0-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8</link>
            <guid>https://velog.io/@elena_park/%ED%9B%84%EA%B8%B0-%EC%9C%84%EC%BD%94%EB%93%9C-2%EC%B0%A8-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%ED%9B%84%EA%B8%B0-%EC%97%AC%EA%B8%B0%EC%96%B4%EB%95%8C-%ED%81%B4%EB%A1%A0-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8</guid>
            <pubDate>Sun, 09 May 2021 09:37:05 GMT</pubDate>
            <description><![CDATA[<h1 id="여기어때-클론-프로젝트">여기어때 클론 프로젝트</h1>
<hr>
<h2 id="프로젝트-소개">프로젝트 소개</h2>
<ul>
<li>팀명: 야,여기 어때 </li>
<li>설명: 종합숙박 O2O 서비스 여기어때 사이트 클론 프로젝트</li>
</ul>
<p><img src="https://images.velog.io/images/elena_park/post/6d42f0ea-0f70-460f-8560-85dde2b98801/%EC%97%AC%EA%B8%B0%EC%96%B4%EB%95%8C%20%ED%99%88.png" alt=""></p>
<h2 id="개발-기간">개발 기간</h2>
<ul>
<li>21.4.26 ~ 21.05.07 (11일)</li>
</ul>
<h2 id="개발-인원">개발 인원</h2>
<ul>
<li>프론트엔드: 김효진 박단비 박성은</li>
<li>백엔드: 백승찬 신지원 황수민</li>
</ul>
<h2 id="프론트엔드-기술스택">프론트엔드 기술스택</h2>
<ul>
<li>JavaScript(ES6)</li>
<li>React.JS(함수형 컴포넌트, Hook)</li>
<li>Styled-Component</li>
<li>Kakao Map API</li>
<li>Kakao Login API</li>
<li>JSX(HTML)</li>
</ul>
<h2 id="협업도구">협업도구</h2>
<ul>
<li>Git, Github : 버전관리 및 협업</li>
<li>Trello : 일정 관리</li>
<li>Slack : 비대면 소통</li>
</ul>
<p><img src="https://images.velog.io/images/elena_park/post/b90e8bef-0369-4ee6-a31b-d246d7b24d65/%EC%97%AC%EA%B8%B0%EC%96%B4%EB%95%8C%20%ED%8A%B8%EB%A0%90%EB%A1%9C.png" alt=""></p>
<h2 id="프론트엔드-주요-구현-사항">프론트엔드 주요 구현 사항</h2>
<p>Front-end 3명이서 구현해야할 페이지를 아래와 같이 분담하였다.</p>
<p>(직접 구현✅ 팀원 구현 🟩)</p>
<p>🟩 로그인, 회원가입(일반/소셜 로그인) 및 Navbar
🟩 메인 페이지 및 호텔 리스트 페이지 
✅ 호텔 디테일페이지, 예약 및 예약내역, 리뷰 생성 기능 </p>
<hr>
<h3 id="로그인회원가입일반소셜-로그인-및-navbar-구현">로그인,회원가입(일반/소셜 로그인) 및 Navbar 구현</h3>
<p>🟩 카카오 소셜 로그인/ 로그인에 따른 카카오톡 닉네임 nav bar 표시<img src="https://images.velog.io/images/elena_park/post/ce1548dc-87b2-49f9-8f3c-b4d34eb3548f/Sogin_BetterChoice.gif" alt="">
🟩 휴대폰 인증을 통한 일반 회원가입/로그인<img src="https://images.velog.io/images/elena_park/post/c4c89681-2076-4c3b-8917-5b43d74a1f85/SignUp_BetterChoice.gif" alt=""></p>
<h3 id="메인페이지-및-호텔-리스트-페이지">메인페이지 및 호텔 리스트 페이지</h3>
<p>🟩 메인 페이지 / 숙박유형, 지역, 날짜, 인원수 선택 에 따른 필터링 검색<img src="https://images.velog.io/images/elena_park/post/efbfbee2-733c-42a0-ae51-40a6da43d627/Main_BetterChoice.gif" alt="">
🟩 호텔 리스트 페이지 / 필터링된 호텔 리스트 중 다시 추천순, 평점순, 가격순, 성급별 필터링<img src="https://images.velog.io/images/elena_park/post/f168a3d7-b1ea-4c85-8e35-407ca79326e0/Lists_BetterChoice.gif" alt=""></p>
<h3 id="호텔-디테일페이지-예약-및-예약내역-리뷰-생성-기능">호텔 디테일페이지, 예약 및 예약내역, 리뷰 생성 기능</h3>
<p>✅ 호텔 상세페이지 / 카카오 지도 API를 활용한 지도 표시, 룸 타입에 따른 숙박예약</p>
<p><img src="https://user-images.githubusercontent.com/60565155/120958670-29c79e00-c793-11eb-8943-2af1b6eb273e.gif" alt="Res_BetterChoice"></p>
<p>✅ 상세페이지에서 선택한 룸 예약 및 예약 후 내역 페이지</p>
<p><img src="https://user-images.githubusercontent.com/60565155/117567110-774dde00-b0f5-11eb-8000-bee2f959a7e9.gif" alt="야_여기어때_Trim_예약하기_3(gif)"></p>
<p>✅ 예약을 한 사용자에게만 리뷰쓰기 권한 부여 및 Amazon S3를 이용하여 리뷰등록</p>
<p><img src="https://images.velog.io/images/elena_park/post/1c24d643-cc52-41f2-98b9-b77799ec1027/Review_BetterChoice.gif" alt=""></p>
<h2 id="프로젝트-소감">프로젝트 소감</h2>
<p>위코드에서 진행한 두 번째 클론 프로젝트. 
이번 프로젝트에서는 1차에서 겪었던 문제점을 보완하고자 많이 노력했다.</p>
<p>나는 호텔 디테일 페이지, 예약 및 리뷰 생성 페이지를 맡게 되었다. 이전 프로젝트에서 class형 컴포넌트를 사용하여 작업했기에 이번에 우리팀은 함수형 컴포넌트 및 hooks로, 스타일 작업에서는 기존의 SASS가 아닌 styled-component를 사용하여 구현하기로 했다.</p>
<p>1차와는 다르게 새로운 기술을 적용하는 만큼 공부를 병행하며 작업을 진행해야했다. 함수형을 처음 적용해보았고 초반에는 익숙하게 사용하는 것에 어려움이 있었지만 차츰 익숙해지면서 점차 class형보다 훨씬 간결하고 직관적인 코드를 작성할 수 있어서 좋았다.</p>
<p>styled-component를 이용한 스타일 작업 역시 스타일 파일을 따로 두어 작성하지 않아도 되는 점, 기존의 방식처럼 요소 자체에 class명을 부여하여 스타일링 작업을 하는 것이 아니라 아래와 같이 스타일링 부분 자체에서 props를 받아 로직을 작성하는 조건부 스타일링 처리가 가능한 것 또한 편리해서 좋았다.
<img src="https://images.velog.io/images/elena_park/post/d4f211d0-39d9-45f5-a450-33563c944eca/styledComponentPropsExample.png" alt=""></p>
<p>개인적으로 이번 프로젝트는 1차에서 시행착오를 겪었던 부분을 다시금 단단하게 다질 수 있게 해줌과 동시에 새로운 기술을 습득하는 것에 대한 두려움을 덜게 해준 매우 유의미한 프로젝트였다. </p>
<p>잠깐이었지만 진정 개발자의 삶을 사는 것이 어떠한 것인가에 대해 알 수 있었던 경험이었다.
항상 새로운 기술은 있었고, 내가 이걸 할 수 있을까 두려움이 앞섰던 것은 사실이지만, 결국에는 공부를 해서 적용할 수 있었다는 것, 구현을 해냈다는 사실이 매우 뿌듯하다. </p>
<p>새로움에 대한 두려움을 버리고 도전하는 것, 그것이 개발자가 되기 위한 여러가지 덕목 중 하나가 아닐까 한다.</p>
<hr>
<p>🎬야,여기어때 전체 구현 영상 : <a href="https://www.youtube.com/watch?v=HhGPW_Zb-p4">https://www.youtube.com/watch?v=HhGPW_Zb-p4</a></p>
<p>🎈야,여기어때 프론트엔드 깃헙 주소 : <a href="https://github.com/wecode-bootcamp-korea/19-2nd-betterChoice-frontend">https://github.com/wecode-bootcamp-korea/19-2nd-betterChoice-frontend</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[후기] 위코드 1차 프로젝트 후기 (그리팅몰 클론 프로젝트)]]></title>
            <link>https://velog.io/@elena_park/%ED%9B%84%EA%B8%B0-%EC%9C%84%EC%BD%94%EB%93%9C-1%EC%B0%A8-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%ED%9B%84%EA%B8%B0-%EA%B7%B8%EB%A6%AC%ED%8C%85%EB%AA%B0-%ED%81%B4%EB%A1%A0-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8</link>
            <guid>https://velog.io/@elena_park/%ED%9B%84%EA%B8%B0-%EC%9C%84%EC%BD%94%EB%93%9C-1%EC%B0%A8-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%ED%9B%84%EA%B8%B0-%EA%B7%B8%EB%A6%AC%ED%8C%85%EB%AA%B0-%ED%81%B4%EB%A1%A0-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8</guid>
            <pubDate>Tue, 27 Apr 2021 04:56:35 GMT</pubDate>
            <description><![CDATA[<h1 id="그리팅몰-클론-프로젝트">그리팅몰 클론 프로젝트</h1>
<hr>
<h2 id="프로젝트-소개">프로젝트 소개</h2>
<ul>
<li>팀명: Greatingdor</li>
<li>설명: 건강식 식단 및 식자재 판매 플랫폼인 그리팅몰(greating mall) 사이트 클론 프로젝트</li>
<li>그리팅몰 original website (<a href="https://www.greating.co.kr">https://www.greating.co.kr</a>)</li>
</ul>
<p><img src="https://images.velog.io/images/elena_park/post/09c32465-1e57-4c15-9ce9-6af103b0010b/%EA%B7%B8%EB%A6%AC%ED%8C%85%EB%AA%B0%20original%20main.png" alt=""></p>
<h2 id="개발-기간">개발 기간</h2>
<ul>
<li>21.04.12 ~ 21.04.23 (11일)<h2 id="개발-인원">개발 인원</h2>
</li>
<li>프론트엔드: 박성은 박세리 이명진</li>
<li>백엔드: 이서진 이윤형 함경재</li>
</ul>
<h2 id="프론트엔드-기술스택">프론트엔드 기술스택</h2>
<ul>
<li>JavaScript(ES6)</li>
<li>React.JS</li>
<li>React-Router</li>
<li>Sass </li>
<li>HTML, CSS</li>
</ul>
<h2 id="백엔드-기술스택">백엔드 기술스택</h2>
<ul>
<li>Python</li>
<li>Django Web Framework </li>
<li>Token: Bcrypt, JWT</li>
<li>Database: MySQL</li>
</ul>
<h2 id="협업도구">협업도구</h2>
<ul>
<li>Git, Github : 버전관리 및 협업</li>
<li>Trello : 일정 관리</li>
<li>Slack : 비대면 소통</li>
</ul>
<p><img src="https://images.velog.io/images/elena_park/post/81f6a6b6-c5b5-4c94-b0ee-9a0dae290938/%EA%B7%B8%EB%A6%AC%ED%8C%85%EB%8F%84%EB%A5%B4%20Trello.png" alt=""></p>
<h2 id="프론트엔드-주요-구현-사항">프론트엔드 주요 구현 사항</h2>
<p>(직접 구현✅ 팀원 구현 🟩)</p>
<h3 id="회원가입로그인-페이지">회원가입/로그인 페이지</h3>
<p>🟩 회원가입 기능 : fetch를 이용하여 백엔드와 통신. POST method로 회원정보를 서버에 보내고 서버에 성공적으로 전달이 되는 경우 success라는 message가 뜨며 로그인 페이지로 이동
 <img src="https://user-images.githubusercontent.com/60565155/116185430-91cea180-a75c-11eb-885d-b4c8fad2a98c.gif" alt="회원가입"></p>
<p>🟩 로그인 기능 : 서버로부터 회원가입이 된 회원 정보를 받아온 뒤 로그인 구현
<img src="https://images.velog.io/images/elena_park/post/25ce9678-de9f-4871-afa1-06fb07373b60/%EB%A1%9C%EA%B7%B8%EC%9D%B8.gif" alt=""></p>
<h3 id="메인-상품-리스트-페이지">메인 상품 리스트 페이지</h3>
<p>🟩 광고 배너 제작 : 광고 배너 코드 구현
<img src="https://images.velog.io/images/elena_park/post/3ebcabf7-59e4-49ae-8bb1-26a378f43277/%EA%B4%91%EA%B3%A0%EB%B0%B0%EB%84%88.gif" alt=""></p>
<p>🟩 제품 카드 제작 : 상세페이지로의 연결 및 제품 간략 정보를 담은 제품 카드 구현 
🟩 제품 카테고리 필터 기능 : 제품 종류를 토대로 필터가 되는 기능 구현
<img src="https://user-images.githubusercontent.com/60565155/116186258-3b626280-a75e-11eb-8559-b1dda404d20b.gif" alt="카테고리_Trim"></p>
<p>🟩 제품 페이지네이션 기능 : 제품 수량이 많을 경우 페이지 넘버를 통해 이전, 다음 페이지를 탐색
<img src="https://user-images.githubusercontent.com/60565155/116187048-c132dd80-a75f-11eb-9792-9ad0310a40ad.gif" alt="페이지네이션"></p>
<h3 id="공용컴포넌트-구현">공용컴포넌트 구현</h3>
<p>✅ Navbar : 카테고리 및 검색창 드롭다운 구현, 검색창 아이템 다중선택 구현 (검색 기능은 2차 프로젝트 진행 후 추가 구현 예정)
✅ Footer : 외부 링크 연결 
<img src="https://user-images.githubusercontent.com/60565155/116176075-75c30400-a74c-11eb-9740-53ed8f09f0ee.gif" alt="네브바"></p>
<h3 id="상품-상세-페이지">상품 상세 페이지</h3>
<p>✅ 동적 라우팅 이용하여 상품 리스트에서 클릭한 아이템에 해당하는 data 호출하여 상세페이지 구현 
✅ 장바구니, 구매하기 클릭 시 옵션 모달창 생성 및 수량 증감 구현
✅ 상세페이지 하단 메뉴 탭 구현 및 각 탭에 해당하는 data 출력 (상품정보,교환/반품 탭에서는 우선 클릭 제품의 id 번호를 반영한 이미지를 임시로 사용하였음)
✅ 상품후기, 상품문의 리스트 드롭다운 구현
<img src="https://user-images.githubusercontent.com/60565155/116176110-87a4a700-a74c-11eb-925c-276c5c8b7ebf.gif" alt="상세"></p>
<h2 id="기억하고-싶은-코드">기억하고 싶은 코드</h2>
<p><img src="https://user-images.githubusercontent.com/60565155/116176110-87a4a700-a74c-11eb-925c-276c5c8b7ebf.gif" alt="상세"></p>
<p>상세페이지에서 하단 각 Tab을 클릭할 때마다 어떻게 서로 다른 컨텐츠를 보여줘야 하는지 고민이 되었다. 멘토님을 통해 객체에 특정 값을 맵핑하는 것을 알게되어 메뉴탭을 구현할 수 있었다.</p>
<p><img src="https://images.velog.io/images/elena_park/post/c065edbb-2ef4-4883-ae66-36877f145b9e/1%EC%B0%A8%20%EA%B8%B0%EC%96%B5%ED%95%98%EA%B3%A0%EC%8B%B6%EC%9D%80%20%EC%BD%94%EB%93%9C.png" alt=""></p>
<p>먼저 CATEGORY_ARR라는 값이 변하지 않는 배열을 선언해주고, 해당 배열 안에 각 TAB의 이름이 될 값들을 넣어준다. </p>
<p>return문 안에서 해당 배열을 map으로 돌리며 중복이 발생될 수 있는 코드를 깔끔하게 구현할 수 있었다. 각 <code>&lt;li&gt;</code> 태그에는 map 함수의 두번 째 인자로 부여되는 index값을 이용하여 key prop 및 onClick이벤트 발생 시 사용될 수 있게 하였다. </p>
<p>state에는 currentId를 정의하여 페이지 최초 렌더 시 보여줄 탭인 1을 할당되었는데, 해당 currentId는 각 <code>&lt;li&gt;</code>태그를 클릭할때마다 부여된 onClick이벤트인 clickHandler함수를 통해 클릭된 TAB의 index에 1이 더해진 값으로 재할당된다. </p>
<p>이 과정을 통해 <code>{TAB_OBJ[this.state.currentId]}</code>의 currentId는 재할당된 state 값이 적용되어, 클린된 TAB에 해당되는 컨텐츠를 보여주는 방식이다. </p>
<p>이렇게 객체 맵핑을 이용하여 컨텐츠를 보여주는 방식이 매우 신선하여 기억하고 싶은 코드로 선정하게 되었다.</p>
<h2 id="프로젝트-소감">프로젝트 소감</h2>
<p>이번 1차 프로젝트는 React 라이브러리를 이용하여 본격적으로 진행한 첫 팀 프로젝트로서 기대도 컸지만 동시에 내가 제대로 1인분을 해낼 수 있을 지 두려움도 많았던 프로젝트였다. </p>
<p>우리 팀은 더도말고 덜도말고 기본에만 충실하자라는 일념 하에 필요한 기능만 우선적으로 배분하여 구현하기로 하고 시간이 남으면 추가 구현을 진행하기로 했다. 그리고 매일 백엔드, 프론트엔드 구성원 모두 스탠드업 미팅을 진행하면서 진행상황을 공유하면서 프로젝트를 체계적으로 진행해나갔다.</p>
<p>하지만 11일의 마감 기한 내에 프로젝트를 완성해야하는 만큼 기한에 대한 압박이 상당했다. 게다가 코드를 제대로 치지 못하고 반나절, 하루를 보냈을 때에는 스트레스를 너무 많이 받아 그러한 모습이 겉으로 표출되어 팀원들에게도 많이 미안했던 기억이 있다. </p>
<p>그러나 퍼포먼스 코치님과 팀 LOVE 면담을 진행했을 때 너무 좋은 팀웍을 가진 팀으로 보인다는 평가를 받았던 우리 팀원들은, 그 평가에 걸맞게 서로를 압박하지 않고 독려해주며 프로젝트를 이끌어나갔다.</p>
<p>그렇게 1차 프로젝트는 마무리되었지만 2차 프로젝트가 끝나면 다시 모여서 1차를 다듬기로 약속했고, 그 전까지 각자의 2차 프로젝트 팀에 집중하기로 했다.</p>
<p>개인적으로 퍼포먼스를 잘 내지 못했던 것에 아쉬움이 많았던 프로젝트여서 다시 보완하고 다듬는 것에 기대가 된다. 바로 2차를 시작하지만 1차에서 좋았던 점은 다시 적용해보고, 아쉬웠던 부분은 보완해나가고자 한다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL 27 | 인증, 인가 세션 정리]]></title>
            <link>https://velog.io/@elena_park/TIL-27-%EC%9D%B8%EC%A6%9D-%EC%9D%B8%EA%B0%80-%EC%84%B8%EC%85%98</link>
            <guid>https://velog.io/@elena_park/TIL-27-%EC%9D%B8%EC%A6%9D-%EC%9D%B8%EA%B0%80-%EC%84%B8%EC%85%98</guid>
            <pubDate>Sun, 11 Apr 2021 10:49:56 GMT</pubDate>
            <description><![CDATA[<h1 id="인증과-인가">인증과 인가</h1>
<h2 id="인증은-무엇이고-왜-해야할까">인증은 무엇이고 왜 해야할까?</h2>
<h3 id="인증authentication">인증(Authentication)</h3>
<ul>
<li>로그인 절차에서 정확한 이메일/비밀번호 조합을 입력했는지 확인하는 과정<h3 id="인증은-왜-필요할까">인증은 왜 필요할까?</h3>
</li>
<li>해당 서비스를 누가, 어떻게 사용하는지 추적이 가능하도록 함<h3 id="인증에-필요한-정보">인증에 필요한 정보</h3>
</li>
<li>아이디,이메일주소,비밀번호</li>
<li>여기서 가장 중요한 것은 비밀번호이다.(암호화의 과정이 필요하다)<h3 id="비밀번호는-어떻게-관리할까">비밀번호는 어떻게 관리할까?</h3>
</li>
<li>법규상의 강제가 필요하다
개인정보의 암호화등을 통해 개인정보 취급자의 실수 또는 해커의 공격 등으로 인해 개인정보가 비인가자에게 유출,노출되더라도 그 내용 확인을 어렵게 하는 보안기술이 필요</li>
<li>Database에 저장 시 개인 정보를 해싱하여 복원할 수 없도록 함</li>
</ul>
<h3 id="암호화는-어떻게-할까">암호화는 어떻게 할까?</h3>
<h4 id="단방향-해쉬">단방향 해쉬</h4>
<ul>
<li>본래 해쉬함수는 자료구조에서 빠른 자료의 검색, 데이터의 위변조 체크를 위해서 쓰이지만, <strong>복원이 불가능한 단방향 해쉬함수는 암호학적 용도로 사용</strong>된다.
ex) 사용자가 비밀번호로 hello라는 string을 전달하면 해쉬함수는 암호화 알고리즘을 통해서 아무도 알 수 없는 랜덤한 string을 리턴한다. 단방향 해쉬는 이렇게 암호화된 string을 다시 hello로 바꿀 수 없다.
(cf.반대로 양방향 해쉬는 암호화된 string을 다시 원래의 hello로 바꿀 수 있는 것을 의미한다.)</li>
<li>결과만 봐서는 당장 식별이 불가능하므로 완벽해보일 수 있다.</li>
<li>SHA-256, MD5, SHA-1 등의 종류가 있는데 보통 SHA-256을 사용한다.</li>
</ul>
<h4 id="단방향-해쉬의-단점">단방향 해쉬의 단점</h4>
<ul>
<li>이러한 단방향 해쉬는 같은 알고리즘으로 같은 비밀번호를 다시 해싱하면 항상 같은 결과가 도출된다. </li>
<li>이와 같은 허점을 이용해서 가능한 경우의 수를 모두 해시값으로 만들어서 판매하는 서비스도 생기는 등의 단점이 있다. </li>
</ul>
<h4 id="salting--keystretching">SALTING &amp; KeyStretching</h4>
<p><img src="https://images.velog.io/images/elena_park/post/3f183941-bb4f-45b7-831c-9d5c107fdb70/saltingKeyStretching.png" alt=""></p>
<ul>
<li>단방향 해쉬의 단점을 보완하고자 나온 <strong>입력한 비밀번호와 임의로 생성한 문자열(Salt)을 합쳐서 해싱하여 이 해시값을 저장하는 방법</strong></li>
<li>단순 해쉬값이 해킹에 쉽게 노출되므로 Salting이라는 아이디어가 등장함</li>
<li>비교를 위해 결과 값에는 항상 해시 값과 Salt 값을 같이 저장함 </li>
<li><strong>여기에서 해커가 비밀번호 무작위 대입을 통해 해시값을 계산하는데 필요한 시간을 대폭 늘리기 위해 Salting 및 해싱을 여러번 반복해서 원본 값을 유추하기 어렵게 만드는 것이 Key Stretching 개념</strong></li>
</ul>
<h5 id="bcrypt">bcrypt</h5>
<p><img src="https://images.velog.io/images/elena_park/post/2c0fab57-1ad5-46dc-85f3-13a7340c3628/bcrypt.png" alt=""></p>
<ul>
<li>Salting &amp; Key Stretching의 대표적인 오픈소스 라이브러리</li>
<li>다양한 언어 지원, 사용이 간편하여 쉽게 적용 가능</li>
</ul>
<h2 id="인가는-무엇이고-왜-해야할까">인가는 무엇이고 왜 해야할까?</h2>
<h3 id="인가authorization">인가(Authorization)</h3>
<ul>
<li>사용자가 서버에 요청을 보내면 인증 과정을 거쳐 확인된 사용자가 맞는지 확인하는 과정<h3 id="인가는-왜-필요할까">인가는 왜 필요할까?</h3>
</li>
<li>HTTP의 Stateless한 특성 때문에 필요함 (과거의 상태를 기록하지 않는 성질)</li>
</ul>
<blockquote>
<p><strong>그렇다면, HTTP는 Stateless한데 서버에서 요청을 받으면 사용자가 로그인한 상태인지 어떻게 알 수 있을까?</strong></p>
</blockquote>
<ul>
<li>매 HTTP 요청마다 <strong>headers를 활용하여 사용자가 인증 절차를 거친 사용자임을 증명하는 정보를 담아서 보내는 방법</strong>: authorization이라는 key에 해당 정보를 담는다</li>
</ul>
<h3 id="실제로-통신이-어떻게-이루어질까">실제로 통신이 어떻게 이루어질까?</h3>
<h4 id="기존-방식">기존 방식</h4>
<p><img src="https://images.velog.io/images/elena_park/post/d8113b5d-97b8-4033-b36f-090a2cb61b5e/%EC%9D%B8%EC%A6%9D%EC%9D%B8%EA%B0%80(%EA%B8%B0%EC%A1%B4).png" alt=""></p>
<h4 id="기존-방식의-단점">기존 방식의 단점</h4>
<p><img src="https://images.velog.io/images/elena_park/post/d886bb32-ba28-4b07-bd85-260a7b57c4c2/123.png" alt=""></p>
<ul>
<li>분산 서버시스템일 경우 Session이 한 쪽 서버에만 저장되어있는 경우 다른 서버들에서는 해당 정보를 알 수 없다.</li>
</ul>
<h4 id="기존-방식의-단점을-보완하기-위한-json-web-tokenjwt의-등장">기존 방식의 단점을 보완하기 위한 JSON Web Token(JWT)의 등장</h4>
<p><img src="https://images.velog.io/images/elena_park/post/0beee2df-f181-4c7e-8171-d0d1c002b060/HW.png" alt=""></p>
<ul>
<li><p>JavaScript 구조로 되어있는 웹 토큰</p>
</li>
<li><p>*<em>헤더(header)에 들어가는 정보 *</em></p>
<ol>
<li>토큰의 타입과 해시 알고리즘의 정보<ol start="2">
<li>BASE64 방식으로 인코딩(암호화는 아니고 다른 방식으로 바꾼 것임)해서 JWT의 가장 첫 부분에 기록됨</li>
</ol>
</li>
<li>예시: <code>{&quot;alg&quot; : &quot;HS256&quot;, &quot;typ&quot;:&quot;JWT&quot;}</code></li>
</ol>
</li>
<li><p>*<em>내용(Payload)에 들어가는 정보 *</em></p>
<ol>
<li>exp와 같이 웹 토큰의 만료시간을 나타나는 공개적인 내용</li>
<li>클라이언트와 서버간 협의 하에 사용되는 비공개적 내용 (Primary key의         id 등)</li>
<li>그 외 어떤 내용이던 상관없이 추가 가능</li>
<li>암호화가 아닌 BASE64로 인코딩하며 JWT의 두 번째 요소에 위치</li>
<li>예시: <code>{&quot;user-id&quot;:1, &quot;iat&quot;:1539517391}</code> </li>
</ol>
</li>
<li><p><strong>서명(Signature)에 들어가는 정보</strong></p>
<ol>
<li>JWT의 무결성을 확인(JWT가 원본 그대로라는 것을 확인)</li>
<li>토큰의 발행 주체는 백엔드로, 백엔드에서 패스워드 암호화, JWT 생성</li>
<li>실제로 백엔드에서 JWT 토큰을 만들어서 프론트에 전달하면 프론트는 보통     Cookie, local storage, session storage에 저장하게 됨</li>
<li>서명에서는 <strong>BASE64URL 인코드된 헤더와 내용</strong> 그리고 <strong>JWT Secret     Key</strong>(별도로 생성함)을 <strong>헤더에 지정된 암호 알고리즘으로 암호화하여 전송    한다</strong>.(복호화 가능)</li>
<li>프론트엔드가 JWT를 백엔드 API 서버로 전송하면 서버에서는 전송받은 JWT    의 서명부분을 복호화하여 서버에서 생성한 JWT가 맞는지 확인한다. 이는 마치 계    약서의 위변조를 막기 위해 서로 사인하는 것과 동일한 것임</li>
<li>헤더와 내용은 암호화가 아닌 BASE64 인코딩한 것이므로** 디코딩을 하면 누구나 원본을 볼 수 있으므로 개인정보를 담으면 안됨**</li>
</ol>
</li>
</ul>
<h4 id="json-web-token의-예시">JSON Web Token의 예시</h4>
<p><img src="https://images.velog.io/images/elena_park/post/1ad34210-e266-43cb-983a-230a0c346117/JWToken%EC%98%88%EC%8B%9C.png" alt=""></p>
<ul>
<li>프론트에서 이 token을 받으면 Cookie, Local Storage, Session Storage 셋 중 한 군데에 저장하여 HTTP 통신 시 headers 부분에 key와 value로서 이 token을 넣어 보내면, 서버에서 확인 과정을 통해 인가가 진행된다. </li>
</ul>
<h4 id="json-web-token의-활용">JSON Web Token의 활용</h4>
<p><img src="https://images.velog.io/images/elena_park/post/33805544-99ed-480f-8987-5faafd7ad0a7/jWT%EC%98%88%EC%8B%9C.png" alt=""></p>
<h4 id="기존-방식의-단점을-어떻게-보완하는가">기존 방식의 단점을 어떻게 보완하는가?</h4>
<p><img src="https://images.velog.io/images/elena_park/post/16fca68d-b645-4fdd-b42b-e5a1d9548f3f/jWT%EA%B8%B0%EC%A1%B4%EB%8B%A8%EC%A0%90%EB%B3%B4%EC%99%84.png" alt=""></p>
<ul>
<li>서버들끼리 다같이 똑같은 Secret key를 공유하여 같은 키로 계속 암호화, 복호화가 가능하게 된다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL 26 | HTTP 세션 정리]]></title>
            <link>https://velog.io/@elena_park/TIL-26-HTTP-%EC%84%B8%EC%85%98-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@elena_park/TIL-26-HTTP-%EC%84%B8%EC%85%98-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Sun, 11 Apr 2021 09:40:23 GMT</pubDate>
            <description><![CDATA[<h1 id="http란-">HTTP란 ?</h1>
<p>HyperText: 문서와 문서가 링크로 연결되어있음
Transfer : 전송하다 = HTML로 만든 웹페이지 문서를 보낸다
Protocol : 컴퓨터끼리 어떻게 HTML 파일을 주고받을지에 대한 소통방식 또는 약속</p>
<p>=&gt; 내가 만들어놓은 HTML문서를 어떻게 전송할 것인지에 대한 약속</p>
<h1 id="http는-어떻게-동작하는가">HTTP는 어떻게 동작하는가?</h1>
<h2 id="특징">특징</h2>
<h3 id="1-request---response-요청---응답">1. Request - Response (요청 - 응답)</h3>
<p>소통의 핵심은 요청과 응답
인간의 소통방식이 컴퓨터 끼리의 소통방식에도 적용된 것
<strong>HTTP 요청과 응답은 그저 메세지에 불과하다</strong>
요청,응답 모두 TEXT로 구성된다</p>
<h3 id="2-stateless--state상태--less없음">2. Stateless = State(상태) + less(없음)</h3>
<blockquote>
<p>HTTP 통신은 <strong>과거의 HTTP통신에 대한 내용을 전혀! 알지 못한다</strong> :</p>
</blockquote>
<ul>
<li>HTTP통신은 요청을 보내면 응답을 받는다.</li>
<li>하나하나의 요청이 전부 서로 연관성을 갖지 않고 독립적이다.</li>
<li>따라서 A요청 이후 B요청이 일어나면 B는 A를 기억하지 못한다.</li>
<li>이와 같이 A에 대한 기록이 이루어지지 않는 것을 Stateless라고 한다.</li>
<li>따라서 매 통신마다 필요한 모든 정보를 담아서 요청을 보낸다. </li>
</ul>
<h3 id="http-특징-예시">HTTP 특징 예시</h3>
<p>ex) 나는 로그인 상태에서 zoom 회의 참여하기를 클릭해서 접속을 한다.
이때 브라우저는 zoom 서버에게 &quot;나는 ~야, 나 접속할게&quot;라는 메세지를 계속 전달해주는 것</p>
<blockquote>
<p><strong>Token의 등장</strong>
위와 같이 매번 정보를 전달하는 작업이 번거로워, Token이 등장하게 됨. 한번 로그인을 하고 나서 서버에서 Token을 받으면 이후에는 내 모든 정보를 전달하지 않고도 서버에게 미리 받은 Token을 보여주며 입장할 수 있다.</p>
</blockquote>
<h1 id="http-메시지의-구조">HTTP 메시지의 구조</h1>
<p><img src="https://images.velog.io/images/elena_park/post/e8d52794-757d-4d90-924d-e849b7af9646/http%20requset%20%EB%A9%94%EC%84%B8%EC%A7%80.png" alt=""></p>
<ol>
<li>Start Line</li>
</ol>
<ul>
<li>요청의 상태 </li>
<li>메서드(메세지를 보내는 방식:GET,POST..) / URL(/test/test) / 버전(HTTP/1.1)</li>
</ul>
<ol start="2">
<li>Headers</li>
</ol>
<ul>
<li>요청에 대한 추가 정보 (metadata)</li>
</ul>
<ol start="3">
<li>Body</li>
</ol>
<ul>
<li>요청의 실제 정보</li>
</ul>
<p><img src="https://images.velog.io/images/elena_park/post/7663fff8-ed38-4b51-b8c5-b87837e29fb0/HTTP%20response%EB%A9%94%EC%84%B8%EC%A7%80.png" alt="">1. Status Line</p>
<ul>
<li>응답의 상태 </li>
<li>버전(HTTP/1.1)/ 상태코드(200)/ 텍스트(OK: 상태에 대한 설명)</li>
<li>단순히 Client에게 응답하는 것이므로 타겟(url)은 필요 없음</li>
</ul>
<ol start="2">
<li>Headers</li>
</ol>
<ul>
<li>응답에 대한 추가 정보 (metadata)</li>
</ul>
<ol start="3">
<li>Body</li>
</ol>
<ul>
<li>응답의 실제 정보</li>
</ul>
<blockquote>
<p>*<em>200 OK의 의미? *</em>
클라이언트로부터 Request를 받아서 Response를 잘 했을 때의 상태코드</p>
</blockquote>
<h2 id="주로-사용되는-http-request-메소드">주로 사용되는 HTTP Request 메소드</h2>
<h3 id="get">GET</h3>
<p><img src="https://images.velog.io/images/elena_park/post/0f91e331-7326-406f-9547-a79408bed525/httpGet.png" alt=""></p>
<ul>
<li>데이터를 받아오기만 할 때
ex) 웹 페이지에 접속해서 필요한 데이터를 받아오기만 할 때</li>
<li>Body에 데이터를 같이 보낼 필요가 없다<h3 id="post">POST</h3>
<img src="https://images.velog.io/images/elena_park/post/b870b5f6-07f4-4a43-97ac-8a4812190dce/httpPost.png" alt=""></li>
<li>데이터를 생성 / 수정할 때</li>
<li>Body에 담는 내용이 핵심이다
ex) 로그인 시 유저 아이디, 패스워드를 보낼 때
ex) 이미지 예시와 같이 제품을 보다가 장바구니에 넣었을 때, 장바구니에 해당 제품을 보낼 때 (body에 제품 구매에 대한 데이터를 담아서 보내면, 서버에서 Response로서 사용자가 보낸 해당 데이터를 받아서 사용자 계정의 장바구니 안에 제품을 저장시켜주는 것)<h3 id="delete">DELETE</h3>
<img src="https://images.velog.io/images/elena_park/post/344a5b02-316e-43e6-85c2-9cebf1429015/httpDelete.png" alt=""></li>
<li>서버에 저장된 특정 데이터를 삭제할 때</li>
<li>Body에 데이터를 같이 보낼 필요가 없다</li>
</ul>
<h3 id="이외에도-여러가지-메소드가-있다">이외에도 여러가지 메소드가 있다</h3>
<ul>
<li>PUT, OPTION.. </li>
</ul>
<h2 id="주로-사용되는-http-response-상태코드">주로 사용되는 HTTP Response 상태코드</h2>
<p>200 : OK
201 : CREATED
400 : BAD REQUEST (클라이언트에서 요청 시 문제가 발생)
401 : UNAUTHORIZED (로그인을 해야하는데 로그인이 되지 않은 경우)
403 : FORBIDDEN (일반 사용자가 관리자 페이지를 가려고 할 때, 즉 권한이 없을 때)
404 : NOT FOUND (URL이 없을 때)
405 : METHOD NOT ALLOWED (메소드가 잘못되었을 때)
500 : INTERNAL SERVER ERROR (클라이언트에서 요청 시 발생한 문제는 없으나 서버에서 문제가 발생한 경우)</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL 25 | 데이터베이스 세션 정리]]></title>
            <link>https://velog.io/@elena_park/TIL-25-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4-%EC%84%B8%EC%85%98-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@elena_park/TIL-25-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4-%EC%84%B8%EC%85%98-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Sun, 11 Apr 2021 08:23:43 GMT</pubDate>
            <description><![CDATA[<h1 id="데이터베이스database란">데이터베이스(Database)란?</h1>
<hr>
<h2 id="데이터베이스의-기초">데이터베이스의 기초</h2>
<ul>
<li>컴퓨터 시스템에 저장된 정보 또는 데이터(data)의 집합을 의미</li>
<li>데이터베이스는 보통 <strong>데이터베이스 관리시스템(DBMS)으로 제어</strong>함</li>
<li>이렇게 데이터와 DBMS는 연관된 어플리케이션과 함께 &#39;데이터베이스 시스템&#39;으로 일컬어지며, 더 짧게는 &#39;데이터베이스&#39;라고 통칭되기도 함</li>
<li>Application에서는 데이터가 <strong>메모리 상</strong>에 존재하는데, 메<strong>모리에 존재하는 데이터는 장기 보존이 되지 않으므로 app이 종료되면 해당 메모리에 있던 데이트를 다시 읽어들일 수 없다.</strong></li>
<li>따라서 <strong>데이터를 오랜기간 저장 및 보존하기 위해서 데이터베이스를 사용하는 것</strong>이다.</li>
</ul>
<hr>
<h2 id="데이터베이스의-종류">데이터베이스의 종류</h2>
<h3 id="관계형-데이터베이스-rdbms-relational-database-management-system">관계형 데이터베이스 (RDBMS, Relational Database Management System)</h3>
<ul>
<li><p>대표적인 RDBMS : Oracle, MySQL, PostgreSQL 등</p>
<blockquote>
<p>*<em>SQL이란 ? *</em>
(Structured Query Language)
데이터베이스를 조회하거나,생성,관리하기 위해 나온 하나의 언어.</p>
</blockquote>
</li>
<li><p>관계형 데이터란 데이터를 서로 상호관련성을 가진 형태로 표현한 데이터를 의미.</p>
</li>
<li><p>모든 데이터들은 2차원 테이블로 표현할 수 있음.</p>
</li>
<li><p>각각의 테이블은 칼럼(column)과 로우(row)로 구성됨.
  컬럼: 테이블의 각 항목을 의미 (열의 기준이 되는 항목 이름)
  로우: 각 항목들의 실제 값을 의미 
  각 로우는 저만의 고유 키(Primary key)를 가짐. 주로 이 primary key를 통해 해당 로우를 찾거나 인용(reference)하게 됨.</p>
</li>
<li><p>각각의 테이블들은 <strong>서로 상호관련성을 가지고 서로 연결될 수 있음</strong>.</p>
</li>
</ul>
<ol>
<li><strong>일대일(one to one)</strong>: 테이블 A의 로우와 테이블 B의 로우가 정확히 일대일 매칭이 되는 관계
<img src="https://images.velog.io/images/elena_park/post/256af911-98a8-4c24-a0f5-e2870116d869/DB%EC%9D%BC%EB%8C%80%EC%9D%BC.png" alt=""><ul>
<li>user_profile 테이블에서 users 테이블의 id를 참조하고있다. </li>
<li>내 기준에서 외래키(Foreign key)내가 가지고 있지 않은, 다른 테이블이 가지고있는 기본값을 내가 사용할 때 외래키라고 함)가 저쪽 테이블(내가 참조하려는 테이블)의 기본키(Primary key)를 사용한다. </li>
</ul>
</li>
<li><strong>일대다(one to many)</strong>: 테이블 A의 로우가 테이블 B의 여러 로우와 연결이 되는 관계
 <img src="https://images.velog.io/images/elena_park/post/29c5f34f-6088-4558-a881-d75332bbc900/DB%EC%9D%BC%EB%8C%80%EB%8B%A4.png" alt=""></li>
<li><strong>다대다(many to many)</strong>: 테이블 A의 여러 로우가 테이블 B의 여러 로우와 연결이 되는 관계
<img src="https://images.velog.io/images/elena_park/post/0fff0364-921f-48b6-bf39-b9f58391a2c2/DB%EB%8B%A4%EB%8C%80%EB%8B%A42.png" alt=""></li>
</ol>
<ul>
<li>일대일/일대다의 혼합 </li>
<li>데이터베이스를 쓰면서 제일 중요한 것: <strong>중복의 배제</strong></li>
<li>테이블들을 연결하는 이유?<ul>
<li>하나의 테이블에 모든 정보를 다 넣으면 동일한 정보들이 불필요하게 중복 저장됨.</li>
<li>이 경우 더 많은 디스크를 사용하면서 잘못된 데이터가 저장될 가능성이 높아짐.</li>
<li>따라서 테이블을 연결하면 중복된 데이터를 저장하지 않음으로 디스크를 더 효율적으로 쓰게되고,</li>
<li>서로 같은 데이터이지만 부분적으로만 내용이 다른 데이터가 생기는 문제가 사라지는데, 이것을 <strong>정규화(normalization)</strong>라고 함.</li>
</ul>
</li>
</ul>
<h3 id="비관계형-데이터베이스-non-relational-database-management-system">비관계형 데이터베이스 (Non-relational Database Management System)</h3>
<ul>
<li>대표적인 Non-RDBMS : MongoDB, Redis, Cassandra 등</li>
<li>NoSQL: 처음에는 SQL문이 사용되지 않는다는 의미에서 NoSQL이었지만 현재는 SQL이 지원되기 시작하여 Not Only SQL이라는 의미의 NoSQL로 사용되고 있다.</li>
<li>비관계형 타입의 데이터를 저장할 때 주로 사용되는 DBMS</li>
<li>관계형 데이터베이스와 다르게 비관계형이므로 데이터들을 저장하기 전 정의할 필요가 없음</li>
</ul>
<hr>
<h2 id="acid">ACID</h2>
<blockquote>
<p>트랜잭션이란? (Transaction)
일련의 작업들을 한번에 하나의 unit으로 실행하는 것 </p>
</blockquote>
<h3 id="atomicity-원자성">Atomicity (원자성)</h3>
<p>트랜잭션과 관련된 작업들이 부분적으로 실행되다가 중단되지 않는 것을 보장하는 능력</p>
<h3 id="consistency-일관성">Consistency (일관성)</h3>
<p>트랜잭션이 실행을 성공적으로 완료하면 언제나 일관성있는 데이터베이스 상태로 유지하는 것</p>
<h3 id="isolation-고립성">Isolation (고립성)</h3>
<p>트랜잭션을 수행 시 다른 트랜잭션의 연산 작업이 끼어들지 못하도록 보장하는 것 </p>
<h3 id="durability-지속성">Durability (지속성)</h3>
<p>성공적으로 수행된 트랜잭션은 영원히 반영되어야 함을 의미</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL 24 | [React 기초] map 함수 적용 시 key props를 부여하는 이유]]></title>
            <link>https://velog.io/@elena_park/TIL-24-React-%EA%B8%B0%EC%B4%88-map-%ED%95%A8%EC%88%98-%EC%A0%81%EC%9A%A9-%EC%8B%9C-key-props%EB%A5%BC-%EB%B6%80%EC%97%AC%ED%95%98%EB%8A%94-%EC%9D%B4%EC%9C%A0</link>
            <guid>https://velog.io/@elena_park/TIL-24-React-%EA%B8%B0%EC%B4%88-map-%ED%95%A8%EC%88%98-%EC%A0%81%EC%9A%A9-%EC%8B%9C-key-props%EB%A5%BC-%EB%B6%80%EC%97%AC%ED%95%98%EB%8A%94-%EC%9D%B4%EC%9C%A0</guid>
            <pubDate>Sun, 04 Apr 2021 07:08:26 GMT</pubDate>
            <description><![CDATA[<h1 id="map함수-적용-시-key-속성-부여하는-이유">map함수 적용 시 key 속성 부여하는 이유</h1>
<p><img src="https://images.velog.io/images/elena_park/post/85de72bd-b3bb-40f2-87be-c83987155544/react-unique%20key(ul%20tag-without%20key).png" alt=""></p>
<p><img src="https://images.velog.io/images/elena_park/post/5c92daba-e5a4-4408-81a9-c8e797e99de5/react-unique%20key.png" alt=""></p>
<p><img src="https://images.velog.io/images/elena_park/post/7daf6e76-2640-41a3-bcfe-b99ac337aafa/react-unique%20key(ul%20tag).png" alt=""></p>
<p>기존에 JavaScript로 구현한 Westagram을 React로 이전하는 작업 진행 중 주어진 assignment로 댓글 기능을 구현하던 도중, 두번째 이미지와 같은 warning 메세지를 받았다. 메세지를 보니 <code>&lt;ul&gt; 및 &lt;li&gt;</code> 태그를 사용할 때 list 태그에는 key 속성이 필수적으로 부여되어야하는 것으로 이해했다. </p>
<p>이에 왜 list태그에서는 key속성이 필수인지 알아보다가 궁극적으로는 아래와 같이 리액트의 성능개선을 위한 것임을 알게되었다. </p>
<h1 id="불필요한-렌더링을-최소화한-성능-개선">불필요한 렌더링을 최소화한 성능 개선</h1>
<p>리액트에서는 자식 컴포넌트에 고유한 id를 부여함으로써 <strong>기존에 부여한 id가 이전과 동일하다면 자식요소가 변경되어진 것이 아니기 때문에</strong> 즉, 추후에 다른 자식 요소가 추가되거나 위치가 변경이 되어도 id만 동일하다면, _리액트가 불필요한 rendering을 하지 않음으로써 성능개선을 하는 것_이다. 리액트는 그것을 부여한 id를 통해 감지할 수 있으므로 list안에서 쓰이는 자식 컴포넌트에 id를 부여하는 것이 중요하다고 할 수 있다.</p>
<p>이외에도 추가적인 이유가 있겠지만 우선은 이 정도로 그 이유를 알아보고 추후 내용을 추가하려고 한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[CodeKata] Week 1 - Day 2]]></title>
            <link>https://velog.io/@elena_park/CodeKata-Week-1-Day-2</link>
            <guid>https://velog.io/@elena_park/CodeKata-Week-1-Day-2</guid>
            <pubDate>Tue, 30 Mar 2021 02:24:31 GMT</pubDate>
            <description><![CDATA[<h1 id="문제">문제</h1>
<p><img src="https://images.velog.io/images/elena_park/post/65864c3a-8f7d-4d3d-b23c-34dace42e2f3/codekata%201-1.png" alt=""></p>
<h1 id="풀이">풀이</h1>
<pre><code>const reverse = x =&gt; {
      const xStr = x.toString();
    let result = [];
    for(let i = xStr.length-1; i &gt;= 0; i--){
      if(xStr[i] === &#39;0&#39;) {
        continue;
      }
      result.push(xStr[i]);

      if(result[result.length-1] === &#39;-&#39;) {
      result.pop();
      result.unshift(&#39;-&#39;);
      }
    }
return Number(result.join(&#39;&#39;));
};

console.log(reverse(1234)); // 4321
console.log(reverse(-1234)); // -4321
console.log(reverse(1230)); // 321
</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[CodeKata] Week 1 - Day 1]]></title>
            <link>https://velog.io/@elena_park/CodeKata-Week-1-Day-1</link>
            <guid>https://velog.io/@elena_park/CodeKata-Week-1-Day-1</guid>
            <pubDate>Tue, 30 Mar 2021 02:18:30 GMT</pubDate>
            <description><![CDATA[<h1 id="문제">문제</h1>
<p><img src="https://images.velog.io/images/elena_park/post/cd40d26b-f8a7-4626-967d-b5b21653b67d/codekata%201-1.png" alt=""></p>
<h1 id="풀이">풀이</h1>
<pre><code>const twoSum = (nums, target) =&gt; {
  for(let i = 0; i &lt; nums.length; i++) {
    for (let j = 1; j &lt; nums.length; j++) {
      if(nums[i] + nums[j] === target) {
        return [i,j]
      }
    }
  }
}

console.log(twoSum([4, 9, 11, 14], 13));
console.log(twoSum([7, 6, 3, 1], 7));
</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[TIL 23 | Linux & Terminal ]]></title>
            <link>https://velog.io/@elena_park/TIL-23-Linux-Terminal</link>
            <guid>https://velog.io/@elena_park/TIL-23-Linux-Terminal</guid>
            <pubDate>Sun, 28 Mar 2021 11:18:53 GMT</pubDate>
            <description><![CDATA[<h1 id="linux란">Linux란?</h1>
<blockquote>
</blockquote>
<p>리누스 토발즈라는 인물이 개발한 <strong>Unix 기반 운영체제</strong>.</p>
<ul>
<li>리누스 토발즈는 Linux뿐 아니라 Git 버전관리 시스템도 최초로 개발하여 <strong>무료로 오픈소스로 제공</strong>하였다. 따라서 많은 서버가 Linux로 개발되어있다.</li>
<li>구글의 안드로이드 역시 Linux의 한 갈래이다.</li>
<li>Linux는 원래 터미널에서만 사용되는** CLI(Command Line Interface)기반 OS**였는데, 사용자를 위해 GUI(Graphic User Interface)로도 제공되고 있다.</li>
</ul>
<h2 id="디렉토리-구조">디렉토리 구조</h2>
<p><img src="https://images.velog.io/images/elena_park/post/a06d9388-f496-4755-a61f-1db5428c25b1/linux_directory_structure.png" alt=""></p>
<h3 id="핵심개념">핵심개념</h3>
<blockquote>
<p><strong>Filesystem Hierarchy Standard(FHS)</strong>
리눅스 시스템의 디렉토리 구조는 전체적으로 역 트리 구조를 하고 있으며, 명령어의 종류와 사용 권한 등에 따라 각각의 디렉토리로 구분되어진다. FHS라는 표준을 통해 대부분의 리눅스 배포판이 이러한 기본 구조를 갖는다. (FHS는 리눅스 재단에 의해 유지되고 있다.)</p>
</blockquote>
<h3 id="루트-디렉토리">루트 디렉토리</h3>
<ul>
<li><code>cd /</code>를 이용하여 최상위 디렉토리인 루트 디렉토리로 접근이 가능.</li>
</ul>
<h3 id="홈-디렉토리">홈 디렉토리</h3>
<ul>
<li>window안에서의 내 컴퓨터와 같은 의미를 지니고 있다.</li>
<li><code>cd ~</code> 를 이용하여 홈 디렉토리에 접근 가능</li>
</ul>
<h3 id="절대경로">절대경로</h3>
<ul>
<li>무조건 최상위 루트부터 시작하는 경로  </li>
<li>ex) /home/eun/bin<h3 id="상대경로">상대경로</h3>
</li>
<li>내가 있는 위치 기준으로 움직이는 경로</li>
<li>ex) <code>cd ..</code>  : 현재 위치 기준으로 바로 상위 디렉토리로 이동 
<code>.</code> : 현재경로
<code>..</code> : 상위경로</li>
</ul>
<h2 id="환경변수">환경변수</h2>
<ul>
<li>OS도 프로그램이므로 OS를 동작하게 하기 위한 변수가 필요하다.</li>
<li><code>env</code> 명령어로 linux 환경변수 확인이 가능하다.<blockquote>
<p><strong>PATH라는 환경변수에 저장되어 있는 것?</strong> 
터미널에서 사용될 각종 명령어들의 경로가 저장되어있다. 
명령어들을 PATH에 저장함으로써 기존 경로대로 하지 않고 편하게 터미널에서 명령어를 사용할 수 있는 것이다. 
PATH에 원하는 명령어가 빠져있는 경우 PATH에 저장해주면 된다.
여러 경로를 저장하기 위해 각 경로는 <code>:</code>로 구분되어진다.
<img src="https://images.velog.io/images/elena_park/post/f24da350-5701-4e3a-9b2a-0ad434d4b0ef/linux%20path.png" alt=""></p>
</blockquote>
</li>
</ul>
<h2 id="자주-사용되는-linux-명령어">자주 사용되는 Linux 명령어</h2>
<ul>
<li>cd (change directory) : 디렉토리 이동 ex) cd home </li>
<li>ls (list segments) : 현재 폴더 내 파일 확인 </li>
<li>ls -a (list segments all) : 현재 폴더 내 기본 파일 뿐 아니라 닷(.) 파일까지 확인 </li>
<li>pwd (print working directory) : 현재 내 위치 확인</li>
<li>touch : 파일 생성 ex) touch (파일명.확장자명)</li>
<li>mkdir (make directory) : 디렉토리 생성 ex) mkdir (디렉토리명)</li>
<li>rmdir (remove directory) : 디렉토리 제거 ex) rmdir (디렉토리명)</li>
<li>rm (remove) : 파일 또는 디렉토리 제거 ex) rm (파일명) / rm -r (디렉토리명)</li>
<li>cp (copy) : 파일 또는 디렉토리 복사 ex) cp (복사할 파일명) (새 파일명) </li>
<li>mv (move) : 파일 또는 디렉토리 이동 ex) mv (이동시킬 파일) (이동할 경로)</li>
<li>cat (concatenate) : 두 개 이상의 파일을 연결해서 출력 ex) cat (파일명1) (파일명2)</li>
<li>chmod (change mode) : 파일 또는 디렉토리의 권한 설정</li>
<li>clear : 터미널 내용 비우기</li>
<li>history : 지금까지 사용했던 모든 명령어 확인 
특정 단어가 포함된 명령어를 찾고 싶을 경우 ex) history | grep (단어)  </li>
</ul>
<h1 id="참고자료">참고자료</h1>
<p><a href="https://vtam.net/10">디렉토리구조 이미지 참고</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL 22 | Git & Github]]></title>
            <link>https://velog.io/@elena_park/TIL-22-Git-Github</link>
            <guid>https://velog.io/@elena_park/TIL-22-Git-Github</guid>
            <pubDate>Sun, 28 Mar 2021 09:56:17 GMT</pubDate>
            <description><![CDATA[<h1 id="git이란">Git이란</h1>
<ul>
<li>Git이란 프로젝트의 버전 관리를 도와주는 시스템이다.</li>
<li>여기서 프로젝트란? 제일 부모가 되는 폴더 하나를 의미한다.</li>
<li>VCS(Version Control System)이라고도 한다.</li>
</ul>
<h2 id="버전-관리를-하는-이유">버전 관리를 하는 이유</h2>
<p> *<em>버전이란, 하나의 유의미한 변화를 결과물로 만들어낸 것을 의미한다. *</em>
게임에서 버전 업데이트를 하는 것과 같이 프로그래밍에서도 버전이라는 것이 있고 그것을 관리해야 한다.</p>
<blockquote>
</blockquote>
<ol>
<li>보통 많은 개발자들이 협업해서 하나의 새로운 버전을 만든다. 즉, 하나의 버전을 관리하는 과정에서 <strong>협업</strong>이라는 것이 필연적이다.</li>
<li>버전을 관리하는 과정에서 이전의 버전으로 되돌리는 작업이 필요할 수 있다.</li>
<li>효율적으로 백업하는 과정이 필요하다.</li>
<li>수정 사항의 이력을 남길 수 있다.<br></li>
</ol>
<p><strong>이러한 작업을 해주는 것이 Git 버전 관리 시스템이다.</strong></p>
<h2 id="코드가-하나의-버전이-되는-과정에서의-세-개의-공간">코드가 하나의 버전이 되는 과정에서의 세 개의 공간</h2>
<h3 id="작업-공간working-directory">작업 공간(Working Directory)</h3>
<ul>
<li>사용자가 코드 작업을 하는 공간</li>
<li>파일들이 생성, 수정, 삭제되는 공간(즉, 변경사항이 생기는 공간)</li>
</ul>
<blockquote>
<p><strong>작업공간에서 만든 모든 파일을 무조건 하나의 버전으로 만들어야할까?</strong>
그럴 필요는 없다. 작업공간에서 버전이 될 파일을 선별한 후 그것을 다음공간으로 넘길 수 있다.</p>
</blockquote>
<h3 id="스테이징-공간staging-area">스테이징 공간(Staging Area)</h3>
<ul>
<li>버전이 될 후보들이 올라오는(staging) 공간</li>
<li>작업공간에서 해당 후보들을 선별</li>
</ul>
<h3 id="저장소repository">저장소(Repository)</h3>
<ul>
<li>새로 만든 버전과 지금까지의 버전 내역이 저장되는 저장소</li>
</ul>
<h2 id="단계별-git-명령어">단계별 git 명령어</h2>
<p>모든 git 명령어는 <code>git &lt;명령어&gt;</code> 형태로 작성한다.</p>
<h3 id="git-시작">git 시작</h3>
<p><code>git init</code></p>
<ul>
<li>git을 시작할 공간 안에서 git을 시작,초기화한다는 의미에서 아래와 같은 명령어로 git을 시작한다.</li>
<li>이렇게 <code>git init</code>을 하게되면 해당 폴더 안에 <code>.git</code>이라는 숨김파일이 생성되는데 이 파일로 인해서 해당 폴더의 삭제 또는 수정된 것에 대한 모든 변경사항이 감지된다. </li>
</ul>
<h3 id="버전관리가-되는-폴더의-현-상황을-확인">버전관리가 되는 폴더의 현 상황을 확인</h3>
<p><code>git status</code></p>
<ul>
<li>untracked files: test.txt 라는 문구가 있다면 test.txt 파일은 아직 <code>git add</code>로 인해 작업 공간에서 스테이징 공간으로 넘어가지 않았다는 뜻이다. 즉, 새로 생긴 파일.</li>
</ul>
<h3 id="1단계-작업-공간---스테이징-공간">1단계: 작업 공간 -&gt; 스테이징 공간</h3>
<p><code>git add &lt;파일명&gt;</code> 
<code>git add . 또는 git add *</code></p>
<ul>
<li><p>git status로 내역을 확인했을 때 changes to be committed: new file: test.txt 라는 문구가 있다면 이는 <code>git add</code>로 인해 스테이징 공간에는 올라왔지만 아직 <code>git commit</code>으로 저장소에 올라가기 직전의 파일이란 뜻이다. </p>
</li>
<li><p>작업 공간에서 스테이징 공간으로 넘겨줄 파일이 직접 처리하기에 많은 경우에는 <code>git add . 또는 git add *</code>를 사용하여 모든 파일을 한번에 넘길 수 있다.</p>
</li>
<li><p>만약 스테이징 공간에서 이미 스테이징 된 파일을 다시 작업 공간으로 unstage하고 싶은 경우 <code>git rm --cached &lt;파일명&gt;</code> 명령어를 사용하게되면 파일이 다시 작업 공간으로 내려가게 된다.</p>
</li>
</ul>
<h3 id="2단계-스테이징-공간---로컬-저장소">2단계: 스테이징 공간 -&gt; 로컬 저장소</h3>
<p><code>git commit -m &quot;커밋 메세지&quot;</code></p>
<ul>
<li>선별된 파일들이 <code>git add</code> 명령어를 통해 스테이징 공간에 올라왔으면 최종적으로 버전으로 저장되어야 하는데, 이때 <code>git commit -m &quot;커밋 메세지&quot;</code> 명령어를 통해 저장해주어야 한다.</li>
<li>버전이 많아지고 프로젝트 규모가 커질수록 다양한 커밋 내역과 버전들이 쌓이는데, 추후에 해당 커밋을 보았을 때 어떤 변경사항이 생겨서 이 커밋을 만들었는지, 어떤 유의미한 변화를 해당 버전에 담았는지를 확인할 수 있다.   </li>
<li>이렇게 커밋을 하게되면, 내 컴퓨터 안의 저장소에 커밋이 저장된다. </li>
</ul>
<p><code>git commit -am &quot;커밋 메세지&quot;</code> </p>
<ul>
<li>이 명령어는 add와 commit을 동시에 하게 해주는 명령어이다. 다만 최초로 한번은 commit이 되어야 그 다음부터 이 명령어를 사용하여 동시에 add와 commit을 할 수 있다. </li>
</ul>
<h3 id="지금까지-만들어진-commit-내역을-확인하는-방법">지금까지 만들어진 commit 내역을 확인하는 방법</h3>
<ul>
<li><code>git log</code> 명령어 사용</li>
</ul>
<h3 id="로컬-저장소에-저장된-버전을-원격-저장소로-올리는-법">로컬 저장소에 저장된 버전을 원격 저장소로 올리는 법</h3>
<p><code>git push (origin mastser)</code></p>
<ul>
<li>위에서와 같이 로컬 저장소에까지 commit을 마치게된 후 원격 저장소인 Github으로 파일을 업로드하기 위해 쓸 수 있는 명령어이다. </li>
<li>괄호 안의 origin은 원격 저장소의 저장소명, 뒤의 master는 내 로컬저장소의 master 브랜치를 의미한다.</li>
</ul>
<h3 id="브랜치-생성-및-접속-방법">브랜치 생성 및 접속 방법</h3>
<p><code>git branch &lt;브랜치명&gt;</code></p>
<ul>
<li>master 브랜치 외 추가적으로 브랜치를 생성하고 싶을 때 위의 명령어를 사용한다.
<code>git checkout &lt;브랜치명&gt;</code></li>
<li>특정 브랜치로 이동한다.
<code>git checkout -b &lt;브랜치명&gt;</code></li>
<li>새 브랜치를 생성하면서 동시에 해당 브랜치로 이동한다.</li>
</ul>
<h1 id="github">Github</h1>
<ul>
<li>Git을 사용한 프로젝트들의 원격(remote) 저장소를 의미한다. 즉, git을 이용해 버전관리를 한 프로젝트들을 관리하게 해주는 온라인 호스팅 서비스이다.</li>
<li>이외에도 개발자들을 위한 소셜 미디어의 역할을 하기도 한다</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL 21 | DOM(Document Object Model)]]></title>
            <link>https://velog.io/@elena_park/TIL-21-DOMDocument-Object-Model</link>
            <guid>https://velog.io/@elena_park/TIL-21-DOMDocument-Object-Model</guid>
            <pubDate>Mon, 22 Mar 2021 02:02:07 GMT</pubDate>
            <description><![CDATA[<h1 id="dom이란">DOM이란?</h1>
<blockquote>
<p>DOM이란 Document Object Model의 약자로서, <strong>웹 페이지의 HTML을 계층화시켜 트리구조로 만든 객체(Object)모델</strong>이다. </p>
</blockquote>
<p>JavaScript는 이 model로 웹 페이지에 접근하고, 페이지를 수정할 수 있다. 즉, DOM은 HTML인 웹 페이지와 스크립팅 언어인 JavaScript를 연결하는 역할을 수행한다. </p>
<p><img src="https://images.velog.io/images/elena_park/post/a8711a58-bd7d-4fca-85b5-41076b3a3d03/DOM.png" alt=""></p>
<blockquote>
<p>그럼 구체적으로 어떻게 JavaScript는 HTML에 접근할 수 있을까? <br>
<strong>바로 document 객체를 이용해서다.</strong>
JavaScript의 document 객체는 DOM 구조를 접근하는 관문이며, document 객체는 HTML 문서를 나타낸다고 할 수 있다.</p>
</blockquote>
<h1 id="html에-접근해야-하는-이유">HTML에 접근해야 하는 이유</h1>
<p>대량의 정보를 직접 HTML에 코드를 작성하는 것 말고, 서버에서 API 호출을 통해 HTML에 보여져야하는 목록을 가져와서 JavaScript를 통해 동적으로 요소를 생성하는 작업을 할 수 있기 때문이다.</p>
<h1 id="dom으로-html에-접근하는-예시">DOM으로 HTML에 접근하는 예시</h1>
<p>document 객체는 DOM 트리의 최상위 노드(root node)에 접근하게 해준다. document 객체로 요소(element)에 접근하듯이 요소의 속성(attribute)에도 접근할 수 있다. 그렇게 document 객체를 통해 class, id도 추가하고 스타일링도 가능하다. </p>
<p><strong>요소(element)의 내용은 innerHTML로 접근하고 수정할 수 있다.</strong> 다음은 document 객체를 이용하여 body태그의 내용을 바꾸는 예시이다.</p>
<pre><code class="language-js">document.body.innerHTML = &#39;내 이름은 엘레나야&#39;;</code></pre>
<p><strong>만약 특정 요소에 접근하고 싶다면 tag, class, id와 같은 css 선택자로 접근이 가능하다.</strong></p>
<pre><code class="language-js">const pinkElement = document.querySelector(&#39;.pink&#39;);
pinkElement.style.backgroundColor = &#39;pink&#39;;</code></pre>
<p>위의 예시를 설명하면, </p>
<ul>
<li>먼저 document객체를 통해 HTML 파일에서 class명이 pink인 요소를 가져와 pinkElement라는 변수에 담았다. </li>
<li>이후 pinkElement.style.backgroundColor를 통해 해당 요소의 배경색을 pink로 변경하였다.</li>
</ul>
<p>여기서 스타일링 시 css에서 작성하던 것과는 다르게 background-color가 아닌 backgroundColor와 같은 camelCase 형식으로 작성한 것을 볼 수가 있는데, </p>
<p>이처럼 <strong>JavaScript에서 css style을 수정할 경우 하이픈(-)은 사용할 수 없고 camelCase를 이용하여 코드를 작성해야 한다.</strong> </p>
<p>JavaScript를 이용하여 HTML 웹 페이지에 동적으로 요소를 생성할 수도 있다.</p>
<pre><code class="language-js">const pTag = document.createElement(&#39;p&#39;);
body.appendChild(pTag);</code></pre>
<p>위의 예시를 설명하면,</p>
<ul>
<li>먼저 document객체를 통해 p태그를 생성하고 pTag라는 변수에 담았다.</li>
<li>이후 appendChild를 통해 body 내부의 제일 아래쪽에 해당 요소를 추가하였다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL 20 | 개발자 도구]]></title>
            <link>https://velog.io/@elena_park/TIL-20-%EA%B0%9C%EB%B0%9C%EC%9E%90-%EB%8F%84%EA%B5%AC</link>
            <guid>https://velog.io/@elena_park/TIL-20-%EA%B0%9C%EB%B0%9C%EC%9E%90-%EB%8F%84%EA%B5%AC</guid>
            <pubDate>Sun, 21 Mar 2021 08:09:21 GMT</pubDate>
            <description><![CDATA[<h1 id="개발자-도구">개발자 도구?</h1>
<blockquote>
<p><strong>개발자 도구</strong>란 각 브라우저들이 제공하는 개발자를 위한 도구이다. 여기서는 크롬 브라우저를 사용하는 것을 예로 들지만 각 브라우저마다 개발자 도구의 형태와 사용법이 조금씩 다를 수 있다. </p>
</blockquote>
<p><strong>개발자 도구를 여는 방법</strong>은,
윈도우os에서는 <code>ctrl + shift + i</code>를, 맥os에서는 <code>option + command + i</code>를 누르면 열린다. 또는 확인하고자 하는 웹페이지에서 마우스 우클릭하여 맨 아래에 있는 탭인 검사를 누르면 열린다.</p>
<p>개발자 도구에는 다양한 패널이 있지만 가장 사용 빈도가 높은 아래 4개의 패널에 대해서만 다루어보려고 한다.</p>
<h1 id="elements-panel">Elements panel</h1>
<p><img src="https://images.velog.io/images/elena_park/post/8abadd01-25d9-4433-9343-114312d75fa0/element%20panel.png" alt=""></p>
<h2 id="기능">기능</h2>
<ul>
<li>HTML의 구조 및 각 HTML 요소마다 적용되어있는 CSS 스타일링의 내역을 보여준다.</li>
<li>HTML과 CSS 구조를 직접 수정해보면서 웹페이지에 어떻게 적용되는지 실시간으로 확인해볼 수 있다.(TEST용으로 실제로 웹페이지에 적용되는 것은 아니다.)</li>
</ul>
<h2 id="styles-부분의-순서">Styles 부분의 순서</h2>
<ul>
<li>가장 상단부터 CSS selector의 우선순위에 따라 보여진다.</li>
<li>!important -&gt; inline styling -&gt; id selector -&gt; class selector -&gt; tag selector -&gt; * selector -&gt; 상위 요소에 의해 상속된 속성 </li>
<li>속성이 밑줄 표시로 지워진 스타일들의 경우, 속성을 적용했지만 다른 부분에서 속성이 중복되어 설정될 경우 우선 순위에 따라 스타일이 적용되어 반영되지 않는 스타일 속성을 의미한다.</li>
</ul>
<h2 id="user-agent-styles">user agent styles?</h2>
<ul>
<li>각 브라우저에 기본적으로 지정되어있는 styling 값을 의미한다. 따라서 브라우저마다 조금씩 기본 스타일이 다르다. </li>
<li>이러한 기본값을 지우고 싶다면 위에 직접 css 속성을 정의하면 된다.</li>
<li>일반적으로 개발 시작 단계에는 <code>reset.css</code> 혹은 <code>normalize.css</code>파일을 따로 만들어 기본 styling을 초기화시키는 작업을 한 뒤 개발을 한다. 이렇게 되면 브라우저에 상관 없이 동일한 화면을 출력할 수 있다.</li>
</ul>
<h1 id="console-panel">Console panel</h1>
<p><img src="https://images.velog.io/images/elena_park/post/56bef579-07fb-4107-9b29-21c1131da40e/console%20panel.png" alt=""></p>
<h2 id="기능-1">기능</h2>
<ul>
<li>자바스크립트 코드의 즉시 실행 가능</li>
<li>디버깅 가능</li>
</ul>
<h2 id="웹페이지-새로고침을-하더라도-console의-내용이-지워지지-않게-하는-법">웹페이지 새로고침을 하더라도 console의 내용이 지워지지 않게 하는 법</h2>
<ul>
<li>그런데 이렇게 즉시 실행해본 코드들은 웹페이지를 새로고침하게 되면 모두 사라진다. 이렇게 새로고침 후에도 사라지는 것을 막기 위해서는 preserve log에 체크해야 한다.</li>
</ul>
<h2 id="console에-기록된-로그를-모두-지울-때-사용하는-메서드">console에 기록된 로그를 모두 지울 때 사용하는 메서드</h2>
<ul>
<li>console도 객체이므로 다양한 메서드가 존재한다. </li>
<li>하나의 예시로 console에 기록된 로그를 모두 지울 때는 <code>console.clear()</code>라는 메서드를 사용하여 로그를 지울 수 있다.</li>
</ul>
<blockquote>
<p>메서드(method)란, 객체 내에 있는 함수를 뜻한다.</p>
</blockquote>
<h2 id="console에서-warning-errors를-제외하고-보는-방법">console에서 warning, errors를 제외하고 보는 방법</h2>
<ul>
<li>console 패널에서 filter 칸의 오른쪽에 보면 <code>Custom levels</code>라는 drop down 메뉴가 있는데, 클릭하면 waring과 errors를 포함할 것인지 아닌지 여부를 체크하여 console을 이용할 수 있다.</li>
</ul>
<h2 id="다른-패널에서-console-panel을-같이-사용하는-방법">다른 패널에서 console panel을 같이 사용하는 방법</h2>
<ul>
<li>다른 패널에서 <code>esc</code> 탭을 누르면 아래에 console창이 생성되어 다른 패널과 동시에 이용할 수 있다. <h1 id="network-panel">Network panel</h1>
<img src="https://images.velog.io/images/elena_park/post/a0ea9fc0-836a-45ed-a40c-6e8693dd0bcb/newtwork%20panel.png" alt=""><h2 id="기능-2">기능</h2>
</li>
<li>HTTP 네트워크 통신 확인 : 통신을 받기까지의 소요되는 시간을 알 수 있다.</li>
<li>API크롤링, 페이지 로딩 성능 테스트를 할 수 있다.</li>
<li>이미지,영상 등의 소스를 활용할 수 있다.</li>
</ul>
<h1 id="application-panel">Application panel</h1>
<p><img src="https://images.velog.io/images/elena_park/post/18c85612-a23b-4392-8612-f4d09284fe8a/application%20panel.png" alt=""></p>
<h2 id="기능-3">기능</h2>
<ul>
<li>브라우저의 저장소(웹 스토리지, 쿠키)의 정보를 확인할 수 있는 패널이다.</li>
</ul>
<h2 id="웹-스토리지로컬세션-스토리지와-쿠키의-차이점-및-사용-예시">웹 스토리지(로컬/세션 스토리지)와 쿠키의 차이점 및 사용 예시</h2>
<p><img src="https://images.velog.io/images/elena_park/post/989ef9c8-ca5a-40df-9b80-38409937d386/cookie,web%20storage.png" alt=""></p>
<h3 id="웹-스토리지web-storage">웹 스토리지(Web Storage)</h3>
<ul>
<li>브라우저 상에 데이터를 저장하는 저장소</li>
<li>Key-Value 페어의 객체 형태로 데이터 저장한다.</li>
<li>데이터가 서버로 전송되지 않는다.</li>
</ul>
<ul>
<li>로컬 스토리지 (Local Storage), 세션 스토리지(Session Storage)로 나눌 수 있다.</li>
<li>로컬 스토리지: 사용자가 직접 지우기 전까지, 웹 페이지가 닫히더라도 저장된 데이터가 지워지지 않는다. 따라서 <strong>자동로그인 시 ID 저장,비회원 장바구니</strong>등과 같은 창이 닫혔을 때도 브라우저에 정보가 남아있어야 할 경우 사용한다.</li>
<li>세션 스토리지: 웹 페이지의 창이 한번 닫히게 되면 저장된 데이터가 지워진다. 따라서 <strong>일회성 로그인 정보, 은행 사이트</strong> 등을 구현할 때 사용한다.<h3 id="쿠키cookie">쿠키(Cookie)</h3>
</li>
<li>웹 스토리지를 사용하기 이전에 사용했던 저장소</li>
<li>정보의 보관 만료 기한을 사용자가 설정할 수 있다.</li>
<li>매 서버 요청마다 서버로 쿠기가 같이 전송된다.</li>
<li>Key-Value 페어의 문자열 형태로 데이터 저장(세미콜론으로 구분). 텍스트 타입이라 문자열만 저장한다.</li>
<li>웹 스토리지에 비해 보안이 취약하여 <strong>오늘만 하는 이벤트 팝업, 방문페이지 저장</strong> 등과 같이 보안에 상관없는 정보를 저장할 때 사용한다.</li>
</ul>
<h2 id="특정-데이터를-저장하거나-꺼내오는-방법">특정 데이터를 저장하거나 꺼내오는 방법</h2>
<ul>
<li>웹 스토리지에는 누구나 접근하여 데이터를 저장하거나 호출할 수 있기 때문에 <strong>비밀번호와 같은 중요한 정보는 저장하지 않는다.</strong></li>
<li>데이터 저장:
<code>localStorage.setItem(&quot;key 값&quot;, &quot;value 값&quot;);</code>
<code>sessionStorage.setItem(&quot;key 값&quot;, &quot;value 값&quot;);</code>
<code>setcookie(&quot;key 값&quot;, &quot;value 값&quot;, &quot;지속시간(초)&quot;);</code></li>
<li>데이터 호출:
<code>localStorage.getItem(&quot;key 값&quot;);</code>
<code>sessionStorage.getItem(&quot;key 값&quot;);</code>
<code>document.cookie = &quot;쿠키이름 = 쿠키값&quot;</code>;</li>
<li>기타:
<code>removeItem, clear</code>와 같은 데이터 삭제, 스토리지 삭제와 같은 공통 메소드도 있다.
<code>localStorage.length</code>: 데이터의 개수 확인</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL 19 | Semantic Web, Semantic Tag]]></title>
            <link>https://velog.io/@elena_park/TIL-20-Semantic-Web-Semantic-Tag</link>
            <guid>https://velog.io/@elena_park/TIL-20-Semantic-Web-Semantic-Tag</guid>
            <pubDate>Tue, 16 Mar 2021 06:58:12 GMT</pubDate>
            <description><![CDATA[<h1 id="시맨틱-웹semantic-web--의미론적인-웹">시맨틱 웹(Semantic Web) : 의미론적인 웹</h1>
<p>웹사이트는 검색엔진으로의 노출이 매우 중요하다. 당연하지만 노출되지 않는 사이트는 사용자들이 방문할 일이 없기 때문이다.</p>
<p>따라서 이러한 중요성에 따라 SEO(Search Engine Optimization)와 같은 검색엔진 최적화 도구를 이용하여 검색엔진이 사용자의 웹사이트를 검색하기 알맞은 구조로 웹사이트를 조정하기도 한다.</p>
<blockquote>
<p><strong>크롤링?</strong>
검색엔진은 로봇이라는 프로그램을 이용하여 매일 전세계의 웹사이트 정보를 수집한다. 이를 크롤링이라고 하는데, 이외에도 검색 사이트 이용자가 검색할만한 키워드를 미리 예상하여 검색 키워드에 대응하는 인덱스를 만들어둔다. </p>
</blockquote>
<p>이렇게  인덱스를 생성할 때 사용되는 정보는 검색 로봇이 수집한 정보인데 <strong>결국 웹사이트의 HTML 코드</strong>이다. <strong>즉 검색엔진은 HTML만으로 그 의미를 인지하여야하는데 이때 시맨틱 요소(Semantic element)를 해석하게 된다.</strong></p>
<pre><code>&lt;font size=&quot;6&quot;&gt;&lt;b&gt;Hello&lt;/b&gt;&lt;/font&gt;

&lt;h1&gt;Hello&lt;/h1&gt;</code></pre><p>위 두 예시는 화면에 같은 결과를 출력하기는 하지만, 내부에서 가지는 의미는 본질적으로 다르다.</p>
<ul>
<li><p>첫 번째 예시는 <strong>의미론적으로 어떤 의미도 가지고 있지 않다</strong>. 그저 폰트 크기와 글씨체의 굵기만을 지정해놓고 있다.</p>
</li>
<li><p>두 번째 예시에서 h1은 header(제목)중 가장 상위 레벨이라는 의미를 내포하고 있어 개발자가 의도한 요소를 드러내고 있다. 이것이 코드의 가독성을 높이고 유지보수를 쉽게 한다. </p>
</li>
<li><p><em>=&gt; 검색엔진은 두 번째 예시와 같은 h1 요소 내의 컨텐츠를 웹 문서의 중요한 제목으로 인식하고 인덱스에 포함시킬 확률이 높다. *</em></p>
</li>
</ul>
<blockquote>
<p><strong>시맨틱 웹</strong>은 기존 웹을 확장하여 컴퓨터가 이해할 수 있는 잘 정의된 의미를 기반으로 의미적 상호운용성을 실현하여, 다양한 정보자원의 처리 자동화, 데이터의 통합 및 재사용등을 <strong>컴퓨터가 스스로 수행하여, 인간과 컴퓨터 모두 잘 이해할수 있는 웹을 만드는 것이 목표</strong>이다.</p>
</blockquote>
<h1 id="시맨틱-태그semantic-tag">시맨틱 태그(Semantic Tag)</h1>
<h2 id="non-semantic">Non-semantic</h2>
<p>내부 컨텐츠의 의미에 대해 설명을 하지 않는 div,span등의 태그</p>
<h2 id="semantic">Semantic</h2>
<p>내부 컨텐츠의 의미를 정확하게 설명하는 form,table,img,header,nav와 같은 태그</p>
<blockquote>
<p>*<em>HTML5 에서 추가된 시맨틱 태그들은 아래와 같다 *</em>:
header : 헤더(제목)를 의미한다.
nav : 내비게이션을 의미한다.
aside : 사이드에 위치하는 공간을 의미한다.
section : 본문에 여러 내용(article)을 포함하는 공간을 의미한다.
article : 본문의 주 내용이 들어가는 공간을 의미한다.
footer : 보통 웹페이지의 가장 아래에 들어가는 정보 공간을 의미한다.</p>
</blockquote>
<p><img src="https://images.velog.io/images/elena_park/post/44c50d74-5553-413b-bc7f-b6cb61f8ad7b/semantic.png" alt=""></p>
<p>시맨틱 요소로 구성된 웹페이지는 검색 엔진에 의미론적으로 문서정보를 전달할 수 있고, 검색엔진 또한 시맨틱 요소를 이용하여 효과적인 크롤링과 인덱싱이 가능해졌다. 즉, <strong>시맨틱 태그란 브라우저, 검색엔진, 개발자 모두에게 컨텐츠의 의미를 명확히 설명하는 역할을 한다</strong>. 시맨틱 태그에 의해 컴퓨터가 HTML요소의 의미를 보다 명확히 해석, <strong>그 데이터를 활용할 수 있는 시맨틱 웹이 실현</strong>될 수 있다.</p>
<h1 id="시맨틱-태그의-사용-예제">시맨틱 태그의 사용 예제</h1>
<p><code>HTML에 &lt;img&gt;태그를 사용하여 이미지를 주입하는 경우</code></p>
<ul>
<li>태그 자체에 img를 표현한다는 의미를 담고 있으므로 시맨틱 태그를 사용하여 이미지를 주입하는 예이다.</li>
<li>이미지 로드에 실패할 경우 alt라는 속성을 통해 화면에 보여줄 텍스트를 작성할 수 있다.</li>
</ul>
<p><code>HTML에 &lt;div&gt;태그에 CSS속성으로 background-image 속성을 추가하여 이미지를 주입하는 경우</code></p>
<ul>
<li>유의미한 뜻을 가지고 있지 않은 태그인 div를 이용, 단순히 CSS를 통해 배경 이미지를 주입하는 예이다.</li>
<li>이미지 로드에 실패할 경우 <code>&lt;img&gt;</code>태그와 같이 alt 속성의 기능을 하는 것이 따로 없다. 대체 텍스트가 출력되지 않는다.</li>
</ul>
<blockquote>
<p>사용되는 이미지가 사용자에게 컨텐츠 이해에 더 도움을 준다고 생각되는 경우, 검색 엔진에 해당 이미지에 대한 정보가 노출되기를 바라는 경우 <code>&lt;img&gt;</code>태그를 사용하여 이미지를 주입하고, 그렇지 않은 경우 CSS Background-image 속성을 이용하여 이미지를 주입한다.</p>
</blockquote>
<h1 id="참고자료">참고자료</h1>
<p><a href="https://poiemaweb.com/html5-semantic-web">Poeimaweb 시맨틱 웹</a></p>
]]></description>
        </item>
    </channel>
</rss>