<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>bo-oram.log</title>
        <link>https://velog.io/</link>
        <description>매일 도망가는 나 잡아오기</description>
        <lastBuildDate>Mon, 25 Jul 2022 00:16:40 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>bo-oram.log</title>
            <url>https://velog.velcdn.com/images/bo-oram/profile/e3479b7e-4324-47d7-969d-5ec6b0ef0103/image.jpg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. bo-oram.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/bo-oram" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[항해99WIL - 11주차]]></title>
            <link>https://velog.io/@bo-oram/%ED%95%AD%ED%95%B499WIL-11%EC%A3%BC%EC%B0%A8</link>
            <guid>https://velog.io/@bo-oram/%ED%95%AD%ED%95%B499WIL-11%EC%A3%BC%EC%B0%A8</guid>
            <pubDate>Mon, 25 Jul 2022 00:16:40 GMT</pubDate>
            <description><![CDATA[<p>원하는 아웃풋 : <span style="font-weight:bold;">실시간 알림</span>
누군가 나를 포함하는 이벤트를 이르키면 나에게 누군가가 이벤트를 발생시켰다 라는 알림이 오게 하고 싶다
<img src="https://velog.velcdn.com/images/bo-oram/post/a33cf6de-8c00-45ba-ba5d-0c10fb15b0fe/image.png" alt="">
여기서 우리 팀은 socket io라는 라이브러리를 사용했다. 사실 구글링해보면 알림은 굳이 소켓을사용하지 않아도 구현가능하다 실시간인척 하도록 매 시간마다 계속 요청을 보내면 되니까..! 하지만 꼭 경험해보고 싶은 나의 작은 아기고양이 소켓(전혀 작지않음..)</p>
<p><span style="font-size:30px;">자!</span> 그럼 <span style="font-weight:bold;">소켓 통신</span>이 무엇인가
기본적으로 내가 알고있는 웹브라우저에서 이루어지고 있는 통신은 HTTP통신이다 HTTP통신은 HyperText Transfer Protocol의 약자로 html파일을 전송하는 프로토콜을 의미한다(만들어진 목적은 이러하나 현재는 json, image 파일 등 또한 전송한다)<span style="font-weight:bold;"><span style="color:tomato;">HTTP 통신</span>의 통신 방법은 단방향 통신이다 즉 <span style="color:tomato;">클라이언트의 요청이 있을 때</span> 서버는 응답한다</span> 하지만 내 경우 유저가 이벤트를 발생시킬 때까지 눈 똑띠 뜨고 기다렸다가 다른 유저에게 알려주기가 조금 귀찮다 위에서 말한것처럼 매초에 한번씩 요청을 해도 되지만 의미없는 요청이 너무 많이 일어날 것이다. <span style="font-weight:bold;color:tomato;">소켓통신은 양방향 통신이다</span><span style="font-weight:bold;"> 즉 클라이언트도 서버로 요청을 보낼 수 있고 서버도 클라이언트로 요청을 보낼 수 있다</span> 내 경우 누군가 눈 똑띠 뜨고 기다리고 있지 않아도 서버가 뭐 왔는데? 하고 보내준단 소리다 하지만 소켓 통신은 계속해서 Connection을 들고 있기 때문에 http통신에 비해 많은 리소스가 소모된다</p>
<p>정리</p>
<ol>
<li>http 통신은 단방향 통신이다 요청이 있을 때 응답이 이루어진다</li>
<li>socket 통신은 양방향 통신으로 C와 S모두 요청할 수 있다</li>
<li>데이터를 자주 주고받는 채팅, 스트리밍 등이 아닌경우 http통신이 더 유리하다</li>
</ol>
<hr>
<pre><code class="language-javascript">import { io } from &quot;socket.io-client&quot;;
///중략///

const [socket, setSocket] = useState(null);
//다른 컨포넌트에 프롭스로 주기 편하도록 변수에 할당했다 사실 리덕스에 넣어서 쓰고 싶었는데..잘 안됐다
//그래서 사용하려는 컴포넌트에 정말 노추천노추천인 프롭스에 프롭스로 전달했다
useEffect(() =&gt; {
  setSocket(io(&quot;서버주소&quot;)); //마운트 될 때 연결
  return disconnectSocket();//언마운트 될 때 연결끊기
}, []);

const disconnectSocket = () =&gt; {
    socket?.on(&quot;disconnect&quot;, () =&gt; {
      socket.connect();
    });
  };

///중략///

//socket.emit으로 이벤트를 요청하고 socket.on으로 받는다  
// 아래처러 사용했다
const notiList = async () =&gt; {
    await socket?.emit(&quot;getAlert&quot;, { receiverId: userInfo.userId });
    await socket?.on(&quot;getNotification&quot;, (data) =&gt; {
      console.log(data)//콘솔로 온 데이터 찍어보기
      setNotifications(data.findAlertDB); //이벤트
    });
  };
</code></pre>
<p style="font-size:12px;">사실 아직도 잘 모르겠다 어쩌다 이 블로그로 진입한 그대는 절대 이걸 참고하지 않길 바란다 열심히 공부해서 참고할만한 자료로 바꿔 나가겠다!!!</p>

<p>socket io client를 임포트 하고 io(&quot;서버주소&quot;)면 연결은 끝이다. console로 찍어보면 아래처럼 나오기도 하고 서버와 요청응답을 해보며 연결을 확인할 수 있다.
<img src="https://velog.velcdn.com/images/bo-oram/post/b2f561f5-4ee2-40e1-91ca-a95770be5767/image.png" alt="">
그리고 emit으로 요청하고 on으로 응답을 받는다 받은 응답으로 이벤트 처리를 해주면된다.
나는 실시간으로 온 데이터와 실시간으로 쌓인 데이터리스트를 받았다 실시간으로 온 데이터는 카운팅해서 숫자로 유저에게 너가 안본 알림이 몇개야!라고 알려주는 카운트용으로 사용했고 쌓인 데이터는 목록으로 보여주었다</p>
<p><img src="https://velog.velcdn.com/images/bo-oram/post/40894674-1229-4a87-8e3b-84c6d6e7233c/image.png" alt="">
여기의 느낌표 대신 숫자가 들어가는 것이다 종 아이콘을 누르면 목록이 보인다 실시간으로 받아 카운팅해서 숫자로 표시한다고 해도 새로고침하면 말짱도루묵이다.. 왜냐 클라이언트에서 다루는 데이터는 휘발휘발이기 때문 휘발... 그래서 로컬 스토리지를 이용했다 마운트됨과 동시에 로컬 스토리지에 0을 넣어두고 실시간으로 소켓통신이 올때마다 꺼내서 1을 더한 후 다시 넣었다 그리고 로컬 스토리지에 넣어둔 숫자를 종아이콘 앞에 넣어주었다. 종아이콘을 누르면 로컬 스토리지에 넣어둔 넘버를 다시 0으로 바꾼다 숫자가 0일경우 종앞에는 아무것도 표시 되지 않는다</p>
<pre><code class="language-javascript">///중략

//마운트됨과 동시에 로컬 스토리지에 0을 넣고
useEffect(() =&gt; {
    if (!localStorage.getItem(&quot;newNoti&quot;)) {
      localStorage.setItem(&quot;newNoti&quot;, 0);
    }
  }, []);

// 중략

// 소켓통신이 오면 꺼내서 1일 더하고 다시 넣었다 
// 주의할것은 로컬스토리지는 문자만 넣을 수 있다 배열등 다른 형태로 넣을거면 처리를 해주어야한다
// 나는 문자열이 된 &quot;0&quot;을 꺼내 넘버로 변환하고 1일 더했다
// 자바스크립트라 지가 알아서 문자여도 숫자 취급해줄지 알았는데 아니였음
 const addStore = async () =&gt; {
  await  socket?.on(&quot;AddStore&quot;, (data) =&gt; {
      if (data) {
        let myNewNoti = localStorage.getItem(&quot;newNoti&quot;);
        myNewNoti = Number(myNewNoti);
        localStorage.setItem(&quot;newNoti&quot;, myNewNoti + 1);        
        setNewStore((prev) =&gt; [...prev, data]);
      }
    })
  }

 //중략

 // 로컬스토리지에 저장한 숫자를 가져다 종앞에 표시해주기
 // 버튼을 누르면 다시 0으로 셋팅(이름이 동일하면 덮어써짐)
 let notiCount = localStorage.getItem(&#39;newNoti&#39;)

 const notiModalOpen = () =&gt; {
    setModal(true)
    localStorage.setItem(&quot;newNoti&quot;, 0);    
  }

 &lt;button onClick={notiModalOpen}&gt;
   &lt;img src={notice} alt=&quot;알림창&quot;&gt;&lt;/img&gt;
   { Number(notiCount) &gt; 0 &amp;&amp; &lt;NotiCount&gt;{notiCount}&lt;/NotiCount&gt; }
&lt;/button&gt;

</code></pre>
<p>이번 알림을 진행하면서 유즈이팩트의 디펜던시값이 얼마나 중요한지 알았다 내가 뭐만 하면 무한 렌더링이다... 좀 더 공부가 필요한... 넘무 재미써 진짜</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[항해99WIL - 9주차]]></title>
            <link>https://velog.io/@bo-oram/%ED%95%AD%ED%95%B499WIL-9%EC%A3%BC%EC%B0%A8</link>
            <guid>https://velog.io/@bo-oram/%ED%95%AD%ED%95%B499WIL-9%EC%A3%BC%EC%B0%A8</guid>
            <pubDate>Sun, 10 Jul 2022 23:54:58 GMT</pubDate>
            <description><![CDATA[<p>이번주는 회원가입을 작업했다 여어러번...작업했다 이번 프로젝트의 회원가입 구성은
4장의 인풋페이지와 1장의 가입완료 인포페이지로 구성되어있다
<img src="https://velog.velcdn.com/images/bo-oram/post/a0d40f41-52d7-42ab-88e3-1026be2e1e07/image.png" alt=""></p>
<p>매 프로젝트때마다 하는 회원가입인지라 쉽게하고 다음것을 진행하고 싶었지만
첫 번째 난관..저 <strong>4번 페이지의 캐릭터를 커스텀하는 부분</strong>..
처음 시도해보는 기능이라 감이 안왔다 디자이너(이 프로젝트에서는 기획자)가 원하는 부분은</p>
<ol>
<li>컬러부분의 <strong>특정 컬러를 클릭</strong>하면 클릭한 컬러에 관한 명도가 <strong>다른 컬러팔레트 생성</strong></li>
<li>컬러 <strong>팔레트중</strong> 특정 <strong>컬러를 선택</strong>하면 <strong>얼굴컬러 변경</strong></li>
<li><strong>눈모양 클릭</strong>시 클릭한 눈모양이 <strong>얼굴에 붙기</strong></li>
</ol>
<p>오래 고민한 것 치고 엄청 간단하게 해결했다</p>
<ol>
<li>얼굴 이미지를 SVG로 넣기</li>
<li>컬러 배열을 만들고 맵을 돌려 컬러팔레트를 만들기</li>
<li>특정 컬러를 클릭할 시 useState에 컬러값을 저장하기</li>
<li>useState에 담아놓은 컬러를 svg에 fill로 넣어주기<pre><code class="language-javascript">//svg는 path의 fill부분에 직접적으로 컬러를 넣지 않고 이렇게 문자열러 넣어둔 후 
//svg파일
&lt;path opacity=&quot;opacity&quot; d=&quot;M102.834 108(중략)&quot; fill=&quot;current&quot;/&gt;
</code></pre>
</li>
</ol>
<p>//svg파일을 컴포넌트를 임포트하듯 임포트해서 사용할 수 있다
//이미지를 사용하는 js파일
import { ReactComponent as Characterface } from &quot;../../img/characterface.svg&quot;;
<Characterface fill={hex} /></p>
<pre><code>눈과 컬러는 가지수가 많기 때문에 이를 작업하는 컴포넌트에 넣기는 좀 더러웠다
그래서 따로 리소스.js를 만들고 거기에 아래처럼 할당한 후 import해서 사용했다
```javascript
//FaceResource.js
import eyeType1 from &quot;../../img/eyes/test1.svg&quot;;
import eyeType2 from &quot;../../img/eyes/test2.svg&quot;;
import eyeType3 from &quot;../../img/eyes/test3.svg&quot;;
import eyeType4 from &quot;../../img/eyes/test4.svg&quot;;
import eyeType5 from &quot;../../img/eyes/test5.svg&quot;;
import eyeType6 from &quot;../../img/eyes/test6.svg&quot;;
import eyeType7 from &quot;../../img/eyes/test7.svg&quot;;
import eyeType8 from &quot;../../img/eyes/test8.svg&quot;;

export const eyeList = [
  eyeType1,
  eyeType2,
  eyeType3,
  eyeType4,
  eyeType5,
  eyeType6,
  eyeType7,
  eyeType8,
];

export const colorTest = [
  [&quot;#FFF1DD&quot;, &quot;#FFE4BB&quot;, &quot;#FFD699&quot;, &quot;#FFC977&quot;, &quot;#FFBB55&quot;],
  [&quot;#FFE3D7&quot;, &quot;#FFC7AF&quot;, &quot;#FFAB87&quot;, &quot;#FF8855&quot;, &quot;#FF7337&quot;],
  [&quot;#D3F4F4&quot;, &quot;#B0EBEB&quot;, &quot;#7FDFDF&quot;, &quot;#56D4D4&quot;, &quot;#23C7C7&quot;],
  [&quot;#E2DAFF&quot;, &quot;#CCBFFF&quot;, &quot;#B29FFF&quot;, &quot;#997FFF&quot;, &quot;#7F5FFF&quot;],
  [&quot;#CFCFCF&quot;, &quot;#B3B3B3&quot;, &quot;#888888&quot;, &quot;#626262&quot;, &quot;#404040&quot;],
];

//FaceColor.js
import { colorTest } from &quot;./FaceResource&quot;;
</code></pre><p>일단 이렇게 어찌어찌 회원가입에 필요한 모든 컴포넌트를 만들었다
처음에는 signup.js에 화면에 필요한 모든 컴포넌트를 몰아 넣고 변수에 0을 할당해서
다음이나 완료 버튼을 누르면 +1이되고 뒤로가는 버튼을 누르면 -1을 해줘서
화면을 변하게 했다 하지만 브라우저에 있는 백 버튼(&lt;-)을 누르면 역시나 회원가입의 어디에 있던
회원가입창을 완전히 벗어나버린다... 그래서 그냥 각각 페이지로 하여 아래처럼 라우팅 해줬다</p>
<pre><code class="language-javascript">&lt;Route path=&quot;/signup&quot; element={&lt;Singup /&gt;}&gt;
    &lt;Route path=&quot;agreement&quot; element={&lt;Agreement /&gt;} /&gt;
    &lt;Route path=&quot;essential&quot; element={&lt;Essential /&gt;} /&gt;
    &lt;Route path=&quot;basicInfo&quot; element={&lt;BasicInfo /&gt;} /&gt;
    &lt;Route path=&quot;faceCustom&quot; element={&lt;FaceCustom /&gt;} /&gt;
    &lt;Route path=&quot;completion&quot; element={&lt;Completion /&gt;} /&gt;
&lt;/Route&gt;</code></pre>
<p>다 되었나?!! 한 순간 문제....! 사실 이글은 이것 때문에 쓰는거다
<span style="color:tomato;">데이터를 어떻게 모아서 서버에 회원가입 요청할건데?</span> ㅇㅇ리덕스
<span style="color:tomato;">아이디 입력하고 다음페이지에서 새로고침하면 리덕스 넣어둔 아이디데이터 사라지는데?</span> ...?</p>
<p>였다...ㅋ 지금의 보람이는 사라지는건 막을 수 없다 다만 &#39;니가 지금 새로고침해서 이전에 입력한거 날라감 다시 적으센&#39;을 유저에게 알려준후 사라진 데이터를 다시 입력하도록 페이지 전환을 해줘야한다</p>
<p>react-beforeunload를 통해 유저에게 새로고침을 경고했다
<img src="https://velog.velcdn.com/images/bo-oram/post/e6460497-a553-42f0-8fcd-3a53d309596b/image.png" alt=""></p>
<pre><code class="language-javascript">import { useBeforeunload } from &quot;react-beforeunload&quot;;
useBeforeunload((event) =&gt; event.preventDefault()); </code></pre>
<p>그리고 조건문을 걸어 리덕스에 저장된 데이터가 없다면 각입력페이지로 돌아가도록 했다</p>
<pre><code class="language-javascript">useEffect(()=&gt;{    
    pageChange()
  },[])

//아이디와 비밀번호가 없다면 해당 페이지로 이동
  const pageChange = () =&gt;{
    if(location.pathname === &quot;/signup/agreement&quot;){
        return null
    }else if(!userSignupData.id || !userSignupData.password ){
      return navigate(&#39;/signup/essential&#39;)
    }else if(!userSignupData.email || !userSignupData.name || !userSignupData.birthDay){
        return navigate(&#39;/signup/basicInfo&#39;)
    }else if(!userSignupData.nickname || !userSignupData.eyes || !userSignupData.faceColor){
        return navigate(&#39;/signup/faceCustom&#39;)
    }
  }</code></pre>
<p>휴... 이렇게 완성하였으나 당장 눈에 보이는 불편함이있다(달력에 날짜 선택부분)...하지만 다른 작업을 먼저하고 나서 다시 고쳐야지..</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[2022-07-05]]></title>
            <link>https://velog.io/@bo-oram/20220705</link>
            <guid>https://velog.io/@bo-oram/20220705</guid>
            <pubDate>Mon, 04 Jul 2022 16:32:34 GMT</pubDate>
            <description><![CDATA[<p>거의 두달만에 쓰는.... til 앞으론 좀 더 자주 써보자 나 자신아...ㅂㄷㅂㄷ</p>
<p>실전프로젝트 시작하고 열흘 쫌 더 지난 것 같다 하지만 우린 기획에 멈춰 아무것도 하지 못했고 결국... 디자이너님과 바이바이를 했다 ㄸㄹㄹ</p>
<p>우리 팀원들 중 디자인 경험이 있는건 나뿐이어서 어쩔 수 없이 내가 진행할 것 같다 정말정말 개발 공부에 더 많은 삽질을 하고 싶었는데 만약 디자인에 신경을 쓰게된다면 그 시간이 조금 아쉬울 것 같지만 완성을 못하는 것보단... 나으니까:(</p>
<p>오늘은 전체적인 기획 흐름을 다시 짜고 다시.. 처음부터 작업을 시작했다
일단 당장 내게 할당된 페이지는 게시물 작성 페이지 인데 대략 나온 뼈대를 보면 아래와 같다
<img src="https://velog.velcdn.com/images/bo-oram/post/1ac2b576-75fa-4df6-9ffd-d628bf113d43/image.png" alt="">
글로 설명하자면,
<strong>두 버전으로 게시물을 작성할 수 있는데 하나는 일반적인 글로 또 하나는 음성으로 작성한다</strong>
<del>나중에 노래 이어부르기도 할껀데 너무 재밌겠당</del></p>
<p>나는 mongodb를 사용할지 알았는데 이미지를 aws s3에 배포한다고했다 아래 코드는 aws에 자알 나와 있고 사전에 <strong>s3에서 설정</strong>해야하는데 그거슨...!
<a href="https://merrily-code.tistory.com/142">요기를 참고하자 정말 포스팅을 순서대로 잘 해주셨다</a></p>
<hr>
<pre><code class="language-javascript">import AWS from &#39;aws-sdk&#39;

// 만약 buffer오류가 난다면
window.Buffer = window.Buffer || require(&quot;buffer&quot;).Buffer;

  const S3_BUCKET = &#39;finalproject99&#39;
  const REGION = &#39;ap-northeast-2&#39;

  AWS.config.update({
    accessKeyId: &#39;엑세스 키&#39;,
    secretAccessKey: &#39;보안 엑세스 키&#39;
  })

  const myBucket = new AWS.S3({
    params: { Bucket: S3_BUCKET},
    region: REGION
  })

    const [progress, setProgress] = useState(0);
    const [selectedFile, setSelectedFile] = useState(null);

    const handleFileInput = (e) =&gt; {
      setSelectedFile(e.target.files[0]);
    }

    const uploadFile = (file) =&gt; {
      const params = {
        ACL: &#39;private&#39;, // 이부분에서 public-read로 해서 오류가 났었다
        Body: file,
        Bucket: S3_BUCKET,
        Key: file.name
      };

      myBucket.putObject(params)
      .on(&#39;httpUploadProgress&#39;,(evt) =&gt; {
        setProgress(Math.round((evt.loaded / evt.total) * 100))
      })
      .send((err) =&gt; {
        if(err) console.log(err)
      })
    }
  //</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[항해99WIL - 8주차]]></title>
            <link>https://velog.io/@bo-oram/%ED%95%AD%ED%95%B499WIL-8%EC%A3%BC%EC%B0%A8</link>
            <guid>https://velog.io/@bo-oram/%ED%95%AD%ED%95%B499WIL-8%EC%A3%BC%EC%B0%A8</guid>
            <pubDate>Mon, 04 Jul 2022 02:03:34 GMT</pubDate>
            <description><![CDATA[<h4 id="실전-프로젝트에-들어갔는데-너무-이상과-다르다-기획도-안나오고-배정된-디자이너님은-우리가-완성할-수-있는-내용과-그-기간을-고려하지-않고-너무-크고-디테일한-것-을-원하신다-사실-나는-내-포폴에-넣을-작품이기에-당연히-어떤-부분이든-고퀄로-나와주면-좋다-하지만-기간내에-완성이-된다는-전제하다-제발-조금이라도-뭐라도-주세요-디자이너님-작업을-할-수-있도록-뭐라도-뼈대라도-좀-주세요">실전 프로젝트에 들어갔는데 너무 이상과 다르다... 기획도 안나오고 배정된 디자이너님은 우리가 완성할 수 있는 내용과 그 기간을 고려하지 않고 너무 크고 디테일한 것 을 원하신다 사실 나는 내 포폴에 넣을 작품이기에 당연히 어떤 부분이든 고퀄로 나와주면 좋다 하지만!!!! 기간내에 완성이 된다는 전제하다... 제발 조금이라도 뭐라도 주세요 디자이너님.... 작업을 할 수 있도록 뭐라도.. 뼈대라도... 좀... 주세요</h4>
<hr>
<p>그냥 오늘 메모...</p>
<div>
  <span style="color:gray;">1.</span>
  <span style="color:tomato; font-size:20px;">?. (옵셔널 체이닝 연산자)</span>
  <p>
    object에서 property를 가져올 때 해당값이 있는지 없는지 모를때가 있다 그럴때 나는 if문이나 논리연산자를 사용해서 예외 처리를 해왔다
  </p>  
</div>

<pre><code class="language-javascript">//기존 내가 하던 예외 처리
let obj = undefined;
let result = obj &amp;&amp; obj.data; // &amp;&amp;앞이 참이면 뒤의 내용이 실행된다
console.log(result);
</code></pre>
<p>위 코드를 옵셔널 체이닝 연산자를 이용해 바꾸어 보면</p>
<pre><code class="language-javascript">let obj = undefined;
console.log(obj?.data);</code></pre>
<p>obj가 undefined이지만 에러를 내지 않고 undefined를 반환해준다</p>
<p>사실 기존에 쓰던 방법이 어렵거나 불편하진 않다(아직 경험부족으로 그럴지도 모르겠다)하지만 옵셔널 체이닝 연산자를 알게되었으니 요곳도 종종 써보면 좋을것같다</p>
<hr>
<p><span style="color:gray;">2.</span> <span style="color:tomato; font-size:20px;">FormData 객체</span></p>
<p>백 엔드 개발자분께서 "폼데이터로 요청해주세요"라고 요청해주셨는데 잉?.. 그냥 모가다르지 싶었다.. 그리고 나의 삽질이 시작되었다...(제발 어믄거 찾지말고 MDN이나 잘 읽어보자 제발)</p>
<p>FormData는 form data를 ajax로 전송 가능하게 해주는 객체이다. <span style="color:#9D43D9;">이미지를 ajax로 업로드할 때 필요하다고 한다.</span> 아래와 같이 사용한다</p>

<pre><code class="language-javascript">let formData = new FormData();
formData.append(&#39;key&#39;,&#39;value&#39;)
formData.append(&#39;item&#39;,&#39;hi&#39;) // &lt;input name=&quot;item&quot; value=&quot;hi&quot;&gt; 와 같다.</code></pre>
<p>*값은 "문자열"로 자동 변환되는 점 참고하자 </p>

<p>
  여기 까지는 막 검색해도 다 나와서 룰루랄라 요청하기직전에 확인하자 하고 콘솔로 찍어보는 순간 formData{}.....? 난 으마무시하게 많은 친구들을 .append했는데 아무것도 나오지 않는다 <a href="https://developer.mozilla.org/ko/docs/Web/API/FormData" target="_blank">MDN만 잘 읽었어도</a> 당황하지 않았을텐데... 일단 <span style="color:#9D43D9;">결론은 FormData는 console.log()로 찍으면 확인할 수 없고 아래와 같이 formData.entries()를 이용해 확인할 수 있다.</span>
</p>

<pre><code class="language-javascript">// Create a test FormData object
var formData = new FormData();
formData.append(&#39;key1&#39;, &#39;value1&#39;);
formData.append(&#39;key2&#39;, &#39;value2&#39;);

// Display the key/value pairs
for(var pair of formData.entries()) {
   console.log(pair[0]+ &#39;, &#39;+ pair[1]); 
}
// key1, value1
// key2, value2
// 코드 출처 : https://velog.io/@ash3767/react-formData</code></pre>
<p>왜? 콘솔로그에 출력되지 않았을까
FormData 객체는 단순 객체가 아닌 XMLHttpRequest 전송을 위해 설계된 특수한 객체라고 한다.
문자열화할 수 없기 때문에 console.log에 출력되지 않음.. </p>
<hr>
]]></description>
        </item>
        <item>
            <title><![CDATA[항해99WIL - 7주차]]></title>
            <link>https://velog.io/@bo-oram/%ED%95%AD%ED%95%B499WIL-7%EC%A3%BC%EC%B0%A8</link>
            <guid>https://velog.io/@bo-oram/%ED%95%AD%ED%95%B499WIL-7%EC%A3%BC%EC%B0%A8</guid>
            <pubDate>Sun, 26 Jun 2022 11:49:15 GMT</pubDate>
            <description><![CDATA[<p>이번주는 번개장터를 클론코딩했다 많이 아쉬웠던 부분은 너무 보이는 부분에 신경을 써서 해보고자 했던 기능들을 해보지 못했던 것이다... :{</p>
<p>이번주차가 아니더라도 늘.. 계속적으로 보이는 문제가 있다
내가 변경 또는 업로드한 데이터가 화면에 반영되지 않는것들 예를 들면 
로그인을 하였는데도 로그인 버튼이 계속 남아있고 리렌더링을 해야 로그아웃버튼이 활성화 되는 부분 하지만 사실 useState로 상태변경을 잘 해주었더니 금새 화면이 잘 그려졌다.. 왜 지금까지 왜 뭐가 문제여서 잘 안된거지.. 다음에 이문제가 생기면 꼭!!!!! 메모 해둘것이다</p>
<p>그리고 지금 생각나는 이슈(?)중 하나 모달창.....
모달을 여는 함수는 Home 컨포넌트에 있는데 모달을 닫을 때는 모달컴포넌트에서 닫어야하는 점...</p>
<p><img src="https://velog.velcdn.com/images/bo-oram/post/b1e58311-6f35-46c7-9337-2846131361a8/image.png" alt=""></p>
<p>Home컴포넌트에서 아래와 같은 로직을 작성했다(거의 비슷...하다)</p>
<blockquote>
<pre><code class="language-javascript">const [ modalPosition, setModalPosition ] = useState(false)
const modalOn = () =&gt; {
    setModalPosition(ture)
}
const modalOff = () =&gt; {
  setModalPosition(false)
}
//중략</code></pre>
</blockquote>
<p onClick={modalOn}>로그인</p>
//중략
{ modalPosition ? <Modal /> : null}
```

<p>특정 버튼을 누르면 모달이 활성화 되고 모달 내에서 배경이나 엑스버튼을 누르면 modalOff함수 호출해 모달이 닫히길 바랬는데... 저 함수를 어떻게 모달에서 호출하지.... 란 의문</p>
<p>일단 해결은 함수도!!!! 프롭스로 넘길 수 있다!!!!!!!란 것이다 이렇게 간단한걸 하루죙일 생각했다는 거... 으악 즉 요로케</p>
<blockquote>
<pre><code class="language-javascript">{ modalPosition ? &lt;Modal modalOff={modalOff} /&gt; : null}</code></pre>
</blockquote>
<p>```</p>
<p>이게 맞는 방법인지는 모르나 일단 해결했다... 휴
<img src="https://velog.velcdn.com/images/bo-oram/post/7f6a7efb-9d1e-40b5-a01d-17f0735d8ac5/image.png" alt=""></p>
<p>내일 부터는 내가 꼭!!! 하루에 하나씩 기록한다!!!!!!!!!!!!!!악!!!!!!!!!!! 기록이 안되어있으니까 뭐 찾으면 계속 똑같은 루틴을 또 찾고 또 찾고 으이그 </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[실전 프로젝트 1일차]]></title>
            <link>https://velog.io/@bo-oram/ssss</link>
            <guid>https://velog.io/@bo-oram/ssss</guid>
            <pubDate>Sat, 25 Jun 2022 14:47:48 GMT</pubDate>
            <description><![CDATA[<p>오늘부터 실전 프로젝트가 시작되었다</p>
<p>우리조는 &quot;길고양이&quot;를 아이템(?)으로 하는 프로젝트인데 좀 더 세세하게 페이지별 이야기 하자면</p>
<div>
  <ol>
    <li style="font-weight:bold; margin:5px 0;">
      로그인/회원가입
    </li>
    <li style="font-weight:bold; margin:5px 0;">
      메인페이지<br />
      <span style=" font-weight:normal; background-color:#ffcbd9; margin:0;">우리 동네 길고양이 목록, 지역별 고양이 호감도</span>
    </li>
    <li style="font-weight:bold;  margin:5px 0;">
      상세 고양이 페이지<br />
      <span style="font-weight:normal; background-color:#ffcbd9; margin:0;">유저가 등록한 고양이의 정보들 (사진, 상태, 종류, 추정 나이, 중성화여부)</span>
    </li>
    <li style="font-weight:bold;  margin:5px 0;">
      모임 커뮤니티<br />
      <span style="font-weight:normal; background-color:#ffcbd9; margin:0;">같이 밥주러가는 등의 조인 커뮤니티, 질문 방이 될 수도</span>
    </li>
    <li style="font-weight:bold;  margin:5px 0;">
      채팅방<br />
      <span style="font-weight:normal; background-color:#ffcbd9; margin:0;">1:1채팅</span>
    </li>
    <li style="font-weight:bold;  margin:5px 0;">
      마이페이지<br />
      <span style="font-weight:normal; background-color:#ffcbd9; margin:0;">유저 정보, 관리중인 길고양이, 지역저장, 회원탈퇴</span>
    </li>    
  </ol>
</div>


<p>위 와 같다 사실 확정된 내용은 아니다..
일단 위처럼 구성하기로 하고 좀 더 수정하기로 했다.</p>
<hr>
<p>작업을 같이 하다보면 여러가지 트러블이 생기기 마련인데 그래서 우리는 룰을 정했다
<strong>&quot;화가 나면 바로 말하지 않기 글로 써보고 스스로 읽어보고 이야기하기&quot;</strong>
혹여나 서로 후회가 될 또는 상처가 될 상황을 최대한 예방(?)하기 위한 룰이다
그리고 전에 들었던 트러블 내용 중 남이 말도없이 내 코드를 만져서 맘이 상했었다고 어떤 다른 조원에게 들은 적이 있기에 그 내용도 추가했다 <strong>&quot;남 코드 만지지말기 혹시 꼭 만져야 한다면 이야기 해주기&quot;</strong>  </p>
<hr>
<p>일단 요로케... 오늘 회의는 끝이났다 팀장님이 하고자 하는 방향이 명확해서 우리조 회의는 그렇게 오래 걸리지 않았다 후... 잘 할 수 있을지 모르겠지만 열심히 해볼거다!! 소켓과.. 무한스크롤 이번엔 꼬옥!!!!! 해본다!!!!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[항해99WIL - 6주차]]></title>
            <link>https://velog.io/@bo-oram/%ED%95%AD%ED%95%B499WIL-6%EC%A3%BC%EC%B0%A8</link>
            <guid>https://velog.io/@bo-oram/%ED%95%AD%ED%95%B499WIL-6%EC%A3%BC%EC%B0%A8</guid>
            <pubDate>Sun, 19 Jun 2022 13:33:43 GMT</pubDate>
            <description><![CDATA[<p>오늘의 키워드는 협업이다. 내 첫 경험이었던 한 주이다.</p>
<p>난 웹디자이너이자 어느정도의 퍼블리셔일을 3~4년 정도 해왔다 조그만 회사였기 때문에 기획서등의 계획에 관한 절차는 늘 없었고 위에서 &quot;어린이날이니까 어린이날 할인 좀 하자&quot; 하시면 그냥 남들이 만든 작년 어린이날 이미지들 광고 카피들을 그대로 가져와 뚝딱뚝딱 만들어 올렸었다 즉 어떤 지시가 떨어지면 그 이후 실제 업무의 시작부터 그 끝까지 내 멋대로 할 수 있었던것이다</p>
<p>이번주는 백엔드와 프론트엔드가 만나서 프로젝트하나를 완성한다. 우리 조는 단순 포스팅 기능의 앱이며, 포스팅시 9가지의 표정중 하나를 선택해서 오늘의 기분을 나타낼 수 있었고 그것들(표정들)을 날짜별로 모아둔 마이페이지로 특정 날짜의 나의 기분을 알 수 있는 프로젝트이다</p>
<p>그렇기때문에 처음에는 재미있을거란 생각으로 한 주를 시작했지만 사실상 불편한것들이 많았다
그리고 나를 답답해 하는 것 같은 상대방의 부분적인 어투도 상당히 나를 얹잖게했다.</p>
<p>아마 서로가 아마추어이기 때문에 어떤식으로 말해야 내가 원하는 의미가 전달 될 지 몰랐었던거 같다 사실 협업이라고 하기엔 조금 어울리지 않을 수 도 있는 것 같다 이게 맞는지 모르겠지만 우리는 어느정도의 약속(API명세서)을 하고 각자 약속에 맞게 일한 뒤 그냥 붙여서 제출한게 다이기 때문이다. 조금 키워드에서 벗어난 부분이 있지만 일단 나의 첫 협업은 그냥 &#39;불편한 사회생활&#39; 어차피 해야한다면 못 할 것은 없는 그 정도였다  </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[항해99WIL - 5주차]]></title>
            <link>https://velog.io/@bo-oram/%ED%95%AD%ED%95%B499WIL-5%EC%A3%BC%EC%B0%A8</link>
            <guid>https://velog.io/@bo-oram/%ED%95%AD%ED%95%B499WIL-5%EC%A3%BC%EC%B0%A8</guid>
            <pubDate>Sun, 12 Jun 2022 11:52:08 GMT</pubDate>
            <description><![CDATA[<h2 id="axios">Axios</h2>
<h4 id="axios는-브라우저-nodejs를-위한-promise-api를-활용하는-http-비동기-통신-라이브러리이며-백엔드와-크론트엔드간-통신을-쉽게하기-위해-ajax와-더불어-사용한다">Axios는 브라우저, Node.js를 위한 Promise API를 활용하는 HTTP 비동기 통신 라이브러리이며, 백엔드와 크론트엔드간 통신을 쉽게하기 위해 Ajax와 더불어 사용한다.</h4>
<p style="margin:0;">Axios의 특징</p>
<li>요청 객체에 url이 있다.</li>
<li>써드파티 라이브러리로 설치가 필요하다.</li>
<li>data는 object를 포함한다.</li>
<li>status가 200이고 statusText가 ‘OK’이면 성공이다.</li>
<li>자동으로 JSON데이터 형식으로 변환된다.</li>
<li>요청을 취소할 수 있고 타임아웃을 걸 수 있다.</li>
<li>HTTP 요청을 가로챌수 있다.</li>
<li>download진행에 대해 기본적인 지원을 한다.</li>

<hr>
<p>기본적인 사용방법은 공식문서에도 잘 나와있지만 나는 아래 포스팅이 그냥 눈에 더
잘 들어왔다 :&gt;
<a href="https://basemenks.tistory.com/243">axios 에서 Get과 Post 란?</a></p>
<hr>
<p>현재 진행중인 미니프로젝트에서는 아래와 같이 사용중이다
<img src="https://velog.velcdn.com/images/bo-oram/post/4ac4bfac-f5dc-4faa-bbc9-9ba47f2eb63c/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[가상 운영체제와 가상 머신 / 운영체제가 일하는 법]]></title>
            <link>https://velog.io/@bo-oram/%EA%B0%80%EC%83%81-%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C%EC%99%80-%EA%B0%80%EC%83%81-%EB%A8%B8%EC%8B%A0-%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C%EA%B0%80-%EC%9D%BC%ED%95%98%EB%8A%94-%EB%B2%95</link>
            <guid>https://velog.io/@bo-oram/%EA%B0%80%EC%83%81-%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C%EC%99%80-%EA%B0%80%EC%83%81-%EB%A8%B8%EC%8B%A0-%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C%EA%B0%80-%EC%9D%BC%ED%95%98%EB%8A%94-%EB%B2%95</guid>
            <pubDate>Wed, 08 Jun 2022 01:44:12 GMT</pubDate>
            <description><![CDATA[<p>초창기(~1980년대)의 운영체제는 스와핑도 제한적이었고, 할당메모리도 100kb미만으로
지금의 프로그램당 메모리 단위가 mb, gb인것에 비하면 현저히 작았다.
(지금은 초창기 운영체제에 비해 다양하고 복잡한 일을 처리하기 때문이다)</p>
<p>초창기 운영체제인 유닉스 운영체제 6판과 오늘 리눅스
<strong>유닉스 운영체제 6판: 작성자 2명, C와 어셈블리언어 9000행으로 구성
현재의 리눅스: 수 천명의 작업자와 1천만 행이 훨씬 넘는 구성</strong></p>
<p>운영체제는 단지 프로그램이기 때문에 직접 작성하는 것이 가능하다. 리눅스도 대학생이었던
리누스 토르발스에 의해 탄생했다.</p>
<hr>
<p>가상운영체제 :
<strong>다른 운영체제 관리하에 가상으로 운영체제를 실행할 수 있다</strong>
VirtualBox 및 VMware등의 가상운영체제 프로그램은 거의 모든 운영체제를 지원한다
**법적으로는 가상 인스턴스 사본의 총 개수를 제한하고 있다</p>
<p>호스트 운영체제 입장에서는 게스트 운영 체제도 보통의 어플리케이션이다</p>
<p><img src="https://velog.velcdn.com/images/bo-oram/post/4516ee19-9123-476c-be0d-538edbe16bb2/image.png" alt=""></p>
<p>가상 머신(<strong>컴퓨터인척하는 프로그램</strong>) :
물리적 컴퓨터에서 실행되지만 물리적 컴퓨터처럼 작동한다.</p>
<p>가성 머신 내의 소프트웨어는 호스트 컴퓨터를 변조할 수 없기 때문에 <u>바이러스에 감염된 데이터에
액세스하거나 운영체제를 테스트 하는 등 호스트 환경에서 수행하기
위험한 작업을 수행하기 위해서 필요</u>하다. 그외 서버 가상화 등에서도 사용되는데 <strong>클라우드 컴퓨팅</strong>으로 가상 머신내 서버 가상화의 예를 들 수 있다
대표적인 클라우드 컴퓨팅 제공업체는 aws이고 영업이익의 절반을 차지한다고 한다
많은회사가 규모의 경제 작업량 변화에 대한 높은 적응성, 내부 직원의 필요성 감소덕분에 자체 서버보다 가상 서버가 더 효율적이라고 여기고 있다</p>
<hr>
<p><strong>부팅</strong>: 전원이 공급된 순간 각 장치를 검사하고 초기화하는 과정을 거쳐 컴퓨터가 작업할 수 있는 환경이 될 때 까지의 과정을 부팅이라고 한다</p>
<div style="border:1px solid; padding:10px;">
1.컴퓨터에 부착되어있는 모든 장치에게 신호를 보내서 정상여부를 확인</br>
2.POST(power on self test)를 수행함 -> 시스템버스, 램이나 키보드, 드라이브등을 검사</br>
3.부팅에 필요한 모든파일들을 주기억장치로 읽어 들임</br>
4.로그온 화면을 표시함</div>

<p><strong>운영체제는 실행되면 사이클을 실행</strong>하는데 책(1일 1로그 100일완성
it 지식 - 2부 35쳅터)에서 말한 간단한 사이클은 인출사이클부분을 이야기하는것같다
<img src="https://velog.velcdn.com/images/bo-oram/post/dba83310-2eaf-450f-8e4b-35ba60d7515e/image.png" alt=""></p>
<p><strong>위의 과정으로 필요에 따라 각 프로세서에 차례대로 관심을 갖고 처리</strong>하며, 프로세서간 초점을 전환한다. 운영체제는 어떤 이벤트가 발생하면 해당 이벤트를 처리해야하는 애플리케이션에 전달한다.
그리고 애플리케이션이 일할 기회를 얻어주기도 한다 예를들어 파일을 종료할때 사용자에게
&#39;파일을 저장하시겠습니까&#39;라고 물어 남은일을 정리할 기회를 주는 것을 예로 들수있다.</p>
<hr>
<p>CPU의 두가지 모드 : 
운영체제를 보호하기 위해 CPU에는** 유저모드와 커널모드**의 두가지 모드가 있다
악의적 프로그램들의 직접적 접근을 막기위함으로 만약 어떤 나쁜 프로그램이 <u>운영체제를 거치지 않고 하드웨어를 직접적으로 실행하게 한다면 CPU는 이를 판단해 실행하지 않는다.</u></p>
<p>위의 두 모드를 간단히 말하면
<strong>유저 모드: 어플리케이션이 수행되는 모드(모니터 모드라고도 이야기한다)
커널 모드: 이터럽트 또는 트랩이 발생해서 운영체제가 호출돼 수행되는 모드</strong> 
(트랩이 걸리는 경우:  사용자 모드에서 특권명령 실행 시도, 프로그램이 사용자 영역의 메모리
공간이 아닌 곳의 접근을 시도할 때)</p>
<p>이 때 <span style="color:tomato;">프로그램이 필요한 자료를 찾기위해 직접 엑세스 하는것이 아니라 운영체제에 요청을 하는
인터페이스를 시스템콜</span> 이라고 합니다</p>
<p><a href="https://luckyyowu.tistory.com/133">운영체제 - 시스템 콜</a></p>
<hr>
<p>디바이스 드라이버 :
책(1일 1로그 100일완성 it 지식 - 2부 35쳅터)에서는 디바이스 드라이버를 &quot;특정 종류의 하드웨어 장치 간에 가교역할을 하는 코드&quot; 라고 정의 했다</p>
<p>이를 쉽게 풀면 <strong>우리가 쓰는 키보드, 마우스 등 입출력 장치과 운영체제가 서로 소통할 수 있게 통역하는 역할을 하는 코드</strong> 정도로 이해할 수 잇을것이다.</p>
<p>어떠한 새로운 장치를 연결해 사용할 때 컴퓨터는 이게 마우스인지 키보드인지 어떻게 작동하는 장치인지 알 수 없다 그래서 컴퓨터가 이 장치를 동작시킬 때 어떻게 동작되어야 하는지에 대한 프로그램을 따로 설치하게 되는데 이 것이 디바이스 드라이버이다.</p>
<p>운영체제가 추상적이거나 이상화된 장치에 포괄적인 요청을하고, 드라이버가 특정 장치에 맞게 요청을 구체적으로 구현한다.</p>
<p>*범용 운영체제에는 많은 디바이스 드라이버가 있고 예를 들어 윈도우는 소비자들이 사용할만한 장치의 드라이버를 이미 설치한 상태로 출하한다</p>
<hr>
<p>기술의 발달덕분에 <strong>장치들은 전반적으로 성능 좋은 프로세서 용량이 큰 메모리 다양한 주변장치 등
범용 컴퓨터와 비슷한 모습</strong>을 띠고 있다.</p>
<p>이런 추세가 계속되면서 <u>별도의 운영체제를 만들기보다는
범용 운영체제를 사용하는 방식이 더 타당</u>하다라고 저자는 말하고 있다</p>
<p>단점은 PL같은 라이선스에 따라 결과물 코드 일부를 공해 해야 될 수도 있다는 점인데
킨들과 티보의 사례로 적절히 대처할 수 있을 것</p>
<p>** TiVo의 경우: GPL의 요구사항을 준수해 다른 사람이 수정할 수 있도록 소스 코드를 공개하였지만 수정된 소프트웨어는 TiVo의 하드웨어에서 실행되지 않습니다</p>
<p>** 킨들의 영우: <a href="https://www.amazon.com/gp/help/customer/display.html?nodeId=200203720">킨들의 코드공유</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[항해99WIL - 4주차]]></title>
            <link>https://velog.io/@bo-oram/%ED%95%AD%ED%95%B499WIL-4%EC%A3%BC%EC%B0%A8</link>
            <guid>https://velog.io/@bo-oram/%ED%95%AD%ED%95%B499WIL-4%EC%A3%BC%EC%B0%A8</guid>
            <pubDate>Sun, 05 Jun 2022 14:53:13 GMT</pubDate>
            <description><![CDATA[<p>리액트 <strong>컴포넌트는 리액트</strong>로 만들어진 앱을 이루는 최소한의 단위를 말하며,
MVC의 뷰를 독립적으로 구성하여 재사용을 할 수 있고 이를 통해 새로운 컴포넌트를
쉽게 만들 수 있다는 장점을 가지고 있다</p>
<h4 id="컴포넌트는-함수형과-클래스형-이-두가지-방법으로-선언할-수-있다">컴포넌트는 함수형과 클래스형, 이 두가지 방법으로 선언할 수 있다</h4>
<p>과거에는 클래스형을 많이 사용했지만 19년도 이후 함수형 컴포넌트에
리액트 훅(hook)이 도입되며 현재는 함수형이 더 많이 사랑받고 있다.</p>
<p>아래는 각각 함수형과 클래스형 컴포넌트를 선언한 것이다</p>
<pre><code class="language-javascript">// 함수형 컴포넌트
import React from &#39;react&#39;;

function App() {
  const name = &quot;너무 재미있는 리액뚜&quot;;
  return &lt;div&gt;{name}&lt;/div&gt;;
}
export default App;</code></pre>
<pre><code class="language-javascript">// 클래스형 컴포넌트
import React,{Component} from &#39;react&#39;;

class App extends Component {
  render() {
    const name = &quot;너무 재있는 리액뚜&quot;;
    return &lt;div&gt;{name}&lt;/div&gt;;
  }
}
export default App;</code></pre>
<p>두 컴포넌트의 역할을 동일하나 <span style="background-color:tomato; color:#fff;padding:5px;">클래스형의 경우 state, 라이프 사이클 기능을 사용할 수 있으며,
render함수를 통해 jsx를 반환해야한다
반면 함수형은 선언하기가 상대적으로 편하다 기존 함수형 컴포넌트는 state와 라이프사이클api를
사용하지 못한다는 단점이 있었으나 리액트 훅이 도입되며 해결되었다</p>
<div style="line-height:1.8;">함수형 컴포넌트 안에서도 함수선언문과 함수표현식으로 나뉘는데 첫 번째는 this가 가르키는
대상의 차이이다 함수 선언문은 자신이 종속된 객체를 가르키며 표현식은 자신이 종속된
인스턴스를 가르킨다 또 함수 선언식은 호이스팅의 영향을 받지만 표현식은 받지 않는 등
둘은 차이가 있다 장단점이 있으나 느끼는 것은 사바사이기 때문에
자기가 편한 방식을 사용하며 차이를 잘 인지하고 일관된 개발이 필요할 것 같다 </div>


<hr>
<p> 위에서 언급한대로 <strong>기존 함수형 컴포넌트는 State와 라이프사이클API를 사용하지 못한다는
단점</strong>이 있었다 _이를 보완하기 위에 나온게 React Hook_이다 훅은 생명주기 기능을
연동할 수 있게 해주는 함수 이다. 오직 함수 컴포넌트에서만 사용가능하다
만약 같은 함수를 여러번 사용하게 될 때에는 직접 훅을 만들어서 사용할 수도 있다.</p>
<p>공식문서에서는 아래와 같은 두가지의 규칙을 제시하고 있다</p>
<ol>
<li><p>최상위에서만 호출할 수 있다.</p>
</li>
<li><p>react함수 내에서만 호출할 수 있다.</p>
<p><a href="https://velog.io/@velopert/react-hooks">리액트의 Hooks 완벽 정복하기</a></p>
</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[이진 검색, 선택 정렬, 퀵 정렬]]></title>
            <link>https://velog.io/@bo-oram/%EC%9D%B4%EC%A7%84-%EA%B2%80%EC%83%89-%EC%84%A0%ED%83%9D-%EC%A0%95%EB%A0%AC-%ED%80%B5-%EC%A0%95%EB%A0%AC</link>
            <guid>https://velog.io/@bo-oram/%EC%9D%B4%EC%A7%84-%EA%B2%80%EC%83%89-%EC%84%A0%ED%83%9D-%EC%A0%95%EB%A0%AC-%ED%80%B5-%EC%A0%95%EB%A0%AC</guid>
            <pubDate>Mon, 30 May 2022 01:00:33 GMT</pubDate>
            <description><![CDATA[<p>우리가 수를 알 수 없는 많은 사람이 기재되어있는 전화번호부에서 특정 한 사람을 찾는다고 가정해보자 만약 <span style="background-color:#F5EEEE;">규칙없이 뒤섞여 있는 상태라고 한다면 리스트안의 모든 사람들을 비교</span>해나가야 할 것이다. </p>
<p>&lt;규칙없이 뒤섞인 상태에서 김보람찾기&gt;</p>
<div style="border:1px solid;padding:20px;margin-top:-10px;text-align:center;">박보람, 정보람, 이보람, 최보람, 김보람, 장보람, <br>곽보람, 채보람, 강보람,
문보람, 임보람, 성보람, 전보람, 한보람</div>

<p>만약 <strong>리스트가 어떤 규칙에 의해 정렬되어있다면</strong> 어떨까 예를 든 이름 <u>리스트가 자음순으로 배열되어있다고 가정</u>하고
<img src="https://velog.velcdn.com/images/bo-oram/post/07ae9182-29f9-45fc-9387-d80f3ec18353/image.png" alt="">
&quot;김보람&quot;을 찾아보자 아마도 다음과 같은 순으로 찾아나갈 것이다 말로 풀자면
자음순으로 정렬되어있다고 생각한 순간 <span style="background-color:#E06767; color:#fff;">김보람을 찾기 위해 리스트의 반절중 뒷부분은 보지 않을 것이다</span> 왜? 기억(ㄱ)은 <span style="color:#E06767;">앞부분에 위치할거라고 확신하기 때문</span>이다. 그렇게 <span style="background-color:#F5EEEE;">그룹을 반으로 나누고 고려대상에서 제외할 그룹은 무시</span>하고 또 그룹을 나누고 제외할 그룹은 무시되고를 반복하여 결국 결과에 도달할 것 이다(여기서는 &quot;김보람&quot;을 찾았을 것이다)</p>
<p><img src="https://velog.velcdn.com/images/bo-oram/post/cdb9d4e4-3049-4789-9d82-12c35fc81bad/image.png" alt=""></p>
<p>이 검색 알고리즘을 <span style="font-size:20px; font-weight:bold;">&quot;이진 검색&quot;</span>이라고 한다. 이진 검색에서 중요한 부분은 <span style="color:tomato;">일의 양이 데이터의 양이 증가함에 비해 천천히 증가한다는 점</span>이다. <span style="background-color:#F5EEEE;">1000개중 1개의 이름을 찾을때는 이름 10개를 확인</span>해야한다. <span style="background-color:#F5EEEE;">2000개가 있을 땐</span> 어떨까 두배로 양이 늘었지만 이름은 한개만 더 확인하면된다 <span style="background-color:#F5EEEE;">11개를 확인</span>하면 된다는 이야기다 왜냐하면 첫 그룹을 나누어 확인하면서 2000의 반절인 1000이 검색대상에서 제외되기 때문이다. 즉 데이터의 양이 1000배 많아지더라도 일은 10번의 단계만을 더 거치게 된다.</p>
<hr>

<p>앞에서도 이야기했듯 이렇게 찾아 내기 위해서는 &quot;정렬&quot;이 앞선 조건일텐데 이 정렬은 어떻게 할 수 있을까 선택 정렬과 퀵정렬에 대해 알아보자</p>
<p><strong style="font-size:20px;">선택 정렬</strong>은 <span style="background-color:#F5EEEE;">매 회전마다 가장 적합하다고 판단되는 값을 선택해 나가는 방법</span>이다
<img src ="https://velog.velcdn.com/images/bo-oram/post/4dbb6f67-a3fb-4927-ae48-37ad08c74ae1/image.png"></p>
<p style="color:tomato;">구현이 쉬운편이고 정렬을 위한 비교 횟수가 많지만 실제 교환 횟수는 적기에 많은 교환이 일어나야하는 자료상태에서 효율적 이지만 항상 O(N^2)의 시간복잡도를 갖는 오래 걸리는 정렬 방식이다.</p>

<hr>

<p><strong style="font-size:20px;">퀵 정렬</strong>은 분할 정복방법을 통해 주어진 배열을 정렬하는데 쓰인다 이글의 첫시작인 이진검색에 알맞는 정렬방법이라고 할 수 있다
<span style="background-color:#F5EEEE;">분할 정복:문제를 작은 2개의 문제로 분리하고 각각을 해결한 다음, 결과를 모아서 원래의 문제를 해결하는 전략</span></p>
<p>배열 가운데 <span style=" color:tomato;">피벗을 고른다</span>(피벗을 고르는 과정에는 아직도 많은 논쟁이 있다)<span style=" color:tomato;">피벗 앞에는 피벗보다 값이 작은 요소가 오고, 피벗 뒤에는 피벗보다 값이 큰 요소가 오도록 피벗을 기준으로 배열을 둘로 나눈다</span> 이렇게 배열을 둘로 나누는 것을 분할(Divide) 이라고 하고 분할을 마친 뒤에 피벗은 더 이상 움직이지 않는다. 분할된 배열에 다시 이 과정을 반복하는 것을 반복하며 정렬을 마치는 것이다.
<img src="https://velog.velcdn.com/images/bo-oram/post/facea011-74f2-4ce3-b200-f567a60564c1/image.png" alt="">
위 그림은 퀵정렬의 개념을 요약한 그림이다 좀 더 디테일한 설명을 원한다면
<a href="https://gmlwjd9405.github.io/2018/05/10/algorithm-quick-sort.html">[알고리즘] 퀵 정렬(quick sort)이란</a>을 참고하자</p>
<p>퀵 정렬은 분할로 이루어진 정렬법으로 분할과정에서 logN의 시간이 걸리게 되고 전체적으로 보면 NlogN의 시간이 걸리게 된다. 이는 다른 정렬방법중 비교적 <strong>준수한 속도</strong>이다 하지만 <strong>선택된 피벗에 따라서 시간복잡도가 매우 크게 다를 수 있다는 단점</strong>이 있다 즉 최악의 피벗을 고른다면 O(N^2)의 시간복잡도를 가질 수 도 있다</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[항해99WIL - 3주차]]></title>
            <link>https://velog.io/@bo-oram/%ED%95%AD%ED%95%B499WIL-3%EC%A3%BC%EC%B0%A8</link>
            <guid>https://velog.io/@bo-oram/%ED%95%AD%ED%95%B499WIL-3%EC%A3%BC%EC%B0%A8</guid>
            <pubDate>Sun, 29 May 2022 09:45:26 GMT</pubDate>
            <description><![CDATA[<p>이번주 키워드 <strong>DOM, 서버리스</strong></p>
<h3 id="1-dom">1. DOM?</h3>
<p>돔은 Document Object Model의 약자로 <span style="color:tomato;">문서 + 객체 + 모델</span>이 합쳐진 상태이다
즉 <u>문서를 객체로 만든 모델</u> 이라고 이해하면 빠르다</p>
<p>여기서 문서는 HTML문서를 말한다. 만약 브라우저를 공장이라 한다면
html은 주문서인데 이 주문서에 내가 원하는 웹페이지의 요소과 구조를 설계해서
브라우저로 보내면 작성 된 구조에 맞게 엘리먼트들이 배치되고 명령보내 속성이나 디자인, 배치 등을 조작할 수 있도록 제작 된 상태, 다시 말해 <span style="background-color:tomato; color:#fff; padding:0 5px;">html속 &lt;꺽쇠&gt;를 실체화한 형태</span>라고 볼 수 있다.</p>
<p style="padding:0;margin:0; color:tomato;">DOM은 API를 가지고 있기 때문에 약속된 형태로 요청하면 그에 맞춰 동작한다.</p>
이 돔은 각종 노드들이 트리 구조로 구성되어있어 <span style="color:tomato;">기본적으로 노드의 기능(textContent,firstChild,lastChild등)을 갖추고 있다 그렇기 때문에 자바스크립트 등의 언어로 각요소들을 조작할 수 있는 것이다.</span>

<p>dom에 CSS는 포함되지 않고 CSSOM(CSS Object Model)가 따로 있다.</p>


<hr>
<h3 id="2-서버리스">2. 서버리스</h3>
<p>  서버리스는 서버와 리스의 합성어로 서버가 없다라고 오해할 수 있다.
하지만 이것은 <strong>사용자가 관리할 서버가없다</strong> 라고 이해해야한다. 어딘가에는 코드가
저장되어야 하기 때문에 서버가 없는것은 불가능하다.</p>
<p><strong>서버리스는 클라우드 서비스 공급자가 서버를 관리</strong>해주며 특정 요청이나 이벤트가 있을 때
클라우드 서버를 이용하거나 서비스 할 어플리케이션을 동작시키는 것이다
보통 &quot;서버리스 컴퓨팅&quot;또는 &quot;서버리스 아키텍처&quot;라고 불린다</p>
<p>서버리스는 복잡한 <u>기능들을 개발자가 직접 개발하지 않고 클라우드 공급자가 제공하는 서비스
를 이용해 쉽고 안정적으로 구현</u>가능한 <strong>BaaS</strong>(BACKED-AS-A-SERVIECE)와 <u>개발자가 만든 기능들을 
클라우드 제공업체가 함수단위로 나누어 관리</u>해주는<strong>FaaS</strong>(Function-as-a-Service)로 나누어 이해할 수 있다</p>
<p>서버리스의 장점은 <span style="color:green;">운영 비용 절감되며 서비스를 빠르고 간단하게 출시할 수 있다</span>
단점은 함수가 호출된 이후 <span style="color:green;">실행되는 데에 대기시간이 존재</span>하기 때문에 빠른 응답이 필요할 경우에는
부적절할 수 있다</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[항해99WIL - 2주차]]></title>
            <link>https://velog.io/@bo-oram/%ED%95%AD%ED%95%B499WIL-2%EC%A3%BC%EC%B0%A8</link>
            <guid>https://velog.io/@bo-oram/%ED%95%AD%ED%95%B499WIL-2%EC%A3%BC%EC%B0%A8</guid>
            <pubDate>Sun, 22 May 2022 08:55:10 GMT</pubDate>
            <description><![CDATA[<p>이번주 키워드는 <strong>1.JavaScript의 ES란? 2.ES5/ES6 문법 차이</strong>이다 하나씩 알아보자</p>
<hr>
<h2> 1.JavaScript의 <sapn style="color:tomato;">ES</sapn>란?</h2>
결론 부터 말하면 <b>ES는 자바스크립트 표준 규격</b>이라고 할 수 있다.

<div style="font-size:20px;">1990년대 후반, <a href="https://ko.wikipedia.org/wiki/%EB%B8%8C%EB%9D%BC%EC%9A%B0%EC%A0%80_%EC%A0%84%EC%9F%81">브라우저 전쟁</a>이 일어난다. 1,2,3차의 브라우저 전쟁속 많은
브라우저들이 탄생했는데 이 <span style="color:orange;">브라우저들 마다 다른 스크립트 언어를 사용하기 때문에 서로 호환되지 않는 문제가 발생</span>한다. 즉 같은 코드여도 어떤 브라우저에서는 작동되고 어떤 브라우저에서는 오류를 뱉어낸다는 것이다. 이를 막기 위해 넷스케이프는 96년 11월에 국제 표준화 기구(Ecma)에 자바스크립트 기술 규격 제정을 요청하고 Ecma는 자바스크립트에 대한 표준을 내리게 된다.</div>

<p style="color: lightgray;">또한 ECMA에서는 자바스크립트의 표준만 내리는 게 아니라 다른 표준안도 정하기 때문에 그와 구분하기 위해 숫자를 붙였는데 262다.</p>

<hr>
<h2> 1.<sapn style="color:tomato;">ES5/ES6</sapn>문법 차이</h2>
2009년에 업데이트된 ES5 2015년에 업데이트된 ES6 사이에서 큰 변화가 있었고 그 이후 버전들은 ESNext라 칭한다. 이제 시장에서는 ES6이상을 원하지만 이전에 남겨진 코드들을 이해하려면 그 전 버전 역시 어느정도 알고 있어야 한다.

<h3 id="1-let-const">1. let, const</h3>
<p>기존의 var 키워드는 함수 레벨 스코프를 가지며 암묵적 재할당이 가능했었다.
하지만 <strong>let은 동일한 이름으로 선언될 수 없으며 재할당은 가능하다. const는 한번 초기화된 변수해 재할당, 재선언 모두 불가능</strong>하다 그리고 이 둘(let,const)은 블록 레벨 스코프를 가져 외부에서 참조할 수 없다. 또한 var와 달리 TBZ의 제약을 받아 변수 초기화 전에 엑세스 하려고 하면 오류를 뱉는다</p>
<h3 id="2-화살표---함수">2. 화살표 ( =&gt; )함수</h3>
<p>기존 함수를 표현하는 방법은 함수 선언문과 함수 표현식이 있다  </p>
<pre><code class="language-javascript">// 함수 선언
function foo() { }

// 함수 표현식
const foo  = function() { } // 익명함수를 변수에 할당</code></pre>
<p>이 둘의 다른 점은 함수 선언은 호이스팅의 영향을 받으며 함수 표현식은 호이스팅 되지 않는다 즉 함수 표현식을 한언하기 전에는 함수를 호출할 수 없다</p>
<pre><code class="language-javascript">const func1 = () =&gt; { }; // 화살표 함수</code></pre>
<p>화살표 함수는 function키워드를 생략할 수 있으며 만약 파라미터가 하나라면 괄호()를 생략할 수 있다 또 함수 내에 표현식이 하나라면 중괄호와 rutrun을 생략할 수 있다</p>
<h3 id="3-template-literals">3. Template literals</h3>
<p>기존에는 표현식 사이에 문자열을 넣을 때 &quot;저는 &quot; + (a + b) + &quot;살이고 &quot; + c + &quot;이런식으로 표현했다 ES6이후 부터는 백틱(<code>)을 이용하여</code>저는 ${a+b}살이고 ${c}를 좋아합니다.`;이렇게 표현식과 텍스르를 함께 리턴할 수 있다.</p>
<h3 id="4-클래스">4. 클래스</h3>
<p>ES6이전에는 없던 문법으로 이전 Class의 개념이 없었을 때 Class의 형태를 구현하려면 prototype을 이용해 구현했어야 했다 같은 객체 생성자 함수를 사용하는 경우, 특정 함수 또는 값을 재사용 할 수 있는데 바로 프로토타입이라고 한다</p>
<pre><code class="language-javascript">//prototype
function Dog(name) { 
    this.name = name; 
} 
Dog.prototype.say = function(){ 
    console.log(&#39;귀여운 &#39;+ this.name ) 
} 
var dog = new Dog(&#39;푸들&#39;); 
dog.say() // 결과 : 귀여운 푸들
</code></pre>
<pre><code class="language-javascript">//Class
class Dog { 
    constructor(name){ 
        this.name = name; 
    } 
    say(){ c
        onsole.log(&#39;귀여운 &#39;+ this.name ) 
    } 
} 
const dog = new Dog(&#39;푸들&#39;); dog.say() // 결과 : 귀여운 푸들
</code></pre>
<h3 id="5-this">5. this</h3>
<p>ES6에서의 this 는 자신을 둘러싸고 있는 this를 바라보기 때문에 따로 바인딩이나 변수에 담을 필요가 없고 화살표 함수를 사용하면 선언된 스코프에 자동 바인딩된다</p>
<h3 id="6-모듈">6. 모듈</h3>
<p>기존에는 name-space 방식 또는 requrejs 같은 라이브러리로 글로벌 레벨 스코프의 변수 오염을 보완했었다 ES6이후에는 import, export를 사용하여 하나의 함수 또는 변수를 관리함으로 다른 파일에서도 이를 활용할 수 있다</p>
<h3 id="7-객체-비구조화-할당객체-구조-분해">7. 객체 비구조화 할당(객체 구조 분해)</h3>
<p>비구조화 할당 문법을 사용하면 객체 안에 있는 값을 추출해서 변수 혹은 상수로 바로 선언해줄 수 있고 함수의 파라미터에서도 가능하다
<a href="https://learnjs.vlpt.us/basics/06-object.html">벨로퍼트님의 객체 자료</a></p>
<h3 id="8-string메서드-추가">8. string메서드 추가</h3>
<p>includes() : 괄호안의 내용이 포함 되어있다면 true를 없다면 false를 리턴함
startsWith() : 괄호안의 내용으로 시작된다면 true를 아니라면 false를 리턴함
endsWith() : 괄호안의 내용으로 끝난다면 true를 아니라면 false를 리턴함</p>
<h3 id="9-spread연산자">9. Spread연산자(...)</h3>
<p>연산자의 대상 배열 또는 이터러블을 개별요소로 분리한다</p>
<h3 id="10-rest파라미터">10. rest파라미터</h3>
<p>Spread연산자(...)를 이용하여 함수의 파라미터를 작성한 형태로 Spread연산자를 이용하면 파라미터로 오는 값을 배열로 전달받을 수 있다</p>
<hr>
<p>더 많은 차이가 있고 이후에 하나씩 추가하고 수정해 나갈 예정이다 : ] </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[호이스팅과 TDZ는 무엇일까 ? ]]></title>
            <link>https://velog.io/@bo-oram/%ED%98%B8%EC%9D%B4%EC%8A%A4%ED%8C%85%EA%B3%BC-TDZ%EB%8A%94-%EB%AC%B4%EC%97%87%EC%9D%BC%EA%B9%8C</link>
            <guid>https://velog.io/@bo-oram/%ED%98%B8%EC%9D%B4%EC%8A%A4%ED%8C%85%EA%B3%BC-TDZ%EB%8A%94-%EB%AC%B4%EC%97%87%EC%9D%BC%EA%B9%8C</guid>
            <pubDate>Fri, 20 May 2022 16:33:07 GMT</pubDate>
            <description><![CDATA[<h3 id="스코프-호이스팅-tdz">[스코프, 호이스팅, TDZ]</h3>
<p>스코프: 변수나 함수를 선언하게 될 때 어디서 어디까지 유효한지에 대한 범위를 의미한다
1.글로벌스코프: 전역이라는 의미로 코드의 모든 범위에서 사용이 가능하다
2.펑션 스코프 : 특정함수 내에서만 사용가능하다(var)
3.블록 스코프: 이프문 포문 스위치문 처럼 중괄호로 감싸지는 코드블록 내부에서만 사용이 가능하다 (let,const)</p>
<p><span style="color:green;">호이스팅</span>
사전적 의미로는 &quot;끌어 올리다&quot;란 뜻이다. <strong>스코프 내부 어디서든 변수 선언은 최상위에 선언된 것 처럼 작동하는 자바스크립트의 작동법</strong>이다. <u>var는 호이스팅이 작동하지만 let과 const는 작동하지 않는다</u></p>
<p><strong>왜?</strong> let과 const는 작동하지 않을까? <span style="color:#F56E6E;"> let과 const 이 둘은 TDZ(Temporal Dead Zone)의 영향을 받기 때문이다
TDZ는 변수의 선언과 변수의 초기화 사이의 변수에 접근할 수 없는 지점을 말하는데 var는 이 영향을 받지
않는다.</span></p>
<hr>
<h4 id="함수-선언문과-함수-표현식에서-호이스팅-방식의-차이">[함수 선언문과 함수 표현식에서 호이스팅 방식의 차이]</h4>
<p>함수를 변수에 담은 것이 함수 표현식 이며, function함수이름(파라미터)와 같이 선언하는 것을 함수 선언문 이라고 한다
위에서 말한 것 처럼 <strong>var와 함수 선언문은 호이스팅 대상이고, let, const, 함수 표현식은 해당되지 않는다</strong>
아래의 예시 코드를 보자</p>
<p style="color:green;">함수표현식의 호이스팅</p>

<blockquote>
<pre><code class="language-javascript">test();
var test = function() {
    console.log(&#39;123&#39;);
}
/* 에러!!!!!!!! 
먼저 호출한 후 함수를 변수에 담았다 var는 호이스팅의 영향을 받으므로 var test;가 위로 끌어 올려진다
그렇게 되면 변수에 아무 값도 담아지지 않은 상태이므로 undefined의 상태이다 이후 test가 변수인 상태로
호출 되므로 not function이라는 에러가 뜬다*/</code></pre>
</blockquote>
<pre><code>```javascript
var test = function() {
    console.log(&#39;123&#39;);
}
test();
/* 정상작동 :)
역시 호이스팅의 작용으로 var test;가 끌어올려 졌지만 호출전 함수가 담겼으므로 정상작동한다
/*</code></pre><pre><code class="language-javascript">test();
let test = function() {
    console.log(&#39;123.&#39;);
}
/* 에러!!!!!!!!!
let은 호이스팅의 영향을 받지 않는다 그렇기 때문에 함수가 만들어지기전 호출되었기 때문에 
Referecne Error에러가 발생한다*/</code></pre>
<p><span style="color:green;">함수선언문의 호이스팅<span></p>
<blockquote>
<pre><code class="language-javascript">test();
function test() {
    console.log(&#39;1234&#39;);
}</code></pre>
</blockquote>
<pre><code>&gt; ```javascript
function test() {
    console.log(&#39;1234&#39;);
}
test();
/*함수 선언문은 위쪽에 있던 아래쪽에 있던 호이스팅의 영향으로 위로 끌어당겨지기 때문에
위 아래 두코드 모두 정상 작동한다*/</code></pre><hr>
<h4 id="실행-컨텍스트와-콜-스택">[실행 컨텍스트와 콜 스택]</h4>
<p>실행 컨텍스트란 <strong>실행할 코드에 제공할 환경 정보들을 모아놓은 객체</strong>이다 </p>
<p>이를 콜 스택에 쌓아올렸다가,
가장 위에 쌓여있는 컨텍스트와 관련 있는 코드들을 실행하는 식으로 전체 코드의 환경과 순서를 보장한다
어떤 실행 컨텍스트가 활성화되는 시점에 선언된 변수를 위로 끌어올리고 외부 환경 정보를 구성하고,this의 값을 설정하는 등의 동작을 수행한다
<img src="https://velog.velcdn.com/images/bo-oram/post/4e4a40c6-7413-40c0-bce1-edecf6c6c29b/image.png" alt=""></p>
<ol>
<li>코드 실행과 동시에 전역 컨텍스트는 활성화 되며 종료 될 때 까지 유지 된다</li>
<li>foo() 함수가 실행되면 foo()함수에 대한 환경 정보를 수집해서 새로운 실행 컨텍스트를 생성하여 전역 위에 쌓는다</li>
<li>foo()함수가 실행되다가 내부 bar()함수를 만나면 또 함수의 실행 컨택스트르 생성에 쌓는다</li>
<li>bar()가 종료되면 해당 실행 컨텍스트는 콜스택에서 제거 된다</li>
<li>foo()함수 역시 실행종료 되면 콜스택에서 재거 된다</li>
</ol>
<hr>
<h4 id="-스코프-체인-">[ 스코프 체인 ]</h4>
<p>스코프 체인은 해당 코드의 유효 범위(in scope) 안에 있는 변수를 정의하는 객체의 체인, 리스트다
어떠한 변수값을 얻으려고 할 때 스코프 체인에서 이를 찾는다 리스트의 끝까지 탐색 후에도 그 변수가 없다면
존재하지 않는 변수를 참조했을 때 발생하는 에러인 ReferenceError가 발생할 것이다
중첩되지 않은 함수의 스코프 체인은 2개의 객체로 이루어진다. 하나는 함수의 매개변수와 지역 변수를
정의하는 객체고, 다른 하나는 전역 객체다.
함수가 정의될때 스코프체인을 저장하고 호출될 때 지역 변수를 보관하는 새로운 객체를 만들고 그 객체를 기존에 만들어둔 스코프 체인에 추가한다.</p>
<h4 id="-변수의-은닉화-">[ 변수의 은닉화 ]</h4>
<p>직접적으로 변경되면 안 되는 변수에 대한 접근을 막는 것을 은닉화라고 한다
클로저 함수를 사용하여 변수를 은닉할 수 있다 &#39;클로저 모듈 패턴&#39;을 사용해 객체에 담아 여러 개의 함수를 리턴하도록 만든다 이러한 정보의 접근을 제한하는 것을 캡슐화라고도 부른다 </p>
<div style="border:1px solid lightgray; color:gray; padding:20px;">
해당 내용은 코딩공부를 하며 작성된것이며 사실과 다를 수 있다요 :<
계속 수정 추가해 나갈것 입니다! </div>

<hr>
<h4 id="콘솔에-찍힐-b값-예상하기">[콘솔에 찍힐 b값 예상하기]</h4>
<pre><code class="language-javascript">let b = 1;

function hi () {

const a = 1;

let b = 100;

b++;

console.log(a,b); // 1 101 (B. 함수 내에 선언된 a,b를 호출한다)

}

//console.log(a);

console.log(b); //1 (A. 함수 밖의 최상단의 b를 호출한다)

hi();

console.log(b);//1 (C. 함수 밖의 최상단의 b를 호출한다)</code></pre>
<blockquote>
<p>1
1
101
1
의 순서로 출력될 것으로 예상 됩니다.
ABC의 순이고 그 이유는 함수가 호출되기전 최상단의 b를 출력했기 때문입니다</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[JavaScript 객체와 불변성이란 ? ]]></title>
            <link>https://velog.io/@bo-oram/JavaScript-%EA%B0%9D%EC%B2%B4%EC%99%80-%EB%B6%88%EB%B3%80%EC%84%B1%EC%9D%B4%EB%9E%80</link>
            <guid>https://velog.io/@bo-oram/JavaScript-%EA%B0%9D%EC%B2%B4%EC%99%80-%EB%B6%88%EB%B3%80%EC%84%B1%EC%9D%B4%EB%9E%80</guid>
            <pubDate>Fri, 20 May 2022 13:20:14 GMT</pubDate>
            <description><![CDATA[<h3 id="기본형-데이터와-참조형-데이터">[기본형 데이터와 참조형 데이터]</h3>
<p><strong>기본형</strong>은 <u>값을 그대로 할당</u>하는 자료형으로 _<strong>Number, String, Boolean, null, undefined, Symbol</strong>_가 있다</p>
<div style="border:1px solid gray; padding:10px;">만약 let a = 5 라고 선언하면 일단 컴퓨터는 데이터가 담길 공간을 확보한다 이후 별도의 메모리 방에 할당된 값(5)을 저장한다 이후 할당 값의 방의 주소를 해당 변수(5)가 들어있는 방을 검색해서 가지고 간다 그리고 그방의 값을 할당 값의 방 주소로 지정한다. </div>

<p>이미지로 표현하면 아래와 같다.
<img src ="https://velog.velcdn.com/images/bo-oram/post/ca32fee9-4251-4be3-ac15-bea9f763c5d3/image.png"></p>
<p><strong>참조형</strong>은 <u>값이 저장된 주소값을 할당</u>하는 자료형으로, 객체가 이에 해당되며 <strong>기본형보다 한단계를 더 거쳐서 저장</strong>된다. 이미지로 표현하면 아래와 같다.
<img src ="https://velog.velcdn.com/images/bo-oram/post/46d24127-b8e8-4593-97bb-e926ec778e9d/image.png"></p>
<hr>
<h3 id="객체의-형변환">[객체의 형변환]</h3>
<p>이전 게시물을 참고해주길 바래욥! :)
<a href="https://velog.io/@bo-oram/JavaScript%EC%9D%98-%EC%9E%90%EB%A3%8C%ED%98%95%EA%B3%BC-JavaScript%EB%A7%8C%EC%9D%98-%ED%8A%B9%EC%84%B1">JavaScript의 자료형과 JavaScript만의 특성</a></p>
<hr>
<h3 id="불변-객체를-만드는-방법">[불변 객체를 만드는 방법]</h3>
<p>객체는 참조형태로 전달하고 전달 받는다. 이때 어드레스를 공유하고 있다면 그상태는 언제든지 변경될 수 있어
문제가 될 가능성이 있다. 의도하지 않은 객체의 변경이 발생하는 원인의 대다수는 &quot;레퍼런스를 참조한 다른 객체에서 겍체를 변경&quot;하기 때문이다.</p>
<p>이를 장지하기 위해서는 두가지 방법이 있다
<strong>객체의 방어적 복사(Object.assign): 객체의 변경이 필요할 경우 복사본을 만들어 값을 변경
불변 객체화(Object.freeze): 객체 자체를 불변 객체로 만드는것</strong></p>
<hr>
<h3 id="얕은-복사와-깊은-복사">[얕은 복사와 깊은 복사]</h3>
<p>값을 복사하는 방법은 deep copy(깊은 복사)와 shallow copy(얕은 복사)가 있다 이는 관점을 달리 해석하면 되는데 아래의 코드를 보자</p>
<pre><code class="language-javascript">let num1 = 1
let num2 = num1

num2 = 2</code></pre>
<p>일 때 두가지 관점으로 해석 할 수 있을 것이다.
<i style="color:gray;">당연히 위 코드에서는 변수 선언 후 num2 = 2 이렇게 재할당 한 들 num1에는 영향이 없다</i></p>
<ol>
<li><p>num2는 num1의 값 1이 들어간다 즉 자체를 넣은 것이 아니기 때문에
나중에 num2를 수정해도  num1에는 영향을 미치지 않을것이다 </p>
</li>
<li><p>num2에 num1 자체를 넣는다 즉 num1과 num2가 동일하므로 나중에 num2를
수정하면 num1에도 영향을 미쳐야 한다</p>
</li>
</ol>
<p>여기서 1번은 깊은 복사이고 2는 얕은 복사이다 <strong>객체는 얕은 복사로 카피되며 원시값은 깊은 복사로 카피</strong>된다</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[JavaScript의 자료형과  JavaScript만의 특성]]></title>
            <link>https://velog.io/@bo-oram/JavaScript%EC%9D%98-%EC%9E%90%EB%A3%8C%ED%98%95%EA%B3%BC-JavaScript%EB%A7%8C%EC%9D%98-%ED%8A%B9%EC%84%B1</link>
            <guid>https://velog.io/@bo-oram/JavaScript%EC%9D%98-%EC%9E%90%EB%A3%8C%ED%98%95%EA%B3%BC-JavaScript%EB%A7%8C%EC%9D%98-%ED%8A%B9%EC%84%B1</guid>
            <pubDate>Fri, 20 May 2022 10:45:39 GMT</pubDate>
            <description><![CDATA[<p style="font-weight:bold; font-size:23px;">느슨한 타입(loosely typed)의 동적(dynamic) 언어?</p>
<span style="color:green;">느슨한 타입:</span> <span style="font-weight:bold;">타입 없이 변수를 선언</span>하는 것이라고 할 수 있다.
자바스크립트는 <u>내부적으로 타입이 관리</u>되기 때문에 선언 시 타입 없이 선언할 수 있다
강력한타입(strong typing)을 사용하는 자바는는 선언시에 int인지 String인지 등 타입과 함께 선언해야 한다 

<p><span style="color:tomato;">동적언어:</span> <strong>변수의 타입이 실행하면서 바뀌는 것을 허용</strong>하는 언어이다 
<u>코드를 컴파일하는 시점에 타입을 알 수 있으면 정적 타입, 실행 후 타입을 알 수 있다면 동적 타입</u>이라고 할 수 있다</p>
<hr>
<p style="font-weight:bold; font-size:20px;">[ 정적, 동적 언어의 장단점 ]</p>
<span style="color:green;">정적타입 언어의 장단점:</span> 자료형에 맞지 않는 값이 선언되어 있을 경우 컴파일 에러를 발생한다 즉 컴파일 시 변수 타입을 체크하기 때문에 <b>타입에러로 인한 문제점을 빨리 발견할 수 있으며 컴파일 시 타입을 결정하기 때문에 실행속도가 빠르다.</b> 반면 매번 일일이 <u>변수의 타입을 선언해 주어야하는 번거러움이 있다</u><br>
<span style="color:darkgray;">정적 타입 언어: Java, C, C++, C#, Scala,  Fortran, Haskell, ML, Pascal 등</span>

<p><span style="color:tomato;">동적타입 언어의 장단점:</span> 매번 타입을 선언할 필요가 없어 <strong>비교적 빠르게 코드를 작성할 수 있고, 실행 시 타입이 결정되므로 유연성이 높다</strong>. 하지만 <u>예상치 못한 타입이 들어와 에러를 발생시킬 수 있다</u> 이를 보완하기 위해 TypeSclipt나 Flow등을 사용할 수 있다(Groovy, Python, JavaScript, Ruby, Smalltalk, Lisp, Objective-C, PHP, Prolo)</p>
<hr>
<p style="font-weight:bold; font-size:20px;">[ JavaScript 형 변환 ]</p>
자바스크립트의 형변환에는 연산자 사용으로 인해 자연적으로 변환하는 <u>암시적 형 변환</u>과 프로그래머가 자료형을 정해서 변환하는 <u>명시적 형 변환</u>이 있다

<p><span style="color:green;">암시적 형 변환:</span> <mark style="background-color:#E1F46D;">더하기(+)연산</mark>을 하면 숫자보다 문자열이 우선시 되기 때문에 숫자와 문자가 연산되면 <mark style="background-color:#E1F46D;">숫자를 문자형으로 변환</mark>하여 연산한다 하지만 <em>그 외 연산자(-, *, /, %)는 숫자를 우선시 하기 때문에 변환되지 않는다.</em>
엄격하지 않은 <mark style="background-color:pink;">동치(==) 비교시에도 변환</mark>은 일어난다. 만약 <mark style="background-color:pink;">&quot;1&quot; == 1 로 비교한다면 true로 반환</mark>된다. 문자 1과 숫자 1은 다르지만 한쪽 또는 양쪽이 형 변환을 거친 후 비교되기 때문이다. 만약 <mark style="background-color:#A8E2EF;">===의 일치연산자</mark>를 사용한다면 타입변환 없이 <mark style="background-color:#A8E2EF;">타입 동등 여부까지 비교하기 때문에 &quot;1&quot; == 1은 false로 반환</mark>될 것이다.</p>
<p><span style="color:green;">명시적 형 변환:</span> 개발자가 의도를 가지고 Object(), Number(), String(), Boolean()등을 이용하여 변환한 것이다</p>
<hr>
<p style="font-weight:bold; font-size:20px;">[ null과 undefined ]</p>
두 타입은 모두 '값이 없음'을 나타낸다.
다른점은 undefined은 변수를 선언하고 값을 할당하지 않은 상태, null은 변수를 선언하고 빈 값을 할당한 상태(빈 객체)이다. 즉, undefined는 자료형이 없는 상태이다.
undefined도 할당 할 수 있지만 비어있는 값을 선언할때는 null의 이용을 권장한다

<p><span style="color:green;">**undefined의 경우 typeof로 출력하면 undefined가 나온다. null은 출력하면 object로 출력된다. 이는 여전히 원시 타입(primitive value)로, JavaScript에서는 구현 버그로 간주한다.</span></p>
<hr>
<p style="font-weight:bold; font-size:20px;">[ TypeSclipt와 Flow ]</p>
이번엔 위에서 이야기한 TypeSclipt와 Flow에 대해 더 자세히 알아보자
다시 한번 정리하면 <span style="color:tomato;">**자바스크립트는 동적인 언어로서의 문제점은 타입의 변경이 너무나도 쉬우면서, 실행 시 타입을 알 수 있기 때문에 테스트 시 안보였던 버그가 서비스 운영시 생길 수 있다는 점**</span>이다. 이를 보완 하기 위에 나온 아이들이 TypeSclipt와 Flow이다 **이 둘은 자바스크립트에 정적 타입 시스템을 도입하는 것으로 코드만 봐서는 숩게 구분 할 수 없을 정도로 비슷하지만 그 목표는 확연히 다르다**

<div style="border:1px solid tomato; padding:20px;margin-bottom:20px; margin-top:20px;"><b>플로우의 목표</b>:
비록 간혹 제대로 된 프로그램을 안통과시켜 줘서 프로그래머의 불편을 초래하는 한이 있더라도
<u>문제가 생길 수 있는 프로그램을 최대한 잡아내는게 목표</u></div>

<div style="border:1px solid blue; padding:20px;"><b>타입스크립트의 목표</b>:
안전하고 증명 가능하게 올바른 타입 시스템은 목표가 아니며
올바름과 생산성 사이에 균형을 잡는 것이 목표다</div>

<p>아래 링크를 참고하면 TypeSclipt와 Flow를 더 자세히 알 수 있다
<a href="https://youtu.be/H16gTwa2J7g">TypeScript와 Flow: 자바스크립트 개발에 정적 타이핑 도입하기</a>
<i style="color:darkgray;">(내 생각에 영상속 개발자는 TypeSclipt를 좀 사랑한다...)</i></p>
<hr>
]]></description>
        </item>
        <item>
            <title><![CDATA[디지털? 아날로그?]]></title>
            <link>https://velog.io/@bo-oram/%EB%94%94%EC%A7%80%ED%84%B8-%EC%95%84%EB%82%A0%EB%A1%9C%EA%B7%B8</link>
            <guid>https://velog.io/@bo-oram/%EB%94%94%EC%A7%80%ED%84%B8-%EC%95%84%EB%82%A0%EB%A1%9C%EA%B7%B8</guid>
            <pubDate>Fri, 20 May 2022 01:49:52 GMT</pubDate>
            <description><![CDATA[<p><strong>아날로그와 디지털은 어떤게 다를까?</strong></p>
<p><span style="color:green; font-weight:bold;">아날로그</span>: <strong>연속적</strong>인 자료의 표현
<span style="color:tomato; font-weight:bold;">디지털</span>: 연속적인 자료를 의도적으로 구분지어 명확히 표현하는 <strong>불연속적표현</strong></p>
<hr>
<p>햇빛과 전등으로 예를 들어보자
<img src="https://velog.velcdn.com/images/bo-oram/post/eb37bb96-d12e-4d78-871b-53f3019646f0/image.png" alt=""></p>
<p>실외의 <strong>햇빛은</strong> 정도의 구분이 없이 밝아지고 어두어지며 <strong>연속적인 값</strong>을 내지만 <strong>전등의 경우</strong>는
꺼지고 켜지는 경우 <strong>2가지의 단계로 구분</strong>지어져 있다
햇빛처럼 연속적인 값의 표현을 아날로그, 전등처럼 중간의 단계없이 일정값의 단계로 구분지어 있는 것을 디지털이라고 할 수 있다</p>
<h3 id="디지털표현의-확산-왜">디지털표현의 확산 &quot;왜??&quot;</h3>
<p>컴퓨터와 로봇들이 삶에 많이 들어오며 <strong>명확히 명령하고 명확히 수행받기 위해</strong> 디지털표현법이이 더 확대되었다고 한다</p>
<hr>
<p style="font-size:20px;">[ 이미지의 디지털화 ]</p>
<li><span style="font-weight:bold;">아날로그 이미지</span> 는 아날로그 카메라의 <u>감광영역이 파사체에서 나오는 빛을 흡수하여 다양한 단계를 거쳐 종이 위에 현상되고 인화되어 표현</u>되는 것이다. </li>

<li><span style="font-weight:bold;">디지털 카메라</span>는 들어오는 빛의 양에 비례는 양으로 계산되어 빛의 강도를 나타내는 수를 배열한 것이다</li>


<div style="border:1px solid tomato; padding:10px; margin:10px; color:tomato;">
피사체를 찍었을 때 들어오는 값은 아날로그 값으로 연속된 값이다 이를 일정 간격으로 나누고 각 위치에서 표현되는 색상 값의 일정 범위를 대표하는값으로 근사화시킴으로서 불연속화하는 것을 이미지의 디지털화 라고 할 수 있다. </div>

<p>일정 간격으로 나누어지는 각 요소를 픽셀, 한국어로는 화소라고 표현한다
만약 4000 * 3000픽셀의 영상이 있다면 이는 1천 200만화소 또는 12메가픽셀이라 표현할 수 있으며 1픽셀당 3가지 색의 빛의 강도를 가지게 되므로 이 영상은 3천 6백만개의 빛의 강도 값을 가지고 있다고 할 수 있다</p>
<hr>
<p style="font-size:20px;">[ 음향 디지털화 ]</p>

<p><strong>소리</strong>란 <i style="color:tomato;">물리적인 공기의 진동</i>을 말한다 1870년대에 토머스에디슨은 <strong>&#39;축음기&#39;</strong>라는 장치를 만들었는데 이 장치는 기압변동을 패턴으로 변환했고 나중에 <strong>이패턴을 이용해 기압 변동을 재현</strong>할 수 있었다.
시간에 따른 기압의 변화를 그래프로 그려보면 아래의 이미지와 같이 나타낼 수 있다
<img src="https://velog.velcdn.com/images/bo-oram/post/a6bfa5aa-1c94-4c08-94da-0670421e083e/image.png" alt=""></p>
<p>위의 곡선그래프에서 곡선의 높이를 일정한 간격으로 나누어 수치화 하고 이렇게 얻은 수치가 아래와 같은 파형의 디지털 표현이다
<img src="https://velog.velcdn.com/images/bo-oram/post/cc997e29-773f-4cac-be32-fdce038df7b7/image.png" alt=""></p>
<p>디지털화 되거나 그 반대방향으로 <strong>변환 할때 일정 부분의 손실</strong>이 발생하지만 이는 사람이 <strong>감지할 수 없을정도</strong>이며 <strong>mp3나 aac같은 방법으로 압축하면 원본의 10분의 1정도로 용량이 줄어든다</strong>
「 사람은 너무 작거나 낮은 소리, 너무 높은 소리는 들을 수 없다 하지만 기계적으로 이를 모두 저장하기 때문에 이부분을 삭제하는 것을 mp3압축방식이이며 여기서 mp3의 기술적인 문제를 보완해 나온것이 AAC다
AAC는 현재 유튜브, 아이폰등에서 사용되는 기본 오디오 포맷이다. 」</p>
<hr>
<p style="font-size:20px;">[ 영화의 디지털화 ]</p>
영화의 디지털 표현은 <span style="font-weight:bold;">음향과 영상 요소를 결합하고 동기화 하는 것</span>이다
1870년대에 영국인 사진가 에드워드 마이브리지가 최초의 영사기 주프락시스코프를 선보이며 영화의 역사가 시작되었다 이때의 영화는 12프레임만 사용하여 부자연 스러웠지만 <i>오늘날의 영화는 초당 24프레임, tv는 초당 25프레임 또는 30프레임의 비율로 보여주며 비디오 게임은 초당 60프레임으로 상당히 빠른 속도이다</i>

<hr>
<p style="font-size:20px;">[ 텍스트 디지털화 ]</p>
컴퓨터는 <i style="color:tomato;">각 문자를 이진수로 풀이한 약속된 코드 값으로 기억</i>한다.
이렇게 정해 놓은 코드를 문자 이진 코드라고 한다.

<p><strong>아스키코드</strong>: 미국 ANSI에서 표준화한 정보교환용 7비트 부호체계(1비트는 통신 에러 검출을 위해 사용함)이며 0~127까지 즉 128개의 고유한 값을 각각 문자에 할당하였다.
<img src="https://velog.velcdn.com/images/bo-oram/post/ed76aee8-34a9-4eb7-a683-21f5b2827d18/image.png" alt=""></p>
<p><strong>유니코드</strong>: 아스키코드는 글자수가 많은 아시아권에서 사용하기는 제한적이기 때문에 그 한계성을 해소할 수 있는체계로 만들어진 코드이다 아스키코드가 1바이트로 정의되었다면 <em>유니코드는 용량을 확장해 2바이트 즉16비트로 표현되므로 최대 65,536자까지 표현할 수 있다.</em>
<img src="https://velog.velcdn.com/images/bo-oram/post/15cf7aee-6ec9-4035-b36e-cd3419ac37aa/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[항해99WIL - 1주차]]></title>
            <link>https://velog.io/@bo-oram/%ED%95%AD%ED%95%B499WIL-1%EC%A3%BC%EC%B0%A8</link>
            <guid>https://velog.io/@bo-oram/%ED%95%AD%ED%95%B499WIL-1%EC%A3%BC%EC%B0%A8</guid>
            <pubDate>Sun, 15 May 2022 14:28:42 GMT</pubDate>
            <description><![CDATA[<p><strong>이번주 WIL키워드</strong></p>
<h2 id="1-api">1. API</h2>
<p>application programming interface의 약자로
애플리케이션에서 데이터를 읽거나 쓸 때 사용하는 접 점을 말한다</p>
<p>쉽게 풀어서 생각하면 키보드 같은 것 이다</p>
<p><strong>나: 내가 이 버튼을 누를테니까 이 글자를 출력해 주겠니? 
키보드(눌림)
컴퓨터: 응 니가 그버튼 누른거 확인했어 출력해 줄게</strong></p>
<p>이때 나와 컴퓨터 간의 인터페이스가 키보드인 것처럼
컴퓨터나 프로그램 사이의 연결 버튼? 뭐 그런 느낌이라고 이해하면 된다</p>
<p>데이터서버 &lt;----- 인터페이스(API) -----&gt; 프로그램 </p>
<p>여기에는 크게
private api :  프라이빗 API : 회사 개발자가 자체 제품과 서비스를 개선하기 위해 내부적으로 발행함
public api : 공공 API : 개방형 API로, 모두에게 공개됨
Partner api : 파트너 API : 데이터 공유에 동의하는 특정인들만 사용할 수 있음</p>
<hr>
<h2 id="2-jwt">2. JWT</h2>
<p>사용자를 인증하고 식별하기 위한 토큰기반의 인증이다
기존 인증 시스템에서는 서버측에서 유저의 정보를 기억하고 있어야 했고 세션(로그인된 상태)을
유지 하기위해 메모리/디스크/데이터베이스 시스템에 담아 관리했었다 그 관리로 많은 자원가 비용이 발생했다
JWT는 서버 쪽이 아닌 클라이언트에 저장되어 사용자가 서버에 요청을 할 때 마다 해당 토큰을
포함하여 전달하고 서버는 요청을 받았을때 로그인이 되었는지를 확인할 필요 없이 이 토큰이 유효하고
인증됐는지만 검증하여 작업을 처리하면 된다. </p>
<p>JWT를 사용했을때 일반적인 처리 순서는</p>
<ol>
<li>클라이언트가 로그인 정보로 본인을 인증한다</li>
<li>서버에서 헤더 base64 + 페이로드 base64 + SECRET_KEY의 형태로 클라이언트에게 발행해준다</li>
<li>클라이언트가 서버에게 어떤 작업을 요할때 토큰을 같이 첨부해 요청한다</li>
<li>서버는 이 토큰이 찐인지 아직 사용할 수 있는지 확인한다</li>
<li>찐이고 사용기간이 남았다면 작업을 실행한다</li>
</ol>
<p>JWT의 단점은 해당 토큰을 발행한 후 그 토큰이 어떤식으로든 가로챔을 당했을 때
그토큰의 사용기간이 만료될때까지 토큰을 뺏거나 삭제할 수 없다 그렇기 때문에 토큰내에 중요한 정보를
넣어서는 안된다.</p>
<hr>
<blockquote>
<p><strong>1주차 느낀점</strong>
일할때도 지금과 같은 양에 시간을 업무에 투자했었다 지금은 온전히 스스로 디벨럽을 위해 내시간을 사용하고 있어서 너무 행복하다
지금 스스로에게 불만은 하루를 너무 달려서 금새 지쳐버리는점이 너무 아쉽다 일주일은 7일인데 3일을 미친듯 달리고 4일을 지쳐있다 하루의 시간분배를 잘하면 좀 더 영양있는 스터디를 할 수 있을것 같은데 아직 방법을 잘 모르겠다.
이번주는 어떤 디테일한 내용을 배웠다기 보다 구글이 짱이라는걸 배웠다 어지간한건 똑똑이들이 이미 어딘가에 올려놓고 구글이 그걸 배포해주고 있으니 혼자해서 안되면 포기하지말고 그냥 넘기지 말고 구글링해보는 습관을 들이자 누가 알려준다고 내 머리에 남아있지는 않다 내가 노가다를 뛰어야 결국 내것이 되는것이니 안알려준다고 답답해 하지말자 일단 다가온 다음주도 파이팅하는걸로 ..!</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[2022-05-13]]></title>
            <link>https://velog.io/@bo-oram/55-05-13</link>
            <guid>https://velog.io/@bo-oram/55-05-13</guid>
            <pubDate>Fri, 13 May 2022 23:25:50 GMT</pubDate>
            <description><![CDATA[<p>항해 5일차가 됐다.
사실 지금 엄청엄청 피곤하다 체력관리 잘해야하는데 지금 너무 재밌어서 자꾸 게임하듯 하나만 더 풀고 자야지
하면서 18시간을 넘게 컴퓨터 앞에있다 아래처럼 내 멋대로 풀었지만 풀고나서 다른 분들이 코드 한줄로 해결한걸 보면 진짜 쌉간지다... 나는 세상 컴퓨터한테 요로케해바 조로케해바 하면서 뺑뺑이돌리는데 뙇 야  요거요거해 피니쉬- 이래버리니까 사실 오늘 내가 아래 푼 문제는 정말 하타치로 해결한 한거다... 그래도!!! 그래도 잘했어 보람아 일단 지금은 걸어가는가 비행기를 타는가가 중요한게 아니야! 목적지에 다다르는게 중요한거야!!!!!
잘했어 잘했어 난 진짜 이런 내가 너무 좋아 머쪄!!!!!!!!!!!!!!!! </p>
<h3 id="알고리즘-문제">알고리즘 문제</h3>
<p><strong>문제1:</strong>
<img src="https://velog.velcdn.com/images/bo-oram/post/15242afd-eee5-459b-afbc-7c0f83302305/image.png" alt=""></p>
<p><strong>내가 푼 해결 법:</strong></p>
<pre><code class="language-javascript">process.stdin.setEncoding(&#39;utf8&#39;);
process.stdin.on(&#39;data&#39;, data =&gt; {
    const n = data.split(&quot; &quot;);
    const a = Number(n[0]), b = Number(n[1]);

    let c = a
    let d = b
    let e = &quot;*&quot;
    let f = e.repeat(c)

    for(let i = 0; i &lt; d; i++){
        console.log(f)        
    }

});</code></pre>
<hr>
<p><strong>문제2:</strong>
<img src="https://velog.velcdn.com/images/bo-oram/post/81742477-9a2f-47de-a725-a5fe30c32390/image.png" alt=""></p>
<p><strong>내가 푼 해결 법:</strong></p>
<pre><code class="language-javascript">function solution(num) {
    var answer = &#39;&#39;;    
    if(num % 2 === 0){
        return(&quot;Even&quot;)
    } else{
        return(&quot;Odd&quot;)    
    }
    return answer;
}</code></pre>
<hr>
<p><strong>문제3:</strong>
<img src="https://velog.velcdn.com/images/bo-oram/post/88258ebb-62b3-44d3-891a-6088d250ac21/image.png" alt=""></p>
<p><strong>내가 푼 해결 법:</strong></p>
<pre><code class="language-javascript">function solution(s) {
    let a = s.length
    if(a % 2 === 0 ){
        let b = s.substr(a/2-1,2)
        return(b)
    }else if(!a % 2 === 0){
        let c = s.substr(a * .5 - 0.5,1)
        return(c)
    }
}</code></pre>
<hr>
<p><strong>문제4:</strong>
<img src="https://velog.velcdn.com/images/bo-oram/post/dce0da21-3c33-4f41-9822-b139d884af02/image.png" alt=""></p>
<p><strong>내가 푼 해결 법:</strong></p>
<pre><code class="language-javascript">function solution(a, b) {
    var answer = 0;
    if(a === b){
        return( a | b)
    }else if(a &lt; b){
        for(let i = a; i &lt;= b; i++){
            answer += i
        }
        return answer;
    }else if(a &gt; b){
        for(let i = b; i &lt;= a; i++){
            answer += i
        }
        return answer;
    }


}</code></pre>
<hr>
<p><strong>문제5:</strong>
<img src="https://velog.velcdn.com/images/bo-oram/post/a99bd443-6623-4c5c-905f-91c3d4cfd042/image.png" alt=""></p>
<p><strong>내가 푼 해결 법:</strong></p>
<pre><code class="language-javascript">function solution(s) {
    var answer = parseInt(s);
    return answer;
}
</code></pre>
<hr>
<p><strong>문제6:</strong>
<img src="https://velog.velcdn.com/images/bo-oram/post/bf441aed-c8fe-4ac9-8836-18e57313d7ff/image.png" alt=""></p>
<p><strong>내가 푼 해결 법:</strong></p>
<pre><code class="language-javascript">function solution(numbers) {
    let a = 0
    for(let i = 0; i &lt;= 9; i++){

        if(!numbers.includes(i)){
             a += i
        }
    }
    return a
}</code></pre>
<hr>
<p><strong>문제7:</strong>
<img src="https://velog.velcdn.com/images/bo-oram/post/cb6fd9d7-36fa-4979-8822-ef71669eae39/image.png" alt=""></p>
<p><strong>내가 푼 해결 법:</strong></p>
<pre><code class="language-javascript">function solution(absolutes, signs) {
    let t = []
    let e = 0
    for (let i=0; i &lt; absolutes.length; i++){
    let f = signs[i]
    if(f === false){
        t.push(-1)
    }else{
        t.push(1)
    }
    let d = absolutes[i] * t[i]
    e += d
}
return e
}</code></pre>
<hr>
<p><strong>문제8:</strong>
<img src="https://velog.velcdn.com/images/bo-oram/post/90cda2b0-6822-4e52-bafb-f18c6c66882a/image.png" alt=""></p>
<p><strong>내가 푼 해결 법:</strong></p>
<pre><code class="language-javascript">function solution(arr) {
    let sum = 0
    let sum_ = arr.length
    arr.forEach(n =&gt;{(sum += n) })
    return sum / sum_
}</code></pre>
<hr>
]]></description>
        </item>
        <item>
            <title><![CDATA[2022-05-11]]></title>
            <link>https://velog.io/@bo-oram/2022-05-11</link>
            <guid>https://velog.io/@bo-oram/2022-05-11</guid>
            <pubDate>Wed, 11 May 2022 02:47:26 GMT</pubDate>
            <description><![CDATA[<p>회원가입 버튼을 누르면 </p>
<p>1.아이디 중복확인은 했는지 
2.비밀번호가 정해진 규칙과 맞는지
3.비밀번호1과 비밀번호2가 동일한지</p>
<p>를 확인하고 모두 충족한다면</p>
<p>1.회원가입 완료 alert 출력
2.db에 입력값 저장
3.로그인창으로 이동</p>
<p>을 해준다</p>
<blockquote>
<pre><code class="language-html"></code></pre>
</blockquote>
<!--html-->
<p><button class="level-item button is-sparta" onclick="sign_up()" >회원가입</button></p>
<!--클릭 시 sign_up() 실행-->
<pre><code>
&gt; ```javascript
//js
function sign_up() {
//
            let username = $(&quot;#id&quot;).val()
            let password = $(&quot;#pw&quot;).val()
            let password2 = $(&quot;#pw2&quot;).val()
            //#id에 입력받은 값을 username에 넣어 사용할꺼야
            //#pw에 입력받은 값을 password 넣어 사용할꺼야
            //#pw2에 입력받은 값을 password2 넣어 사용할꺼야
            //아래부터 중복확인 했는지 판단하기
            if ($(&quot;#help-id&quot;).hasClass(&quot;is-danger&quot;)) {
            //#help-id&quot;에서 .is-danger값을 찾아봐 있니? 있다면
                alert(&quot;아이디를 다시 확인해주세요.&quot;)
                //&quot;아이디확인해&quot;란 alert 출력
                return;
            } else if (!$(&quot;#help-id&quot;).hasClass(&quot;is-success&quot;)) {
            //.is-danger값은 없었구나 그런데 혹시 .is-success도 없니?
                alert(&quot;아이디 중복확인을 해주세요.&quot;)
                //그럼 너 중복확인 버튼 안누른거니까 다시누르고 와
                return;
            }
            if (password == &quot;&quot;) {
            //만약 password에 담아온 pw값이 비어있는다면
                $(&quot;#help-password&quot;).text(&quot;비밀번호를 입력해주세요.&quot;).removeClass(&quot;is-safe&quot;).addClass(&quot;is-danger&quot;)
                //#help-password의 내용을 &quot;비밀번호 입력해&quot;란 내용으로 넣어서 알려줘
                //.is-safe를 빼주고
                //.is-danger를 넣어줘
                $(&quot;#pw&quot;).focus()
                return;
            } else if (!is_password(password)) {
            //비어있지는 않은데 is_password란 이름으로 정해둔 규칙 내용에 맞지 않는다면
                $(&quot;#help-password&quot;).text(&quot;비밀번호의 형식을 확인해주세요. 영문과 숫자 필수 포함, 특수문자(!@#$%^&amp;*) 사용가능 8-20자&quot;).removeClass(&quot;is-safe&quot;).addClass(&quot;is-danger&quot;)
                //위처럼 내용을 바꾸어 알려줘
                $(&quot;#pw&quot;).focus()
                return
            } else {
            //그렇지 않다면(비어있지도 않고 들어온 값이 규칙에도 맞아 떨어진다면)
                $(&quot;#help-password&quot;).text(&quot;사용할 수 있는 비밀번호입니다.&quot;).removeClass(&quot;is-danger&quot;).addClass(&quot;is-success&quot;)
                //#help-password내용을 바꾸어 유저에게 사용가능함을 알려주고 
                //.is-success를 넣어서 컴퓨터에도 알려주자
            }
            //비밀번호는 중요하니까 한번 더 입력해서 확인해야겠지??
            if (password2 == &quot;&quot;) {
            //비밀번호 확인창이 비어있다면 아래와 같이            
                $(&quot;#help-password2&quot;).text(&quot;비밀번호를 입력해주세요.&quot;).removeClass(&quot;is-safe&quot;).addClass(&quot;is-danger&quot;)
                $(&quot;#pw2&quot;).focus()
                return;
            } else if (password2 != password) {
            //비밀번호 확인창이 비어있진 않지만 비밀번호란에 입력한 값과 동일하지 않다면 아래와 같이
                $(&quot;#help-password2&quot;).text(&quot;비밀번호가 일치하지 않습니다.&quot;).removeClass(&quot;is-safe&quot;).addClass(&quot;is-danger&quot;)
                $(&quot;#pw2&quot;).focus()
                return;
            } else {
            //그렇지 않다면 (비어있지 않고, 비밀번호란과 비밀번호확인란에 다른 값이 들어있지 않다면)
                $(&quot;#help-password2&quot;).text(&quot;비밀번호가 일치합니다.&quot;).removeClass(&quot;is-danger&quot;).addClass(&quot;is-success&quot;)
                //#help-password2에 내용을 바꾸어 알려주고 여기에도 .is-seccess를 넣어 컴도 알게하자
            }
            //자 위를 다 통과했니? 그럼 서버에 입력값을 저장해달라고 요청할게
            $.ajax({
                type: &quot;POST&quot;,
                url: &quot;/sign_up/save&quot;,
                data: {
                    username_give: username,
                    password_give: password
                    //서버야 username은 username_give에 담고
                    //password는 password_give에 담아서 넘겨줄게
                },
                success: function (response) {
                //서버야 일다했구나
                    alert(&quot;회원가입을 축하드립니다!&quot;)
                    // 그럼 유저한테 다됐다고 alert창으로 알려줄게
                    window.location.replace(&quot;/login&quot;)
                    // 그리고 로그인창으로 이동할게
                }
            });
        }</code></pre><blockquote>
<pre><code class="language-python">#python
@app.route(&#39;/sign_up/save&#39;, methods=[&#39;POST&#39;])
def sign_up():
    username_receive = request.form[&#39;username_give&#39;]
    #받아온 username_give를 username_receive에 담아서 사용할게
    password_receive = request.form[&#39;password_give&#39;]
    #받아온 password_give를 password_receive에 담아서 사용할게
    password_hash = hashlib.sha256(password_receive.encode(&#39;utf-8&#39;)).hexdigest()
    #비밀번호는 누가 추적하면 안되니까 해시함수로 암호화해서 password_hash에 담아서 사용할게
    doc = {
    #방을 하나 만들어서 아래내용으로 정리할게
        &quot;username&quot;: username_receive,                               # 아이디
        &quot;password&quot;: password_hash,                                  # 비밀번호
    }
    db.users.insert_one(doc)
    #우리서버에 그방을 저장해줄게
    return jsonify({&#39;result&#39;: &#39;success&#39;})
    #서버에서 할 일이 완료됨을 success담아 클라이언트에 전달함</code></pre>
</blockquote>
<pre><code>
[아이디확인하는 부분으로 이동하기](https://velog.io/@bo-oram/2022-05-10)</code></pre>]]></description>
        </item>
    </channel>
</rss>