<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>JY.log</title>
        <link>https://velog.io/</link>
        <description>Hello World!</description>
        <lastBuildDate>Tue, 27 Jun 2023 15:37:36 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>JY.log</title>
            <url>https://velog.velcdn.com/images/jw_agnes_baek/profile/e97d8b11-4af3-409f-8df1-ced4a46e6041/social_profile.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. JY.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/jw_agnes_baek" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[코드 일지] filter/동적라우팅 실습 과제]]></title>
            <link>https://velog.io/@jw_agnes_baek/%EA%B0%9C%EB%B0%9C-%EC%9D%BC%EC%A7%80-%ED%8E%98%EC%9D%B4%EC%A7%80%EB%84%A4%EC%9D%B4%EC%85%98-%EC%8B%A4%EC%8A%B5-%EA%B3%BC%EC%A0%9C</link>
            <guid>https://velog.io/@jw_agnes_baek/%EA%B0%9C%EB%B0%9C-%EC%9D%BC%EC%A7%80-%ED%8E%98%EC%9D%B4%EC%A7%80%EB%84%A4%EC%9D%B4%EC%85%98-%EC%8B%A4%EC%8A%B5-%EA%B3%BC%EC%A0%9C</guid>
            <pubDate>Tue, 27 Jun 2023 15:37:36 GMT</pubDate>
            <description><![CDATA[<ol>
<li>filter 조건 - 가격 낮은 순서 / 별점 높은 순서 / 할인률 높은 순서</li>
</ol>
<ul>
<li>sort함수를 사용할 때, <strong>a-b : 오름차순, b-a : 내림차순</strong>으로 정렬된다.
=&gt; 반환값&lt;0 이면 a가 b보다 먼저, 반환값 &gt;0이면 b가 a보다 먼저 오도록 sort되기 때문</li>
</ul>
<pre><code class="language-js">const Products = () =&gt; {
  const [productsList, setProductsList] = useState([]);
  const [totalProduct, setTotalProduct] = useState(0);

  const filterProducts = e =&gt; {
    const newProductsList = [...productsList];
    const filter = e.target.value;
    if (filter === &#39;price&#39;) {
      newProductsList.sort((a, b) =&gt; a.price - b.price);
      setProductsList(newProductsList);
    } else if (filter === &#39;rating&#39;) {
      newProductsList.sort((a, b) =&gt; b.rating - a.rating);
      setProductsList(newProductsList);
    } else if (filter === &#39;discountPercentage&#39;) {
      newProductsList.sort(
        (a, b) =&gt; b.discountPercentage - a.discountPercentage
      );
      setProductsList(newProductsList);
    }
  };

  return (
    &lt;div className=&quot;products&quot;&gt;
      &lt;div className=&quot;filterContainer&quot;&gt;
        &lt;select onChange={filterProducts}&gt;
          &lt;option value=&quot;&quot;&gt;옵션을 선택해주세요&lt;/option&gt;
          &lt;option value=&quot;price&quot;&gt;가격 낮은순&lt;/option&gt;
          &lt;option value=&quot;rating&quot;&gt;별점 높은순&lt;/option&gt;
          &lt;option value=&quot;discountPercentage&quot;&gt;할인율 높은순&lt;/option&gt;
        &lt;/select&gt;
      &lt;/div&gt;
    ...
};
</code></pre>
<ol start="2">
<li>동적라우팅 관련 부분</li>
</ol>
<ul>
<li>페이지네이션 버튼 배열을 만들기 위해 사용할 수 있는 메서드 구조
<code>new Array(totalProduct / 10).fill(1)</code></li>
<li><blockquote>
<p>전체 데이터에서 10을 나눈 값의 길이를 가진 배열을 새로 생성하고, 그 배열에 1이라는 값으로 채우겠다는 의미 </p>
</blockquote>
</li>
</ul>
<pre><code class="language-js">import {  useSearchParams } from &#39;react-router-dom&#39;;

const Products = () =&gt; {
  const [searchParams, setSearchParams] = useSearchParams();
  const offset = searchParams.get(&#39;offset&#39;);
  const skip = searchParams.get(&#39;skip&#39;);

  const pageArr = new Array(totalProduct / offset).fill(1);

  useEffect(() =&gt; {
    fetch(`https://dummyjson.com/products?limit=${offset}&amp;skip=${skip}`)
      .then(res =&gt; res.json())
      .then(data =&gt; {
        setProductsList(data.products);
        setTotalProduct(data.total);
      });
  }, [offset, skip]);

  return (
...
    &lt;div className=&quot;buttonWrap&quot;&gt;
        {pageArr.map((list, idx) =&gt; {
          return (
            &lt;Link
              key={list + idx}
              to={`/products?offset=${offset}&amp;skip=${idx * offset}`}
              className={`pageBtn ${skip / offset === idx &amp;&amp; &#39;clicked&#39;}`}
            &gt;
              {list + idx}
            &lt;/Link&gt;
          );
        })}
      &lt;/div&gt;
    &lt;/div&gt;
  );
};</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[팀 프로젝트] 1차 팀 프로젝트 회고_배민문방구 클론코딩]]></title>
            <link>https://velog.io/@jw_agnes_baek/%ED%8C%80-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%ED%9A%8C%EA%B3%A0%EB%A1%9D</link>
            <guid>https://velog.io/@jw_agnes_baek/%ED%8C%80-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%ED%9A%8C%EA%B3%A0%EB%A1%9D</guid>
            <pubDate>Mon, 12 Jun 2023 11:49:14 GMT</pubDate>
            <description><![CDATA[<p>프론트엔드 개발자로서 처음 팀 프로젝트를 진행하면서 프론트엔드 팀원들 뿐만 아니라 백엔드분들과도 소통하며 새로운 기능들을 구현해보는 동시에, 프로젝트 매니저로서 프로젝트 일정 관리 및 멘토님들과의 소통까지 담당하다보니 쉽지는 않았지만 그만큼 많이 성장할 수 있었던 프로젝트였다.   </p>
<h2 id="pm으로서의-회고-br">PM으로서의 회고 <br/></h2>
<p><strong>[GOOD]</strong> 기존 일정 관리 방식을 보완하기 위한 GOOGLE SHEETS 양식 도입<br/>
팀 프로젝트 일정 관리 툴인 TRELLO로 첫번째 스프린트를 진행하면서 TRELLO만으로는 각 카드별 세부 업무에 대한 진척도를 파악하는데 어려움이 있다고 판단했다. 그래서 첫번째 스프린트 회고 미팅 후 팀원별, 카드별 세부 항목에 대해 확인할 수 있는 구글 시트를 작성하여 추가로 도입하였다. 
<img src="https://velog.velcdn.com/images/jw_agnes_baek/post/6d9486d0-06d7-4f6c-963d-d094800d39a2/image.png" alt="Google Sheets를 통한 일정 관리">
나에게 할당된 카드 뿐 아니라 다른 팀원들의 진척도도 한번에 확인할 수 있었고, 전체 카드 대비 진척도도 수치화하기 수월해져 데일리 미팅에서나 멘토님과 스프린트 미팅을 진행할 때도 더 명확하게 팀 진행상황에 대해 소통할 수 있었다. </p>
<h2 id="front-end-개발자로서의-회고">Front-End 개발자로서의 회고</h2>
<p><strong>[GOOD]</strong> 이번 프로젝트에서는 Carousel, Checkbox 등 새로운 FE 기능을 구현하는 것에서 더 나아가 어디까지 FE에서 구현할지 논의하거나 실제 통신을 진행하는 과정에서 서버 end-point에 맞게 코드를 수정해가는 등 백엔드 팀원들과 소통하는 방법에 대해서도 배울 수 있었다. 
예를 들어 실제 통신 전 장바구니 페이지에서 Mock data를 바탕으로 기능을 구현했을 때는 가독성에 초점을 두어 하나의 수식에서 수량 변화(Count component)가 이루어지게 작성했었는데, API 명세서를 확인해보니 실제 증가 및 감소에 대한 End point가 상이한 것을 확인하고 수량 변화에 대한 코드를 전체적으로 수정해야하는 경우가 있었다. 
또한 백엔드에서 총 구매 금액에 대한 산출을 FE에서 구현했으면 좋겠다는 요청을 받고 reduce 메서드를 통해 직접 산출하는 경우도 있었다. 이러한 과정을 통해 BE-FE 간의 협업 시에는 다양한 변수가 발생할 수 있어 항상 자세하고 적극적으로 소통하는 프로세스를 경험할 수 있었다. </p>
<h2 id="추후-프로젝트에서의-goal">추후 프로젝트에서의 GOAL</h2>
<ol>
<li>이번 프로젝트에서는 일정 내 기능 구현을 완료하는 것에 중점을 두었었는데, 팀원마다 개발 속도나 중점을 두는 부분(디자인 혹은 기능 구현)이 다르다 보니 미팅에서 논의되었던 사항들과 다르게 진행되는 경우가 있었다. 기한 내 프로젝트 완료가 먼저이다 보니 팀원과 상황에 대해 확인하기보다는 직접 추가 구현 페이지를 담당하거나, 레이아웃까지만 작성된 다른 팀원의 코드에 기능 코드를 추가하는 경우도 있었다. 다음 프로젝트 때는 결과에만 집중하기 보다는 좀 더 과정에 대해 생각해보며 프로젝트를 진행할 수 있으면 좋을 것 같았다. 그래서 이번에는 멘토님들의 코드 리뷰를 받기는 했지만 FE 개발자들 간에 peer review를 진행하지 못해 다음에는 기존의 코드에 대한 리팩토링도 동시에 진행될 수 있도록 고민해보고 싶었다. </li>
<li><strong>이번 프로젝트에서 느낀 개발자란 :</strong> COO님이 개발자는 자기 코드를 지울 수도 있어야 하고, 같이 일하고 싶은 개발자가 되는 것이 중요하다는 말씀을 하셨었는데, 특히나 이번 프로젝트를 진행하며 그 부분에 대한 생각을 많이 하게 되었다. 항상 성장하는 개발자가 되는 동시에 다른 동료들이 같이 일하고 싶은 개발자가 되고 있는가 계속 되돌아봐야겠다고 다짐하게 되었던 프로젝트였다. </li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[[팀 프로젝트] 1차 팀 프로젝트 일지_배민문방구 클론코딩]]></title>
            <link>https://velog.io/@jw_agnes_baek/%EA%B0%9C%EB%B0%9C%EC%9D%BC%EC%A7%80-1%EC%B0%A8-%ED%8C%80-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%ED%9A%8C%EA%B3%A0</link>
            <guid>https://velog.io/@jw_agnes_baek/%EA%B0%9C%EB%B0%9C%EC%9D%BC%EC%A7%80-1%EC%B0%A8-%ED%8C%80-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%ED%9A%8C%EA%B3%A0</guid>
            <pubDate>Sun, 11 Jun 2023 05:05:23 GMT</pubDate>
            <description><![CDATA[<h2 id="프로젝트-개요">[프로젝트 개요]</h2>
<p>팀 FE REPOSITORY 주소: <a href="https://github.com/wecode-bootcamp-korea/46-1st-WePet-frontend">https://github.com/wecode-bootcamp-korea/46-1st-WePet-frontend</a>
개인 REPOSITORY 주소: <a href="https://github.com/AGNESBAEK/46-1st-WePet-frontend">https://github.com/AGNESBAEK/46-1st-WePet-frontend</a> <br/>
<strong>개발 기간 :</strong> 2023/5/26 ~ 2023/6/9 
<strong>개발 인원 :</strong> 프론트엔드 3명, 백엔드 2명
<strong>Tech Stack</strong>
(FE) React.js, JavaScript, sass
(BE) Node.js, Express, My SQL, Bcrypt
(공통) : RESTful API, TRELLO, SLACK, Notion, Google Sheets
<br/></p>
<h2 id="담당-업무-및-구현-기능">[담당 업무 및 구현 기능]</h2>
<h3 id="1-프로젝트-매니저"><strong>1) 프로젝트 매니저</strong></h3>
<p>: TRELLO, Notion, Google Sheets를 통한 프로젝트 일정 관리</p>
<h3 id="2-담당-페이지-레이아웃-및-기능-구현"><strong>2) 담당 페이지 레이아웃 및 기능 구현</strong></h3>
<p><strong>(1) [필수] 메인 페이지 레이아웃 및 기능 구현</strong></p>
<ul>
<li>고객들의 관심을 유도할 수 있는 다양한 화면 효과</li>
<li>Carousel 기능: useEffect와 setInterval을 이용하여 5초마다 새로운 이미지로 전환되게 설정</li>
<li>Slider 기능: 간식/용품 카테고리별 제품을 4개씩 slider로 노출</li>
<li>쿼리 스트링을 통해 최신순, 인기순 기준의 상품들을 map 메서드로 노출
<img src="https://velog.velcdn.com/images/jw_agnes_baek/post/d89eecee-9cc1-48da-9f01-bfc2dae77ed7/image.gif" alt=""></li>
</ul>
<p><strong>(2) [필수] 장바구니 페이지 레이아웃 및 기능 구현</strong></p>
<ul>
<li>checkbox로 전체 선택 및 일부 선택 가능, 선택 갯수 노출<ul>
<li>count 컴포넌트로 실시간 제품별 구매 수량 변경 및 reduce 함수를 통한 실시간 총 구매 금액 산출</li>
<li>구매 유도를 위한 배송비 무료까지 잔여 금액에 대한 알람창 노출</li>
<li>조건부 렌더링으로 장바구니에 담긴 제품이 없을 경우, &quot;앗 장바구니가 텅~&quot; 문구 노출, 구매 버튼 비활성화, 배송비 0원 적용</li>
<li>주문 버튼 클릭 시 결제 페이지로 이동</li>
<li>*[서버(BE)와의 통신]**</li>
<li>유저의 장바구니 데이터를 GET 메서드 통신</li>
<li>장바구니 상품별 수량 변경 부분은 PATCH 메서드 통신 (수량 추가/감소 endpoint)</li>
<li>선택 삭제 및 전체 삭제 기능은 DELETE 메서드 통신 (개별 삭제 및 전체 선택 endpoint)
<img src="https://velog.velcdn.com/images/jw_agnes_baek/post/c225c25f-7548-405d-924a-52a6800c880b/image.gif" alt=""></li>
</ul>
</li>
</ul>
<p><strong>(3) [추가] 마이 페이지 레이아웃 및 기능 구현</strong></p>
<ul>
<li>조건부 렌더링으로 클릭하는 메뉴에 따라 다른 문구 노출<ul>
<li>1:1 문의 내역에는 버튼 클릭 시 문의 내용 입력 모달 확인 가능</li>
<li>이메일 문의 클릭 시 바로 메일을 보낼 수 있게 링크가 적용</li>
<li>결제 완료 후 서버에서 ORDER DATA를 GET 통신으로 전달 받아 마이페이지에 구현
<img src="https://velog.velcdn.com/images/jw_agnes_baek/post/9fef9aaf-cbf3-469f-b985-ea88c7cbcffc/image.gif" alt=""></li>
</ul>
</li>
</ul>
<p><strong>(4) [추가] Nav바 일부 기능 구현</strong></p>
<ul>
<li>로그인 여부에 따라 버튼 문구 변경 (로그인/로그아웃)<ul>
<li>로그인 여부에 따라 NAV 모달에 노출 문구 변경 (앗 로그인이 필요합니다, 안녕하세요 ~님)</li>
<li>로그인이 된 경우에만 장바구니, 마이페이지로 진입(로그인이 안 된 경우에는 로그인 페이지로 이동)</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[클론코딩] 인스타그램 클론코딩_React (Mock data 도입에 따른 코드 수정)]]></title>
            <link>https://velog.io/@jw_agnes_baek/%ED%81%B4%EB%A1%A0%EC%BD%94%EB%94%A9-%EC%9D%B8%EC%8A%A4%ED%83%80%EA%B7%B8%EB%9E%A8-%ED%81%B4%EB%A1%A0%EC%BD%94%EB%94%A9React-Mock-data-%EB%8F%84%EC%9E%85%EC%97%90-%EB%94%B0%EB%A5%B8-%EC%BD%94%EB%93%9C-%EC%88%98%EC%A0%95</link>
            <guid>https://velog.io/@jw_agnes_baek/%ED%81%B4%EB%A1%A0%EC%BD%94%EB%94%A9-%EC%9D%B8%EC%8A%A4%ED%83%80%EA%B7%B8%EB%9E%A8-%ED%81%B4%EB%A1%A0%EC%BD%94%EB%94%A9React-Mock-data-%EB%8F%84%EC%9E%85%EC%97%90-%EB%94%B0%EB%A5%B8-%EC%BD%94%EB%93%9C-%EC%88%98%EC%A0%95</guid>
            <pubDate>Thu, 25 May 2023 12:59:38 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>(요약) 1. Mock data 구조를 변경하면서 코드 전체 구조를 수정해야 했던 경험을 통해 팀 프로젝트 시 Mock data에 대한 충분한 협의가 이루어진 후 개발이 진행되어야 함을 느낄 수 있었다.
2. 개인 협업 시에도 코드 작성을 진행하기 전 실제 data 구조나 전체적인 흐름에 대한 생각이 충분히 선행되어야 한다는 점을 깨달았다.
3. 대대적으로 코드를 수정하는 과정이 쉽지는 않았지만 끝까지 코드에 대해 계속 고민해보고 주변의 리뷰도 받아보는 과정에서 개발자로서의 태도에 대해 다시 한 번 생각해볼 수 있었다.  </p>
</blockquote>
<p>JavaScript로 구현하였던 기능들을 React로 바꾸는 과정 중한 개 피드 기준으로 작성하였던 코드를 컴포넌트화하고, Mock data와 map 메서드를 도입하여 여러 개의 피드를 구현하였다. 다만, 이 과정에서 댓글 작성 부분이 모든 컴포넌트에서 동일하게 적용되어 한 개의 피드에서 작성한 댓글이 모든 피드에 동시 반영되는 문제를 발견했다. </p>
<h3 id="코드-수정-작업-내용">코드 수정 작업 내용</h3>
<h4 id="기존-코드">기존 코드</h4>
<pre><code class="language-js">import React, { useState, useEffect } from &#39;react&#39;;
import Comment from &#39;./Comment&#39;;
import { FOOTER_INFO_LIST } from &#39;../data/data.js&#39;;
import &#39;./Main.scss&#39;;

const Main = () =&gt;{
 const [inputValue, setInputValue] = useState(&#39;&#39;);
 const [comments, setComments] = useState([{ id: 1, comment: &#39;&#39; }]);

    &lt;ul className=&quot;comment-list&quot;&gt;
           {comments.map(comment =&gt; (
          &lt;Comment key={comment.id} comment={comment.comment} /&gt;))}
    &lt;/ul&gt;  </code></pre>
<p>(기존 문제점) 댓글에 대한 일괄 state 관리 - 각 피드별로 생성되는 댓글에 대해 동일한 comments state 적용</p>
<h4 id="1차-수정-코드">1차 수정 코드</h4>
<ul>
<li>먼저 feed에 대한 mock data와 댓글에 대한 mock data를 분리하여 두 가지 mock data를 생성하고, 각 댓글 데이터에 feedId를 key값으로 부여했다. 그리고 댓글 생성 전 commentList 중 feedId가 동일한 댓글 객체에 대한 filter 메서드를 먼저 적용하였다.<pre><code class="language-json">// data/commentDat.json
[
{
  &quot;id&quot;: 0,
  &quot;feedId&quot;: 1,
  &quot;username&quot;: &quot;JonathanH&quot;,
  &quot;comment&quot;: &quot;Nice pic!&quot;
},
{
  &quot;id&quot;: 1,
  &quot;feedId&quot;: 2,
  &quot;username&quot;: &quot;ARimbaud&quot;,
  &quot;comment&quot;: &quot;Have a nice day!&quot;
},</code></pre>
</li>
</ul>
<pre><code class="language-jsx">const prevComments = commentList.filter(
    comment =&gt; comment.feedId === feed.id
  );</code></pre>
<ul>
<li>이와 같이 수정 후 각 피드별로 댓글 입력 기능이 구현되었으나 두 번에 나누어 id가 부여되다보니 id가 중복되는 경우도 발생하였다. 이럴 경우 댓글 삭제 기능이 적용되지 않아 리뷰를 받던 중, 위와 같이 comment 데이터에서 feedId를 filter하는 것은 실제 데이터 구조와 다르며, 실제 데이터 관리는 각 피드에 대한 데이터 객체에 하나의 key값으로 저장되어 있다는 점을 리뷰로 받았다. </li>
</ul>
<h4 id="최종-수정-코드">최종 수정 코드</h4>
<pre><code class="language-json">// /data/feedData.json
[
  {
    &quot;id&quot;: 1,
    &quot;username&quot;: &quot;Bret&quot;,
    &quot;content&quot;: &quot;Busy street in Helsin...&quot;,
    &quot;account_url&quot;: &quot;https://~&quot;,
    &quot;feed_url&quot;: &quot;https://~&quot;,
    &quot;commentList&quot;: [
      {
        &quot;id&quot;: 0,
        &quot;username&quot;: &quot;JonathanH&quot;,
        &quot;comment&quot;: &quot;Nice pic!&quot;
      },
      {
        &quot;id&quot;: 1,
        &quot;username&quot;: &quot;bkhoon&quot;,
        &quot;comment&quot;: &quot;See you soon!&quot;
      }
    ]
  },</code></pre>
<pre><code class="language-js">// /component/Feed.js
  const [inputValue, setInputValue] = useState(&#39;&#39;);
  const [newCommentList, setNewCommentList] = useState(commentList);

  const addComment = () =&gt; {
    if (inputValue) {
      setNewCommentList([
        ...newCommentList,
        {
          id: newCommentList.length + 1,
          username: &#39;insta_user_ID&#39;,
          comment: inputValue,
        },
      ]);
      setInputValue(&#39;&#39;);
    }
  };
</code></pre>
<p>(방법) 기존에 mock data에서 불러오는 댓글 정보는 commentList라는 props로 Main 컴포넌트에서 Feed로 전달 받고, 새로 생성되는 댓글에 대한 state의 초기값으로 설정했다. 또한 id에 중복값이 생성되는 것을 막기 위해 기존에는 useRef를 이용하였으나, 배열의 length를 이용하는 방법으로 수정하였다. </p>
<p>위와 같이 기존에 data에 저장되어 있는 댓글 정보들을 객체 형태의 초기값으로 전달받고 계속적으로 객체의 형태로 전달 받는 구조로 수정 후 피드별 댓글 추가 및 삭제 모두 정상적으로 작동하는 것을 확인하였다. </p>
<h4 id="정리---데이터-구조-변경에-따른-코드-수정">정리 - 데이터 구조 변경에 따른 코드 수정</h4>
<ol>
<li>JavaScipt로 먼저 구현했던 코드들을 React의 특징에 맞게, 최대한 반복되는 부분에 대해서는 component화 하고, 상수데이터를 코드에 적용해보다보니 코드가 점점 짧아지고 가독성이 좋아지면서 React의 장점을 직접 경험할 수 있었다.</li>
<li>&quot;Mock Data를 활용하여 여러 개의 피드 구현&quot; 과제에서 Mock data 구조에 따라 대대적인 코드 수정을 진행해야했던 점을 교훈 삼아, 다음주부터 진행되는 백엔드와의 협업 프로젝트에서는 먼저 데이터 구조에 대한 충분한 협의 후 코드 작업을 진행해야 겠다고 다시 한번 느끼게 된 경험이었다. </li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Code Kata] 2. 로마자에서 숫자로 바꾸기]]></title>
            <link>https://velog.io/@jw_agnes_baek/Code-Kata-2.-%EB%A1%9C%EB%A7%88%EC%9E%90%EC%97%90%EC%84%9C-%EC%88%AB%EC%9E%90%EB%A1%9C-%EB%B0%94%EA%BE%B8%EA%B8%B0</link>
            <guid>https://velog.io/@jw_agnes_baek/Code-Kata-2.-%EB%A1%9C%EB%A7%88%EC%9E%90%EC%97%90%EC%84%9C-%EC%88%AB%EC%9E%90%EB%A1%9C-%EB%B0%94%EA%BE%B8%EA%B8%B0</guid>
            <pubDate>Wed, 24 May 2023 16:06:18 GMT</pubDate>
            <description><![CDATA[<h4 id="문제">문제</h4>
<p>1~3999 사이의 로마자 s를 인자로 주면 그에 해당하는 숫자를 반환하기</p>
<p>로마자를 숫자로 읽는 방법 - 로마자를 왼쪽부터 차례대로 더하기
III = 3 / XII = 12 / XXVII = 27</p>
<p>그러나 4를 표현할 때는 IIII가 아니라 IV로, 뒤의 숫자에서 앞의 숫자를 빼야함</p>
<pre><code>Symbol       Value
I             1
V             5
X             10
L             50
C             100
D             500
M             1000</code></pre><blockquote>
<p>I는 V와 X앞에 와서 4, 9
X는 L, C앞에 와서 40, 90
C는 D, M앞에 와서 400, 900</p>
</blockquote>
<h4 id="풀이">풀이</h4>
<ol>
<li>먼저 map 메서드으로 각 로마자에 대응하는 숫자로 변환해서 배열을 반환</li>
<li>처음에는 문제에 주어진 I, X, C 사례(4, 40, 400 등)만 고려하여 코드를 작성하다가 1994(MCMXCIV)와 같이 I, X, C와 같은 상황이 두 번 이상 발생할 경우 적용이 안되는 것을 확인하였다. </li>
<li>각 로마자를 하나씩 잘라보다가 다음과 같다는 것을 확인하고 아래와 같이 코드에 적용했다.<blockquote>
<p>MCMXCIV = M + M - C + C - X + V - I</p>
<pre><code>    =&gt; M - C + M - X + C - I + V</code></pre></blockquote>
<pre><code class="language-js">function romanToNum(s) {
const arr = s.split(&quot;&quot;)
const convert = {I:1, V:5, X:10, L:50, C:100, D:500, M:1000}
</code></pre>
</li>
</ol>
<p>const result = arr.map(symbol=&gt; convert[symbol])
 let sum =0;
  for (let i=0; i &lt; result.length; i++){ 
    if(result[i] &lt; result[i+1]){
    sum = sum - result[i]
    } else{
    sum += result[i];<br>    }} 
    return sum;
}</p>
<p>```</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Code Review] 03. React 실습 과제_코드 관련 (구조 분해 할당)]]></title>
            <link>https://velog.io/@jw_agnes_baek/Code-Review-03.-%EC%9D%B8%EC%8A%A4%ED%83%80%EA%B7%B8%EB%9E%A8-%ED%81%B4%EB%A1%A0-%EC%BD%94%EB%94%A91</link>
            <guid>https://velog.io/@jw_agnes_baek/Code-Review-03.-%EC%9D%B8%EC%8A%A4%ED%83%80%EA%B7%B8%EB%9E%A8-%ED%81%B4%EB%A1%A0-%EC%BD%94%EB%94%A91</guid>
            <pubDate>Mon, 22 May 2023 14:49:00 GMT</pubDate>
            <description><![CDATA[<h4 id="정의-구조-분해-할당">(정의) 구조 분해 할당</h4>
<p>배열이나 객체의 속성을 분리해 그 값을 변수에 담을 수 있게 하는 ES6 문법으로, 코드를 직관적이고 간결하게 작성할 수 있게 한다. 함수, 배열, 객체에서 모두 사용 가능하다.</p>
<pre><code class="language-js">// 일반 함수
const user = {
  name: &#39;coder&#39;,
  age: &#39;29&#39;,
  job: &#39;programmer&#39;,
};

const getUserInfo = ({ name, age, job }) =&gt; {
  return `제 이름은 ${name}이고 나이는 ${age}살이며 ${job}입니다.`;
};

getUserInfo(user);</code></pre>
<pre><code class="language-js">// 컴포넌트 함수
// ProductList.js
const ProductList = () =&gt; {
  return (
    &lt;ul&gt;
      {PRODUCT_LIST.map(product =&gt; (
        &lt;li key={product.id}&gt;
          &lt;ProductItem product={product} /&gt;
        &lt;/li&gt;
      ))}
    &lt;/ul&gt;
  );
};

// ProductItem.js
const ProductItem = ({ product: { title, price, quantity } }) =&gt; {
  return (
    &lt;&gt;
      &lt;span&gt;{title}&lt;/span&gt;
      &lt;span&gt;{price}&lt;/span&gt;
      &lt;span&gt;{quantity}&lt;/span&gt;
    &lt;/&gt;
  );
};</code></pre>
<h4 id="코드-리뷰-내용-정리">코드 리뷰 내용 정리</h4>
<p><strong>check 1.</strong> props 대신 구조 분해 할당 적용으로 간결한 코드 구현 하기
<img src="https://velog.velcdn.com/images/jw_agnes_baek/post/c3e8d112-d2e3-48be-94c0-184ad6c2b262/image.png" alt=""></p>
<p><strong>Check 2.</strong> boolean값을 가지는 state 값의 경우 의문형으로 설정하기 
<img src="https://velog.velcdn.com/images/jw_agnes_baek/post/eb2e72cc-ef82-4312-8f83-d70dd7ea1d70/image.png" alt=""></p>
<p><strong>check 3.</strong> 중복되는 부분은 최대한 최소화해서 코드 작성</p>
<pre><code>import React from &quot;react&quot;;
import &quot;./Count.scss&quot;;

const Count = () =&gt; {
const Count = ({ count, onChange }) =&gt; {
  const handleCount = (value) =&gt; {
    if (count + value &lt; 1) return;
    onChange(count + value);
  };

  return (
    &lt;div className=&quot;count&quot;&gt;
      &lt;div className=&quot;countInput&quot;&gt;
        &lt;button onClick={handleCount}&gt;-&lt;/button&gt;
        &lt;div className=&quot;countInputText&quot;&gt;1&lt;/div&gt;
        &lt;button onClick={handleCount}&gt;+&lt;/button&gt;
        &lt;button
          onClick={() =&gt; {
            handleCount(-1);
          }}
        &gt;
          -
        &lt;/button&gt;
        &lt;div className=&quot;countInputText&quot;&gt;{count}&lt;/div&gt;
        &lt;button
          onClick={() =&gt; {
            handleCount(1);
          }}
        &gt;
          +
        &lt;/button&gt;
      &lt;/div&gt;
      &lt;button className=&quot;resetBtn&quot; onClick={() =&gt; {}}&gt;
      &lt;button className=&quot;resetBtn&quot; onClick={() =&gt; onChange(1)}&gt;
        reset
      &lt;/button&gt;
    &lt;/div&gt;</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[Code Review] 02. React 실습 과제_가독성 관련]]></title>
            <link>https://velog.io/@jw_agnes_baek/Code-Review-01.-REACT-%EC%8B%A4%EC%8A%B5-%EA%B3%BC%EC%A0%9C</link>
            <guid>https://velog.io/@jw_agnes_baek/Code-Review-01.-REACT-%EC%8B%A4%EC%8A%B5-%EA%B3%BC%EC%A0%9C</guid>
            <pubDate>Sat, 20 May 2023 17:04:55 GMT</pubDate>
            <description><![CDATA[<h4 id="코드-리뷰-내용-정리">코드 리뷰 내용 정리</h4>
<p><strong>check 1.</strong> 코드의 가독성 측면을 고려해 import하는 파일 순서에 대한 convention 고려하기</p>
<ul>
<li>React → Library/Package → Component → 변수/이미지 → css/scss 파일 </br></li>
<li>reset -&gt; common.scss 순서로 import 해서 사용
<img src="https://velog.velcdn.com/images/jw_agnes_baek/post/a7310031-0da9-4325-979d-ce9370ac62c6/image.png" alt=""></li>
</ul>
<p><strong>check 2.</strong> import되는 파일들 중 누락이나 불필요하게 중복으로 import되는 파일은 없는지 확인
<img src="https://velog.velcdn.com/images/jw_agnes_baek/post/859fe23d-da61-47f6-83ce-b75502aeb4dd/image.png" alt=""></p>
<ul>
<li>common.scss과 reset.scss은 전체 페이지에 적용되어야 하는 부분으로 index.js에서 import 해서 사용하지만, 각 컴포넌트의 scss 파일은 해당 컴포넌트의 js파일에서만 import</li>
</ul>
<p><strong>check 3.</strong>태그에 맞는 표기법 확인 및 상황에 맞는 closing-tag 적용하기</p>
<ul>
<li>속성에 부여하는 값이 문자열일 때는 중괄호를 사용하지 않아도 되며, Input 태그 사이에 입력 값이 없는 경우, self-closing을 적용
<img src="https://velog.velcdn.com/images/jw_agnes_baek/post/6232d4f8-dce2-4521-a76d-6d01eca95414/image.png" alt=""></li>
</ul>
<p><strong>check 4.</strong> 이미지 태그의 alt 속성 누락하지 않기
<img src="https://velog.velcdn.com/images/jw_agnes_baek/post/12b8e5a5-b689-4023-a03e-f415203092e3/image.png" alt=""></p>
<ul>
<li>이미지 태그 alt 속성 작성 시 누락하지 않고, 최대한 구체적으로 작성하여 Redundant alt attribute 오류 방지 하기<blockquote>
<p>Redundant alt attribute. Screen-readers already announce <code>img</code> tags as an image. You don’t need to use the words <code>image</code>, <code>photo,</code> or <code>picture</code> (or any specified custom words) in the alt prop</p>
</blockquote>
</li>
</ul>
<p><strong>check 5.</strong> scss 작성 시에는 각 요소마다 className 부여 후 스타일링
<img src="https://velog.velcdn.com/images/jw_agnes_baek/post/fa803cfb-a66f-45bc-b48b-7c72855ecd22/image.png" alt=""></p>
<ul>
<li>빈번히 사용되는 태그로 스타일링 시 depth에 무관하게 적용되어 의도치 않은 스타일링이 될 수 있으며, 동일한 태그로 선언된 다른 요소에도 영향을 미칠 수 있기 때문이다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[GIT] 팀 프로젝트 초기 세팅 과정]]></title>
            <link>https://velog.io/@jw_agnes_baek/GIT-%ED%8C%80-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EC%B4%88%EA%B8%B0-%EC%84%B8%ED%8C%85</link>
            <guid>https://velog.io/@jw_agnes_baek/GIT-%ED%8C%80-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EC%B4%88%EA%B8%B0-%EC%84%B8%ED%8C%85</guid>
            <pubDate>Wed, 17 May 2023 14:53:41 GMT</pubDate>
            <description><![CDATA[<p>기존에는 개인 Github repository에서만 작업을 하거나 이미 세팅이 완료되어 있는 Repository에서 git clone 후 시작했었다보니, 개발자에게 소통 능력과 협업이 중요하다는 점, 그리고 앞으로 수많은 팀 단위 개발에 Github가 중요한 역할을 한다는 것을 이론적으로만 인지하고 있었다. 그런데 직접 팀 프로젝트 초기 세팅을 진행하면서 어떤 부분들을 초기에 잘 세팅해야 하는지, 초기에 제대로 설정되지 않으면 어떤 문제, 불편함이 있는지 느꼈던 점들에 대해 정리해보았다.   </p>
<h4 id="진행-내용">진행 내용</h4>
<p>팀원들이 모여 하나의 PC에서 팀 프로젝트 초기 세팅을 진행하고 Github에 main branch를 생성 -&gt; 각 팀원이 branch를 생성해 그동안 개개인이 진행하던 인스타그램 클론 코딩 작업 결과물을 팀 프로젝트 폴더로 migration 하는 과정</p>
<h4 id="팀-프로젝트-초기-세팅-checklist">팀 프로젝트 초기 세팅 CHECKLIST</h4>
<p><Strong> 1. CRA 및 Third-Party Library 설치</Strong></p>
<pre><code># CRA, Router, styling(SASS or Styled-components) 설치
$ npx create-react-app [프로젝트명] 
$ npm install react-router-dom
$ npm install sass
$ npm install styled-components styled-reset

# prettier eslint-prettier configuration, stylelint with scss, prettier 패키지, 추가 config 패키지 설치 
$ npm install -D prettier eslint-config-prettier eslint-plugin-prettier
$ npm install -D stylelint stylelint-scss stylelint-config-prettier-scss
$ npm install -D stylelint-config-recommended-scss stylelint-config-property-sort-order-smacss</code></pre><p><img src="https://velog.velcdn.com/images/jw_agnes_baek/post/601c8cf6-b2bf-4387-8545-42969556a2d4/image.png" alt=""></p>
<ul>
<li>git으로 추적되지 않는 node_modules 폴더에 설치된 라이브러리들이 저장되어 있지만, package.json 파일에서 dependencies 항목을 관리함에 따라 초기 세팅 후 git clone 시에는 npm install 명령어 하나로 모든 설치를 완료할 수 있다.  </li>
</ul>
<p><Strong> 2. 공통 폴더 구조 설정</Strong>
<img src="https://velog.velcdn.com/images/jw_agnes_baek/post/13eafcc3-5a47-4d96-9e16-ba9113fde6da/image.png" alt=""></p>
<ul>
<li>CRA로 프로젝트를 시작하는 경우, 불필요한 이미지, 파일, 폴더 등이 생성된 상태로 시작함에 따라, 해당 부분들에 대한 삭제 후 추가 폴더 생성 필요</li>
<li>생성한 컴포넌트와 직접적으로 연관된 폴더는 폴더명을 PascalCase로 작성하고, 간접적인 관계의 폴더는 camelCase로 표기
1) 여러 브랜치에서 충돌이 가능한 폴더에 대해서는 중복 방지를 위해아래와 같이 팀원, 브랜치 혹은 기능별로 추가 폴더 구분이 가능하다. <blockquote>
<p>src
├── assets
│   ├── feature1
│   │   └── heart.jpg
│   └── feature2
├── components
│   └── Nav
│       ├── Nav.js
│       └── Nav.scss
├── pages
│   ├── feature1
│   │   ├── Login
│   │   │   ├── Login.js
│   │   │   └── Login.scss
│   │   └── Main
│   │       ├── Main.js
│   │       └── Main.scss
│   └── feature2
│       ├── Login
│       │   ├── Login.js
│       │   └── Login.scss
│       └── Main
│           ├── Main.js
│           └── Main.scss
├── styles
│   ├── common.scss
│   ├── reset.scss
│   └── variables.scss
├── Router.js
└── index.js
// Router.js</p>
</blockquote>
</li>
</ul>
<p>2) public/images/ VS src/assets/images</p>
<ul>
<li>js파일 안에서 사용하는 이미지는 public/images에 저장해서 사용해야 하며, js 파일에서 public/images로 접근할 때는 절대경로로 접근해야 한다. <pre><code>// ProductDetail.js
import React from &#39;react&#39;;
</code></pre></li>
</ul>
<p>const ProductDetail = () =&gt; {
  return <img src="/images/Detail/product1.jpg" alt="프로덕트1" />;
};</p>
<p>export default ProductDetail;</p>
<p>```</p>
<ul>
<li>css/scss 파일에서는 public 폴더에 접근할 수 없어, background-image 속성처럼 css에서 이미지 파일에 접근하기 위해서는 이미지 파일을 src/assets/images에서 관리해서 절대 경로 혹은 상대 경로로 사용해야 한다. </li>
</ul>
<p><Strong> 3. 팀 단위 작업 시 주의사항</Strong></p>
<p>1) 기존에 개인 폴더에서 작업했던 인스타그램 클론코딩 내용들을 팀 단위 폴더로 이동하는 과정에서 일부 개별적으로 적용했던 css 요소가 깨지는 경우를 확인하였다. 이를 바탕으로 추후 팀별 프로젝트 진행 시 각 기능에 따라 폴더를 구분할 수 있는 JS 부분 이외에 CSS 요소들은 미리 충분한 협의를 통해 reset, common.scss에 대해 정한 뒤 각자 작업을 시작해야 함을 깨달았다.
2) 폴더 구조도 좀 더 복잡해짐에 따라 각각 담당하는 기능, branch에 맡는 폴더에서만의 작업을 진행하여 git에서 merge 시 최대한 충돌이 발생하지 않도록 주의해야겠다고 생각했다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Code Kata] 1. 숫자 배열에서 특정 index 반환하기]]></title>
            <link>https://velog.io/@jw_agnes_baek/Code-Kata-Day-1</link>
            <guid>https://velog.io/@jw_agnes_baek/Code-Kata-Day-1</guid>
            <pubDate>Tue, 16 May 2023 00:42:53 GMT</pubDate>
            <description><![CDATA[<h3 id="문제">문제</h3>
<p><code>twoSum</code>함수에 숫자배열과 &#39;특정 수&#39;를 인자로 넘기면,
더해서 &#39;특정 수&#39;가 나오는 index를 배열에 담아 return해 주세요.
(가정) target으로 보내는 합계의 조합은 배열 전체 중에 2개만 존재</p>
<p>nums: 숫자 배열
target: 두 수를 더해서 나올 수 있는 합계
return: 두 수의 index를 가진 숫자 배열</p>
<blockquote>
<p>예를 들어,
nums: [4, 9, 11, 14], target: 13 인 경우, 
return 값은 [0, 1]
(nums[0] + nums[1] = 4 + 9 = 13)</p>
</blockquote>
<h3 id="풀이">풀이</h3>
<p>array메서드인 push를 적용하여 결과값을 출력해보기 위해 바로 배열에 index 값을 넣어 return하는 1번 풀이법과 2번 풀이법 두 가지를 적용해보았으며, nums, target의 값을 바꾸어도 동일하게 결과가 return되는 것을 확인했다. </p>
<h4 id="풀이-1">풀이 1</h4>
<pre><code class="language-js">const twoSum = (nums, target) =&gt; {
  let sum = 0;
  for (let i = 0; i &lt; nums.length; i++) {
    for (let j = 0; j &lt; nums.length; j++) {
      sum = nums[i] + nums[j];
      if (sum === target) {
        return [i, j];
      }
    }
  }
}</code></pre>
<h4 id="풀이2">풀이2</h4>
<pre><code class="language-js">const twoSum = (nums, target) =&gt; {
  let sum = 0;
  let resultArray =[]
  for (let i = 0; i &lt; nums.length; i++) {
    for (let j = 0; j &lt; nums.length; j++) {
      sum = nums[i] + nums[j];
      if (sum === target) {
         resultArray.push(i, j);
        return resultArray
      }
    }
  }
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Git] Git & Github 명령어_협업 관련]]></title>
            <link>https://velog.io/@jw_agnes_baek/Git-Git-Github-%EB%AA%85%EB%A0%B9%EC%96%B4%ED%98%91%EC%97%85-%EC%8B%9C</link>
            <guid>https://velog.io/@jw_agnes_baek/Git-Git-Github-%EB%AA%85%EB%A0%B9%EC%96%B4%ED%98%91%EC%97%85-%EC%8B%9C</guid>
            <pubDate>Fri, 12 May 2023 16:05:05 GMT</pubDate>
            <description><![CDATA[<h4 id="branch-브랜치">Branch 브랜치</h4>
<ul>
<li>branch란, 독립적으로 작업을 진행하기 위한 공간의 개념 - 같은 프로젝트 아래에 여러 브랜치를 생성하여 다른 기능의 개발이 동시에 진행될 수 있도록 한다.
→ 이에 따라 협업 시 각 개발자가 본인의 브랜치를 생성하여 개발을 완료한 뒤, 최종적으로 메인 브랜치에 모든 브랜치의 변경 사항이 적용되게 함으로써 독립적으로 진행하는 협업자들의 코드가 동일하게 적용될 수 있도록 한다.  </li>
<li>브랜치별로 각 작업 단위의 기록이 단계별로 확인되어 이슈가 발생했을 경우 원인이 되는 작업을 찾아내거나 그에 따른 대책을 세우기 쉬워진다.</li>
<li>git이 새로운 remote repository가 생성되었을 때 설정하는 master가 메인 브랜치로, 해당 브랜치 상에서 새로운 파일을 추가 한다거나 각 브랜치의 변동 사항들에 대한 merge 등이 처리된다. </li>
</ul>
<ol>
<li>git clone</li>
</ol>
<ul>
<li>remote repository에 저장되어 있는 파일들을 local로 복제해오기 위한 명령어<pre><code class="language-powershell">git clone</code></pre>
</li>
<li>해당 프로젝트 폴더 안에 있는 git 폴더도 함께 복제되어져 최초 git init 명령어 실행을 하지 않아도 되게 한다.</li>
</ul>
<ol start="2">
<li>git branch</li>
</ol>
<ul>
<li>새로운 브랜치(독립된 작업 공간)를 생성하거나 해당 프로젝트에 존재하는 모든 브랜치명과 현재 위치를 확인하기 위한 명령어<pre><code class="language-powershell">git branch &lt;new-branch-name&gt;
git branch</code></pre>
</li>
<li>모든 branch는 master/main로 이동(checkout)한 뒤 해당 브랜치에서 생성되어야 한다.</li>
<li>기능 별로 branch를 구분하여 관리할 경우, feature/login과 같이 기능단위 branch(목적)임을 보여주는 브랜치명을 지정할 수 있다.
ex.  feature/login 브랜치에서 로그인 구현이 완료되면 master로 checkout 한 뒤 feature/main 등 다른 브랜치  생성</li>
</ul>
<ol start="3">
<li>git checkout </li>
</ol>
<ul>
<li>다른 브랜치로 이동하기 위한 명령어<pre><code class="language-powershell">git checkout &lt;branch-name&gt;</code></pre>
</li>
</ul>
<ol start="4">
<li>git merge </li>
</ol>
<ul>
<li>현재 브랜치의 코드와 특정 브랜치의 코드를 병합하고 싶은 경우 사용할 수 있는 명령어</li>
<li>특정 브랜치에서 새로운 기능의 구현 및 테스트가 완료되었을 경우, 기준이 되는 master 브랜치에 merge 명령어 실행 가능<pre><code class="language-powershell">git merge &lt;branch-name&gt;</code></pre>
</li>
</ul>
<ol start="5">
<li>git pull</li>
</ol>
<ul>
<li>commit 히스토리를 remote repository에서 local로 가져오기 위한 명령어<pre><code class="language-powershell">git pull origin &lt;branch명&gt;</code></pre>
</li>
</ul>
<ol start="6">
<li>git branch -d</li>
</ol>
<ul>
<li>브랜치를 삭제하기 위한 명령어로 사용 시 유의해야 하는 명령어<pre><code class="language-powershell">git branch -d &lt;branch-name&gt;</code></pre>
</li>
</ul>
<p>[참고] 하나의 branch당 한 개의 PR이 가능하나, commit은 여러 개가 남겨질 수 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Git] Git & Github 명령어_기본]]></title>
            <link>https://velog.io/@jw_agnes_baek/Git-Git-Github-%EB%AA%85%EB%A0%B9%EC%96%B4</link>
            <guid>https://velog.io/@jw_agnes_baek/Git-Git-Github-%EB%AA%85%EB%A0%B9%EC%96%B4</guid>
            <pubDate>Fri, 12 May 2023 15:07:09 GMT</pubDate>
            <description><![CDATA[<h4 id="git">Git</h4>
<ul>
<li>프로젝트 파일의 변경 사항을 추적하는 분산 버전 관리 시스템 (VCS)</li>
<li>프로젝트의 변경 사항을 기록하여 특정 시점의 버전으로 복구하는 것을 가능하게 하고, 프로젝트 중심으로 여러 개발자가 협업할 때는 각자의 컴퓨터에서 작업하던 다양한 버전의 파일들을 병합하여 기준이 되는 버전의 프로젝트에 동일하게 적용 될 수 있게 한다.</li>
</ul>
<h4 id="repositories-저장소"><strong>Repositories (저장소)</strong></h4>
<p>Git repository는 Git 으로 관리하는 프로젝트 저장소이며, local 과 remote으로 구분된다. </p>
<p>1) Local repository: 개인의 컴퓨터에 저장된 프로젝트 저장소
2) Remote repository: 외부의 프로젝트 저장소
(ex. 원격 서버)
→ remote repository에서는 코드를 공유하거나, 로컬 버전의 프로젝트와 코드를 병합하거나, 변경 사항을 적용하는 것 등이 가능해 팀 단위로 협업 시 유용하게 사용된다. </p>
<h4 id="git-명령어">Git 명령어</h4>
<ol>
<li>git init - initializing a repository</li>
</ol>
<ul>
<li>처음 git으로 새로운 프로젝트를 관리하기 위해 프로젝트 폴더에서 입력해야 하는 명령어 <pre><code class="language-powershell">git init</code></pre>
</li>
<li>해당 명령어 실행 시, 프로젝트 폴더 내에 .git 디렉토리가 생성되어 <strong>git이 해당 저장소에 대한 모든 변경 사항을 추적/관리</strong>할 수 있게 된다. </li>
</ul>
<ol start="2">
<li>git add - staging files </li>
</ol>
<ul>
<li>commit 진행 전 수정한 파일들의 이력을 남길 준비를 하는 명령어
(수정 내역을 staging area에 추가하기 위한 단계로, 쇼핑몰의 장바구니 같은 개념)
1) 특정 파일만 이력을 남기고 싶을 경우<pre><code class="language-powershell">git add file.js </code></pre>
2) 파일을 각각 추가하지 않고, 수정 이력이 있는 모든 파일의 이력을 남기고 싶은 경우<pre><code class="language-powershell">git add .</code></pre>
</li>
</ul>
<ol start="3">
<li>git status</li>
</ol>
<ul>
<li>add 명령어까지 실행한 git의 상태를 확인하기 위한 명령어로, 어떤 파일이 수정, 추가되었는지 또는 추적되지 않고 있는지 등 디렉토리에서 일어나고 있는 상태를 확인 할 수 있게 한다.
 <strong><code>git status</code></strong> 명령어를 통해 어떤 파일이 확인할 수 있습니다.<pre><code class="language-powershell">git status</code></pre>
</li>
</ul>
<ol start="4">
<li>git commit</li>
</ol>
<ul>
<li>staging area로 옮겼던 파일들을 실제 저장하여 수정한 파일들의 이력을 남기는 명령어</li>
<li>일반적으로 특정 기능을 추가하거나 수정 사항을 적용한 후 commit을 남길 수 있다. </li>
</ul>
<p>1) 한줄로 commit 메세지를 남기고 싶을 경우</p>
<pre><code class="language-powershell">git commit -m &quot;commit message&quot;</code></pre>
<p>2) 여러 줄의 commit 메세지를 남기고 싶을 경우</p>
<pre><code class="language-powershell">git commit</code></pre>
<p>-&gt; git commit을 입력하면 멀티라인으로 메시지를 쓸 수 있는 에디터로 이동</p>
<ul>
<li>Git에서 commit 이란, 프로젝트의 현재 상태를 나타내는 체크포인트로, 여러 개의 commit을 생성 할 수 있다. 
(새 commit을 남기기 위해서는 staging area에 파일을 추가하는 명령어를 먼저 실행해야 한다.)</li>
<li>commit 로그에서 시점을 이동하며 프로젝트 코드의 변경사항을 확인할 수 있어 프로젝트의 진행 상황을 효율적으로 관리할 수 있다.</li>
</ul>
<ol start="5">
<li>git log</li>
</ol>
<ul>
<li>commit했던 이력을 확인할 수 있게 하는 명령어로, 작성자, hash 값, 작성 시점, commit 메세지 등을 확인할 수 있다. </li>
<li>특정 commit 시점의 코드로 되돌리고 싶은 경우의 명령어<pre><code class="language-powershell">git checkout &lt;commit-hash&gt;</code></pre>
</li>
</ul>
<ol start="6">
<li>git push</li>
</ol>
<ul>
<li>작성한 코드를 실제 remote repository에 업로드하기 위한 명령어 (local → remote repository 로 push)<pre><code class="language-powershell">git push origin master</code></pre>
</li>
<li>master 자리에 실제 branch명 작성 필요</li>
</ul>
<ol start="7">
<li>&#39;.gitignore&#39; 파일  - ignoring files</li>
</ol>
<ul>
<li>보안, 용량 등의 문제로 git에서 관리, 추적하지 않기 위한 파일들의 경우에는 프로젝트 폴더에 &#39;.gitignore&#39;파일을 생성하여 관리할 수 있다. </li>
<li>&#39;.gitignore&#39;파일 안에, 해당 파일명과 폴더명을 나열하면 git의 추적을 받지 않게 된다.
(각 파일/폴더 당 새로운 줄에 입력)
```powershell</li>
<li>.log</li>
<li><em>/</em>.backup.*</li>
<li><em>/</em>.back.*
node_modules
bower_components
```</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[알고리즘] 정수-> 문자열 반환]]></title>
            <link>https://velog.io/@jw_agnes_baek/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EB%AC%B8%EC%9E%90%EC%97%B4-%EB%B0%98%ED%99%98</link>
            <guid>https://velog.io/@jw_agnes_baek/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EB%AC%B8%EC%9E%90%EC%97%B4-%EB%B0%98%ED%99%98</guid>
            <pubDate>Wed, 26 Apr 2023 01:25:06 GMT</pubDate>
            <description><![CDATA[<p>[문제] 정수 n이 주어질 때, n을 문자열로 반환하여 return하도록 solution 함수를 완성해주세요.</p>
<pre><code class="language-js">const solution = (n) =&gt; {
    let answer = n.toString();
    return answer;
    }</code></pre>
<p>위와 같이 작성하여 정상적으로 작동되는 것을 확인했는데, 다른 풀이방법들을 확인하던 중 아래와 같은 풀이방법을 확인하였다. </p>
<pre><code class="language-js">const solution = n =&gt; String(n)</code></pre>
<p>앞으로는 작동하는 방법을 찾는데만 집중하기보다는 좀 더 다양하게 가독성을 높이는 방법은 없을지 지속적으로 고민해보는 습관이 필요하겠다고 생각했다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[알고리즘] 짝수의 합]]></title>
            <link>https://velog.io/@jw_agnes_baek/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%A7%9D%EC%88%98%EC%9D%98-%ED%95%A9</link>
            <guid>https://velog.io/@jw_agnes_baek/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%A7%9D%EC%88%98%EC%9D%98-%ED%95%A9</guid>
            <pubDate>Wed, 26 Apr 2023 01:13:32 GMT</pubDate>
            <description><![CDATA[<p>[문제] 정수 n이 주어질 때, n 이하의 짝수를 모두 더한 값을 return 하도록 solution 함수를 작성해주세요.</p>
<pre><code class="language-js">const solution = (n) =&gt; {
let answer = 0;
  for (let i =0 ; i&lt;=n; i++) {
    if (i % 2 === 0) {
      answer += i;
    }}
  return answer;
}</code></pre>
<p>출처- 프로그래머스</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[알고리즘] Q1-5 (splice, unshift, for loop, parseInt, Math.max, indexOf, filter)]]></title>
            <link>https://velog.io/@jw_agnes_baek/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EB%AC%B8%EC%A0%9C-Q1-5</link>
            <guid>https://velog.io/@jw_agnes_baek/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EB%AC%B8%EC%A0%9C-Q1-5</guid>
            <pubDate>Fri, 21 Apr 2023 15:28:08 GMT</pubDate>
            <description><![CDATA[<ol>
<li>Array.prototype.splice()<blockquote>
<p>MDN Syntax
splice(start)
splice(start, deleteCount)
splice(start, deleteCount, item1)
splice(start, deleteCount, item1, item2, itemN)</p>
</blockquote>
</li>
</ol>
<pre><code class="language-jsx">// 문제 1

const arr = [100, 200, 300]

arr.splice (1, 2, 150, 250, 500)

console.log(arr); // 결과값: [100, 150, 250, 500]</code></pre>
<ol start="2">
<li>Array.prototype.unshift()<blockquote>
<p>MDN
The unshift() method adds the specified elements to the beginning of an array and <strong>returns the new length of the array.</strong></p>
</blockquote>
</li>
</ol>
<pre><code class="language-jsx">// 문제 2 

const arr = [1, 3, 4, 6, 9];
const result = [];

for (let i=0; i&lt;arr.length; i++) {
  result.unshift(arr[i]);
}

console.log(result); // 결과값 [9, 6, 4, 3, 1]</code></pre>
<ol start="3">
<li>구구단 프로그램 출력<pre><code class="language-jsx">// 문제 3
</code></pre>
</li>
</ol>
<p>for (let i=2; i&lt;10; i++) {
    console.log(<code>${i}단</code>)</p>
<pre><code>for (let j=1; j&lt;10; j++) {
    console.log(`${i} * ${j} = ${i*j}`)
}

console.log(``) //구구단 프로그램 출력</code></pre><p>}</p>
<pre><code>
4. 공백으로 구분된 8개의 숫자들 중 최댓값을 반환하는 코드
parseInt() : string을 number형으로 변환
```jsx
// 문제 4

const numbers = &quot;10 11 5 6 12 7 3 9&quot;
let arr = numbers.split(&quot; &quot;).map((num)=&gt; parseInt(num))
console.log(Math.max(...arr)); // 결과값 12</code></pre><ol start="5">
<li>배열 내 중복된 단어를 제거하는 함수
Array.prototype.indexOf()<blockquote>
<p>MDN
The indexOf() method returns the first index at which a given element can be found in the array, or -1 if it is not present.
MDN Syntax
indexOf(searchElement)
indexOf(searchElement, fromIndex)</p>
</blockquote>
<pre><code class="language-jsx">// 문제 5
function func(words){
const result = words.filter ((word, index)=&gt;{
return words.indexOf(word)===index
}) 
console.log(result); 
}
</code></pre>
</li>
</ol>
<p>const words = [&#39;Have&#39;, &#39;A&#39;, &#39;Good&#39;, &#39;Time&#39;, &#39;Have&#39;, &#39;Good&#39;]
func(words) // 결과값 [&#39;Have&#39;, &#39;A&#39;, &#39;Good&#39;, &#39;Time&#39;]</p>
<p>```</p>
<p>출처
<a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice">https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice</a>
<a href="https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/unshift">https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/unshift</a>
<a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf">https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[개발자 도구 - Elements/Console/Network/Application panel]]></title>
            <link>https://velog.io/@jw_agnes_baek/%EA%B0%9C%EB%B0%9C%EC%9E%90-%EB%8F%84%EA%B5%AC-ElementsConsoleNetworkApplication-panel</link>
            <guid>https://velog.io/@jw_agnes_baek/%EA%B0%9C%EB%B0%9C%EC%9E%90-%EB%8F%84%EA%B5%AC-ElementsConsoleNetworkApplication-panel</guid>
            <pubDate>Tue, 11 Apr 2023 14:05:48 GMT</pubDate>
            <description><![CDATA[<h4 id="개발자-도구를-여는-방법">개발자 도구를 여는 방법</h4>
<ol>
<li>마우스 오른쪽 버튼을 눌러 &#39;검사&#39; 버튼</li>
<li>크롬에서 Command/Ctrl + Shift + C 단축키 사용</li>
<li>단축키 F12</li>
</ol>
<h4 id="elements-panel">Elements panel</h4>
<ul>
<li>웹 페이지의 구성 요소(HTML, CSS 요소)들을 확인할 수 있는 패널</li>
<li>실제 적용되어 있는 코드들을 확인하고, 실제 웹페이지 데이터에는 영향을 주지 않으면서 요소들을 직접 조작해서 CSS요소 등을 변경하고 적용해볼 수 있다. </li>
<li>특히 FE에서 많이 사용하는 panel이며, 실시간으로 구성 요소들의 변화를 확인할 수 있어 실무에서 PM-디자이너-개발자 간의 소통 시에도 자주 사용되는 패널</li>
</ul>
<h4 id="console-panel">Console panel</h4>
<ul>
<li>Console 패널은 Javascript를 조작할 수 있는 패널</li>
<li>Console 패널에서는 실제 웹 페이지에 적용되어 있는 코드는 조작할 수는 없으나, 콘솔창에 코드를 쳐서 웹 브라우저를 조작할 수 있다. </li>
<li>Javascript 파일에서처럼 변수 선언, 함수 생성, alert 이벤트 추가 등이 가능한 패널 </li>
<li>Console 패널도 프론트엔드 개발자가 가장 많이 사용하는 패널로, 서버에서 받아오는 데이터가 잘 들어오는지, 의도대로 기능이 구현되는지 등을 확인할 때 사용할 수 있다.</li>
<li>개발자 도구는 정말 개발자들만 사용하고 열어본다는 특징을 이용하여, 다른 개발자들이 볼 수 있는 메시지가 작성되어 있는 등 개발자를 위한 공간으로도 활용되는 패널 </li>
</ul>
<p><strong>[MDN] Console API reference 중</strong></p>
<ol>
<li>console.log (&#39;log&#39;);
: &#39;Prints a message to the Console.&#39;</li>
</ol>
<ul>
<li>변수, 텍스트, 숫자, 함수 등 다양한 값을 넣고 Console 패널에서 확인하는 API<br></li>
</ul>
<ol start="2">
<li>console.clear( );
: &#39;Clears the console.&#39;
: &#39;If Preserve Log is enabled, console.clear() is disabled.&#39;</li>
</ol>
<ul>
<li>콘솔에 기록된 로그들을 모두 지울 때 사용하는 API</li>
<li>Preserve Log 설정이 되어 있는 경우에는 console.clear();를 실행할 수 없다.</li>
<li>Preserve log 활성화하는 방법: &quot;관리자도구 &gt; 설정 &gt; Preferences &gt; Console&gt; ‘Preserve log upon navigation’&quot; 활성화</li>
<li>다른 패널에서 ESC키 누르면 Console 패널을 같이 사용할 수 있다.</li>
</ul>
<h4 id="network-panel">Network panel</h4>
<ul>
<li>클라이언트와 서버 간에 발생하는 통신의 정보를 확인할 수 있는 패널로, 프론트엔드, 백엔드 개발자가 모두 많이 사용하는 패널</li>
<li>클라이언트가 네트워크 요청을 하고 받는 응답 내용을 확인할 수 있고, 데이터, 이미지, 동영상 등 형식별로 주고 받는 데이터를 구분하여 확인할 수 있다.
ex. Fetch/XHR 탭 - 데이터 요청을 하고 전달받는 데이터를 확인</li>
<li>통신 과정에서 에러가 발생했을 경우에 &#39;status code&#39;를 통해 어떤 에러인지 확인할 수 있다. 
ex. 200번대 코드 - 통신 성공 코드, 400번대 코드 - 주로 클라이언트 측의 원인, 500번대 코드는 주로 서버 측의 원인</li>
</ul>
<h4 id="application-panel">Application panel</h4>
<ul>
<li>브라우저의 저장소에 저장된 데이터를 확인할 수 있는 패널</li>
<li>브라우저 저장소에는 크게 Local Storage, Session Storage, Cookies가 있으며, 각 저장소 특징에 따라 다른 기능을 구현하는데 사용할 수 있다.</li>
<li>다만, 데이터가 클라이언트 측에 저장되어 쉽게 해킹 될 수 있고 JavaScript을 통해 쉽게 조작이 가능하기 때문에 민감한 정보나 보안상 이슈가 있는 정보를 저장하기에는 적합하지 않다. </li>
<li>저장소 특징에 따라 사용되는 상황이 다르며, 같은 기능에 대해서도 사이트/서비스의 특성, 회사의 방침 등에 따라 달라질 수 있다.</li>
</ul>
<p>1) Local Storage</p>
<ul>
<li>세 가지 저장소 중 가장 용량(Capacity)이 큰 저장소(10mb)로, 저장된 데이터는 물리적으로나 코드로 제거하지 않은 한, 브라우저가 종료되어도 삭제되지 않는다.</li>
<li>이에 따라 자동 로그인 기능을 구현할 때 사용되기도 하는 저장소</li>
<li>Local Storage에 데이터 저장: &quot;localStorage.setItem(&quot;key&quot;, &quot;value&quot;)&quot;</li>
<li>Local Storage의 데이터 호출: &quot;localStorage.getItem(&quot;key&quot;)&quot;</li>
</ul>
<p>2) Session Storage</p>
<ul>
<li>Session Storage는 5mb 크기의  용량을 가지고 있으며, 브라우저가 종료되면 데이터도 함께 삭제되는 저장소</li>
<li>Session Storage에 데이터 저장: &quot;sessionStorage.setItem(&quot;key&quot;, &quot;value&quot;)&quot;</li>
<li>Session Storage의 데이터 호출: &quot;sessionStorage.getItem(&quot;key&quot;)&quot;</li>
</ul>
<p>3) Cookies</p>
<ul>
<li>가장 작은 용량의 저장소(4kb)이며, 다른 저장소와 달리 브라우저에서 뿐만 아니라 서버에서도 사용 가능한 저장소 </li>
<li>데이터 저장 시간에 대한 제한 설정이 가능해서, 브라우저가 종료 되더라도 데이터는 삭제되지 않고 설정한 시간이 만료되면 사라진다는 특징이 있다.</li>
<li><blockquote>
<p>이에 따라 오늘 하루 팝업 그만 보기와 같은 기능을 구현할 때 사용할 수 있다.</p>
</blockquote>
</li>
<li>Cookie 데이터 설정: &quot;setcookie(&quot;key&quot;, &quot;value&quot;, &quot;초 단위의 지속 시간&quot;)&quot;</li>
<li>데이터를 호출: &quot;document.cookie&quot;</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[CSS] position 속성: static, relative, absolute, fixed]]></title>
            <link>https://velog.io/@jw_agnes_baek/CSS-position-%EC%86%8D%EC%84%B1-static-relative-absolute-fixed</link>
            <guid>https://velog.io/@jw_agnes_baek/CSS-position-%EC%86%8D%EC%84%B1-static-relative-absolute-fixed</guid>
            <pubDate>Thu, 06 Apr 2023 07:13:44 GMT</pubDate>
            <description><![CDATA[<h3 id="position-속성-static-relative-absolute-fixed">position 속성: static, relative, absolute, fixed</h3>
<ul>
<li>position 속성에는 static, relative, absolute, fixed, sticky이 있으며, 이 중 relative와 absolute가 많이 사용됨</li>
</ul>
<h4 id="1-static">1) static</h4>
<ul>
<li><p>기본 설정값으로 되어 있으며, 별도의 위치 지정 없이 웹 페이지 상의 흐름에 따라 해당 요소가 배치된다. </p>
</li>
<li><p>‘A static element is said to be <em>not positioned</em> and an element with its position set to anything else is said to be <em>positioned</em>.’</p>
</li>
</ul>
<h4 id="2-relative">2) relative</h4>
<ul>
<li><p>별도의 속성이 추가로 부여되기 전까지는 static과 동일하게 작동되며, 추가로 top, right, bottom, left 속성을 부여하여 위치로 조정할 수 있다. </p>
</li>
<li><p>이 때 다른 요소들의 위치에는 영향을 주지 않는다.<br>(Other content will not be adjusted to fit into any gap left by the element.)</p>
</li>
</ul>
<h4 id="3-absolute">3) absolute</h4>
<ul>
<li>특정 부모에 대해 절대적인 위치에 배치할 수 있게 하는 것으로, 부모 요소의 position에 relative, fixed, absolute 중 하나라도 있으면 그 부모에 대해 절대적으로 움직이게 된다. </li>
<li>특정 부모 요소가 지정되지 않았을 경우, body에 대해 적용된다. </li>
<li>absolute 값을 갖게 되면 block element도 inline element 처럼 내용의 크기만큼의 너비를 갖게 된다. </li>
</ul>
<h4 id="4-fixed">4) fixed</h4>
<ul>
<li>브라우저 화면 내에서 스크롤해도 같은 위치에 특정 요소를 고정하기 위해 사용되는 값으로, relative같이 top, right, bottom, left 속성과 함께 사용되며, 부모 태그에 relative를 부여할 필요 없이 설정이 가능하다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[CSS] display 속성 - block, inline, inline-block, none]]></title>
            <link>https://velog.io/@jw_agnes_baek/CSS-display-%EC%86%8D%EC%84%B1-block-inline-inline-block-none</link>
            <guid>https://velog.io/@jw_agnes_baek/CSS-display-%EC%86%8D%EC%84%B1-block-inline-inline-block-none</guid>
            <pubDate>Thu, 06 Apr 2023 05:30:06 GMT</pubDate>
            <description><![CDATA[<h3 id="display-속성-block-inline-inline-block-none">display 속성: block, inline, inline-block, none</h3>
<ul>
<li>CSS로 각 요소의 속성도 변경이 가능함에 따라 interactive한 웹 구현을 위해 각 요소에 클래스를 부여하여 각 요소들의 display 속성을 바꿀 수 있다.</li>
</ul>
<h4 id="1-block-요소"><strong>1) block 요소</strong>:</h4>
<p>ex) header, footer, p, li, table, div, h1 </p>
<ul>
<li>block 요소 바로 옆의 같은 줄에는 다른 요소를 배치할 수 없다. 옆에 공간이 남아도 다음 block 요소는 다음 줄로 넘어가게 된다. </li>
<li>block 요소의 width는 부모 태그의 가로 전체 너비와 같고, 세로 크기는 해당 태그 내부에 있는 내용이나 요소의 크기에 의해 결정되나, 별도로 width나 height를 설정할 수 있다.</li>
</ul>
<h4 id="2-inline-요소"><strong>2) inline 요소</strong>:</h4>
<p>ex) span, a, img, strong 태그</p>
<ul>
<li>inline 요소들은 줄 바꿈 없이 바로 옆에 다른 요소를 위치시킬 수 있다.  </li>
<li>각 요소의 width, height 크기 설정이 불가능하다.
(img태그만 예외)</li>
<li>CSS property: display, float를 이용하여 inline 속성을 부여할 수 있다.<pre><code class="language-css">.inlineP {
display: inline-block;
}
</code></pre>
</li>
</ul>
<p>.floatLeft {
float: left;
}</p>
<p>```</p>
<h4 id="3-inline-block-요소"><strong>3) inline-block 요소</strong>:</h4>
<ul>
<li>inline 요소와 같이 줄 바꿈 없이 옆에 다른 요소를 가질 수 있고, block 요소의 특징과 같이 width, height 크기 설정이 가능하다.</li>
</ul>
<h4 id="4-none">4) none:</h4>
<ul>
<li>화면에서 해당 요소가 보이지 않게 하는 것으로, script 태그와 같이 일부 요소들은 none을 기본값으로 갖는다. </li>
<li>JavaScript와 사용하여 특정 요소를 숨기거나 다시 보여지게 할 때 이용된다. </li>
</ul>
<p>[참고] &#39;visibility: hidden&#39;; vs &#39;display: none&#39;;</p>
<ul>
<li>display 속성을 사용할 경우 아예 페이지에 해당 요소가 존재하지 않는 것처럼 보이게 하는 반면, visibility 속성을 사용할 경우에는 요소의 내용은 보이지 않으나 여전히 해당 요소 크기만큼의 공간은 남아있다는 차이점이 있다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[HTML] Semantic Web, Semantic Tag_<img>태그 vs background-image 속성]]></title>
            <link>https://velog.io/@jw_agnes_baek/Semantic-elements-img%ED%83%9C%EA%B7%B8</link>
            <guid>https://velog.io/@jw_agnes_baek/Semantic-elements-img%ED%83%9C%EA%B7%B8</guid>
            <pubDate>Wed, 05 Apr 2023 07:01:59 GMT</pubDate>
            <description><![CDATA[<h3 id="semantic-web-and-semantic-tag">Semantic Web and Semantic Tag</h3>
<h4 id="semantic-web">Semantic Web</h4>
<ul>
<li>웹의 창시자인 팀 버너스리가 1998년 제안한 개념이며, 현재 W3C에 의해 표준화 작업이 진행 중</li>
<li>Semantic Web이란 &#39;의미론적인 웹&#39;이라는 의미로, 컴퓨터가 자체적으로 네트워크 상에 있는 정보 자원의 의미를 이해하고 스스로 데이터의 재사용을 수행할 수 있도록 하는 웹을 의미</li>
</ul>
<h4 id="semantic-tag">Semantic Tag</h4>
<ul>
<li>Semantic tag를 사용하면 코드의 가독성을 높여 해당 요소의 의미를 브라우저, 검색엔진, 개발자 모두가 명확하게 파악할 수 있게 한다. 이 경우 개발자는 해당 코드의 유지 보수를 쉽게 할 수 있고, 검색엔진은 효과적인 크롤링 및 인덱싱을 통해 Semantic web을 실현할 수 있게 한다. </li>
<li>웹 페이지의 구역을 정의하기 위해 사용하는 Semantic tag에는 header, nav, section, article, footer, aside 태그 등이 있다.</li>
</ul>
<h3 id="이미지를-추가하는-방법">이미지를 추가하는 방법</h3>
<ul>
<li>이미지를 추가하는 방법은 아래 두 가지로 구분할 수 있으며 각 상황을 고려하여 더 적절한 방법을 선택할 수 있다. </li>
<li>img 태그를 사용하여 추가하는 방법 (Semantic한 방법)</li>
<li>div 태그에 background-image 속성을 사용하여 추가하는 방법 (Non-semantic한 방법)</li>
</ul>
<ol>
<li>img 태그를 사용</li>
</ol>
<ul>
<li>img 태그에는 &#39;alt&#39; 속성을 부여할 수 있어 이미지가 보여지지 않는 경우에도 해당 이미지에 대한 정보 전달이 가능</li>
<li><blockquote>
<p>이미지에 구체적인 정보가 담겨 있는 경우에는 img 태그를 사용하는 것이 더 효율적</p>
</blockquote>
</li>
<li>배경 이미지로 추가되는 경우, 기본 인쇄 옵션에서 제외됨에따라 해당 이미지가 포함되게 출력하기 위해서는 img 태그를 사용하여 이미지를 추가</li>
<li>Semantic tag인 img 태그를 사용하면 검색 엔진의 인덱싱에 포함되어 이미지 노출을 통한 SEO 효과를 누릴 수 있음</li>
</ul>
<ol start="2">
<li>div 태그의 background-image 속성을 사용</li>
</ol>
<ul>
<li>해당 이미지가 디자인 요소로만 사용되어 콘텐츠에 직접적인 영향을 미치지 않을 경우에는 background-image 속성으로 이미지 추가하는 것이 효율적</li>
<li>img 태그로 이미지를 추가하면 파일명이나 경로가 변경될 경우, HTML 마크업도 함께 수정해야 하는 반면, background-image 속성으로 추가하는 경우에는 CSS 수정만으로 관리가 가능</li>
<li>콘텐츠 인쇄 시 해당 이미지가 출력되지 않게 하는 경우에는 background-image 속성 사용</li>
</ul>
<p>Reference
<a href="https://www.w3schools.com/html/html5_semantic_elements.asp">https://www.w3schools.com/html/html5_semantic_elements.asp</a>
<a href="https://ko.wikipedia.org/wiki/%EC%8B%9C%EB%A7%A8%ED%8B%B1_%EC%9B%B9">https://ko.wikipedia.org/wiki/%EC%8B%9C%EB%A7%A8%ED%8B%B1_%EC%9B%B9</a>
<a href="https://inseq.co.kr/ko/bbs/i-24/show.do?seq=19&amp;searchCl1=&amp;searchMulti=&amp;searchKeyword=">https://inseq.co.kr/ko/bbs/i-24/show.do?seq=19&amp;searchCl1=&amp;searchMulti=&amp;searchKeyword=</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[WEB] 웹 서비스 주요 키워드 개념 ]]></title>
            <link>https://velog.io/@jw_agnes_baek/WEB-%EC%9B%B9-%EC%84%9C%EB%B9%84%EC%8A%A4-%EC%A3%BC%EC%9A%94-%ED%82%A4%EC%9B%8C%EB%93%9C-%EA%B0%9C%EB%85%90</link>
            <guid>https://velog.io/@jw_agnes_baek/WEB-%EC%9B%B9-%EC%84%9C%EB%B9%84%EC%8A%A4-%EC%A3%BC%EC%9A%94-%ED%82%A4%EC%9B%8C%EB%93%9C-%EA%B0%9C%EB%85%90</guid>
            <pubDate>Wed, 05 Apr 2023 03:30:04 GMT</pubDate>
            <description><![CDATA[<h4 id="클라이언트client-및-서버server">클라이언트(Client) 및 서버(Server)</h4>
<ul>
<li><strong>클라이언트</strong>는 서버에 정보나 서비스를 요청하는 측을 의미하며, <strong>서버</strong>는 정보나 서비스를 저장하고 있다가 클라이언트의 요청이 있을 때, 네트워크를 이용해 해당 데이터를 전달해주는 측 </li>
<li><strong>클라이언트</strong>는 사용자가 사용하는 기기의 웹 브라우저를 의미하지만, 사용자 자체나 사용자가 사용하는 기기를 클라이언트라고 지칭하기도 한다. <strong>서버</strong> 또한 물리적인 하드웨어를 의미하지만, 서버 내의 웹 서버 소프트웨어를 서버라고도 지칭하기도 한다.</li>
</ul>
<h4 id="요청request과-응답response">요청(Request)과 응답(Response)</h4>
<ul>
<li>클라이언트-서버 간의 통신은 요청-응답의 구조로 이루어진다.</li>
<li>클라이언트 측이 서버 측에 어떤 정보나 서비스를 제공해달라고 전송하는 메시지를 <strong>요청</strong>, 서버에서 해당 요청에 맞는 데이터를 전달해주는 메시지를 <strong>응답</strong>이라고 한다.</li>
<li>클라이언트 측은 주소 표시줄을 통해서 특정 서버에 정보를 요청할 수 있고, 클라이언트-서버 간의 통신에서는 HTTP (HyperText Transfer Protocol)가 사용된다.   </li>
</ul>
<h4 id="프론트엔드front-end와-백엔드back-end">프론트엔드(Front-End)와 백엔드(Back-End)</h4>
<ul>
<li><strong>프론트엔드</strong>는 웹 애플리케이션에서 사용자들에게 보여지는 부분을 의미하며, HTML, CSS로 이루어지는 디자인 요소와 이미지 슬라이드나 팝업 등 JavaScript로 구현되어야 하는 부분들이 있다. </li>
<li><strong>프론트엔드 개발자</strong>는 서버 측에 요청하고 반환된 정보가 사용자에게 보여지는 화면 구성을 담당함에 따라 애플리케이션의 사용자 인터페이스(User Interface, UI)와 사용자 경험(User Experience, UX) 최적화를 고려해야 한다.</li>
<li><strong>백엔드</strong>는 웹 애플리케이션에서 사용자가 보지 못하는 영역인 서버나 데이터베이스 등을 의미한다.</li>
<li><strong>백엔드 개발자</strong>는 사용자들의 요청에 해당하는 정보를 제공하기 위한 API 작성, 라이브러리 생성, 데이터베이스 통합 등 데이터를 관리하거나 서버를 운영하는 일을 담당한다. </li>
</ul>
<h4 id="네트워크-network-와-ip주소">네트워크 (Network) 와 IP주소</h4>
<ul>
<li><strong>네트워크</strong>란 서버, 라우터, 스위치 등 네트워크 장치(노드)들이 서로 유선이나 무선의 통신망(링크)으로 연결되어 자원이나 정보를 공유하는 집합을 의미한다. </li>
<li>네트워크 장치들은 노드 간 연결을 통해 프로토콜을 사용하여 데이터를 교환한다.</li>
<li><strong>IP 주소</strong>는 네트워크 상에서 각 네트워크 장치를 식별하기 위해 특수한 번호로 부여되는 논리적인 주소를 의미한다.</li>
<li>현재 주로 사용되는 IP주소 형태는 0부터 255까지의 숫자가 네 마디로 구분되는 IPv4 방식</li>
</ul>
<h4 id="라우터router">라우터(Router)</h4>
<ul>
<li><strong>라우터</strong>는 서로 다른 네트워크 간의 통신 과정에서 중계 역할을 해주는 장치로, 패킷 소모를 최소화하고 경로를 최적화하여 패킷을 포워딩 해주는 장치를 의미한다.</li>
<li>코어 라우터, 센터 라우터, 브로드밴드 라우터 등 네트워크에서 쓰이는 위치나 규모 등에 따라 종류가 구분된다. </li>
</ul>
<h4 id="tcpip">TCP/IP</h4>
<p>(Transmission Control Protocol/Internet Protocol)</p>
<ul>
<li><strong>TCP/IP</strong>는 네트워크에서 사용되는 통신 프로토콜의 집합으로, 프로토콜의 네트워크 범위에 따라 애플리케이션 계층, 전송 계층, 인터넷 계층, 링크 계층으로 구분한다.
1) 애플리케이션 계층: HTTP, DNS 등 응용 프로그램이 사용되는 프로토콜 계층
2) 전송 계층: 송신자와 수신자를 연결하는 통신 서비스를 제공하는 프로토콜 계층으로, 애플리케이션과 인터넷 계층 사이의 데이터가 전달될 때 중계 역할을 담당
3) 인터넷 계층 - 장치로부터 받은 네트워크 패킷을 IP 주소로 지정된 목적지로 전송하기 위해 사용되는 계층
4) 링크 계층 - 전선, 무선 등으로 데이터를 전달하며 장치 간에 신호를 주고 받는 규칙을 정하는 계층</li>
</ul>
<h4 id="데이터베이스-database">데이터베이스 (Database)</h4>
<ul>
<li>** 데이터베이스**는 일정한 규칙이나 규약을 통해 구조화되어 저장되는 데이터의 모음을 의미한다. 각 데이터를 담는 테이블로 구성되어 있으며, 데이터 저장 형식에 따라 데이터베이스는 RDBMS와 NoSQL로 구분할 수 있다. </li>
<li>데이터베이스도 하나의 프로그램으로서 작동하기 위한 OS가 필요하며, 데이터베이스를 관리 하는 통합 시스템은 DBMS ( DataBase Management System)이라고 지칭한다.</li>
<li>데이터베이스 안에 있는 데이터들은 각 DBMS의 쿼리 언어를 통해 삭제, 수정, 조회 등을 수행할 수 있고 실시간 접근과 동시 공유가 가능하다.</li>
</ul>
<h4 id="-참고서적">## 참고서적</h4>
<p>비전공자를 위한 이해할 수 있는 IT 지식
혼자 공부하는 얄팍한 코딩 지식
면접을 위한 CS 전공지식 노트</p>
]]></description>
        </item>
    </channel>
</rss>