<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>oh_ji_0.log</title>
        <link>https://velog.io/</link>
        <description>기본에 충실하고 싶습니다. #Front-end-developer</description>
        <lastBuildDate>Tue, 27 Dec 2022 13:33:40 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>oh_ji_0.log</title>
            <url>https://images.velog.io/images/oh_ji_0/profile/53415c03-4470-41f2-9113-4362a6633498/KakaoTalk_20200522_231914712_06.jpg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. oh_ji_0.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/oh_ji_0" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[패스트캠퍼스] iOS 개발 강의 학습일지 _4주차]]></title>
            <link>https://velog.io/@oh_ji_0/%ED%8C%A8%EC%8A%A4%ED%8A%B8%EC%BA%A0%ED%8D%BC%EC%8A%A4-iOS-%EA%B0%9C%EB%B0%9C-%EA%B0%95%EC%9D%98-%ED%95%99%EC%8A%B5%EC%9D%BC%EC%A7%80-4%EC%A3%BC%EC%B0%A8</link>
            <guid>https://velog.io/@oh_ji_0/%ED%8C%A8%EC%8A%A4%ED%8A%B8%EC%BA%A0%ED%8D%BC%EC%8A%A4-iOS-%EA%B0%9C%EB%B0%9C-%EA%B0%95%EC%9D%98-%ED%95%99%EC%8A%B5%EC%9D%BC%EC%A7%80-4%EC%A3%BC%EC%B0%A8</guid>
            <pubDate>Tue, 27 Dec 2022 13:33:40 GMT</pubDate>
            <description><![CDATA[<h3 id="폴더구조">폴더구조</h3>
<ul>
<li>android</li>
<li>ios</li>
<li>lib<ul>
<li>주 프로젝트 작업 공간.</li>
</ul>
</li>
<li>pubspec.yaml<ul>
<li>프로젝트 설정 공간.</li>
</ul>
</li>
<li>analysis_options.yaml<ul>
<li>linter 설정.</li>
</ul>
</li>
</ul>
<h3 id="위젯">위젯</h3>
<ul>
<li><p>android/app/build.gradie</p>
<ul>
<li>애플리케이션 이름 작성</li>
</ul>
</li>
<li><p>widget</p>
<ul>
<li>Scaffold<ul>
<li>body</li>
</ul>
</li>
<li>appBar</li>
<li>Text</li>
</ul>
</li>
<li><p>StatelessWidget</p>
<ul>
<li>build</li>
</ul>
</li>
<li><p>public 위젯과 private 위젯</p>
<ul>
<li>_로 시작하는 private 위젯은 같은 파일 내에서만 호출할 수 있다.</li>
</ul>
</li>
<li><p>단일 박스 (컨테이너) 위젯 작성.</p>
<ul>
<li>레이아웃을 위한<ul>
<li>Container<ul>
<li>width, height</li>
<li>padding<ul>
<li>EdgeInsets.all()</li>
<li>EdgeInsets.symmetric()</li>
</ul>
</li>
</ul>
</li>
<li>SizedBox</li>
<li>Center</li>
</ul>
</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[패스트캠퍼스] iOS 개발 강의 학습일지 _3주차]]></title>
            <link>https://velog.io/@oh_ji_0/%ED%8C%A8%EC%8A%A4%ED%8A%B8%EC%BA%A0%ED%8D%BC%EC%8A%A4-iOS-%EA%B0%9C%EB%B0%9C-%EA%B0%95%EC%9D%98-%ED%95%99%EC%8A%B5%EC%9D%BC%EC%A7%80-3%EC%A3%BC%EC%B0%A8</link>
            <guid>https://velog.io/@oh_ji_0/%ED%8C%A8%EC%8A%A4%ED%8A%B8%EC%BA%A0%ED%8D%BC%EC%8A%A4-iOS-%EA%B0%9C%EB%B0%9C-%EA%B0%95%EC%9D%98-%ED%95%99%EC%8A%B5%EC%9D%BC%EC%A7%80-3%EC%A3%BC%EC%B0%A8</guid>
            <pubDate>Tue, 20 Dec 2022 14:40:39 GMT</pubDate>
            <description><![CDATA[<p>1) 외부 패키지 사용
2) 실제 앱 만들기</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[패스트캠퍼스] iOS 개발 강의 학습일지 _2주차]]></title>
            <link>https://velog.io/@oh_ji_0/%ED%8C%A8%EC%8A%A4%ED%8A%B8%EC%BA%A0%ED%8D%BC%EC%8A%A4-iOS-%EA%B0%9C%EB%B0%9C-%EA%B0%95%EC%9D%98-%ED%95%99%EC%8A%B5%EC%9D%BC%EC%A7%80-2%EC%A3%BC%EC%B0%A8</link>
            <guid>https://velog.io/@oh_ji_0/%ED%8C%A8%EC%8A%A4%ED%8A%B8%EC%BA%A0%ED%8D%BC%EC%8A%A4-iOS-%EA%B0%9C%EB%B0%9C-%EA%B0%95%EC%9D%98-%ED%95%99%EC%8A%B5%EC%9D%BC%EC%A7%80-2%EC%A3%BC%EC%B0%A8</guid>
            <pubDate>Mon, 12 Dec 2022 11:00:50 GMT</pubDate>
            <description><![CDATA[<h2 id="학습일지">학습일지</h2>
<p>1) Dart.</p>
<ul>
<li><p>Dart 연습 환경 세팅</p>
<ul>
<li><a href="https://dartpad.dev/">https://dartpad.dev/</a></li>
</ul>
</li>
<li><p>선언법</p>
</li>
<li><p>변수 타입</p>
<ul>
<li>String</li>
<li>int (정수)</li>
<li>double (실수)<ul>
<li>double height = 170.3;</li>
</ul>
</li>
<li>bool</li>
</ul>
</li>
<li><p>list</p>
<ul>
<li>.add()</li>
<li>addAll()</li>
<li>generic &lt;&gt;<ul>
<li>List<String> stringList = <String>[];</li>
</ul>
</li>
<li>중복된 값을 허용한다. 인덱스로 접근이 가능하다.</li>
<li>.contains()<ul>
<li>bool 반환.</li>
</ul>
</li>
<li>.last()</li>
<li>.first()</li>
<li>.remove()<ul>
<li>값을 삭제한다.</li>
</ul>
</li>
</ul>
</li>
<li><p>Set</p>
<ul>
<li>Set<String> set = {};</li>
<li>set.add(”a”);</li>
<li>순서 보장 안되는 열거 타입, set은 리스트보다 접근, 사용시 빠르다.</li>
<li>인덱스 접근이 불가능하다.</li>
<li>중복을 허용하지 않는다</li>
</ul>
</li>
<li><p>Map</p>
<ul>
<li>Map&lt;dynamic, String&gt; map = {};</li>
<li>key값은 unique 해야한다.</li>
<li>key값에 변수를 넣을 수 있다.</li>
<li>key 값에 number, 문자열 과 같이 타입이 다른 경우 다른 key값으로 인식한다.</li>
<li>.remove()<ul>
<li>key값 삭제</li>
</ul>
</li>
<li>.keys</li>
<li>.keys.toList()</li>
<li>.toSet()</li>
<li>.clear()</li>
<li>.containsKey()</li>
</ul>
</li>
<li><p>var</p>
<ul>
<li>타입 추론가능한 타입</li>
<li>타입추론이 아닌 타입을 명시 권장.</li>
<li>var 보단 타입을 명시하는 것을 권장한다.</li>
</ul>
</li>
<li><p>String?</p>
<ul>
<li>nullable : null 값 허용.<ul>
<li>반대: non-nullable: null 값이 허용되지 않음.</li>
</ul>
</li>
</ul>
</li>
<li><p>final</p>
<ul>
<li>상수 데이터.</li>
<li>변하지 않는 데이터.</li>
<li>final keyword + 변수 타입 + 변수명.<ul>
<li>ex. final String name = “이름”;</li>
</ul>
</li>
<li>const 도 final과 마찬가지로 사용한다.<ul>
<li>차이: final은 런타임에 값이 할당, const는 compile타임에 할당된다.</li>
</ul>
</li>
</ul>
</li>
<li><p>DateTime</p>
<ul>
<li>DateTime now = DateTime.now()</li>
<li>.now()</li>
</ul>
</li>
<li><p>Future.delayed</p>
<ul>
<li>Future.delayed(Duration(seconds: 30),(){})</li>
<li>const때는 컴파일할때 한번에 값을 할당하기때문에 1초 전과 1초 뒤 DateTIme.now()를 해도 같은 값으로 실행된다.</li>
</ul>
</li>
</ul>
<p>2) 앱 위젯</p>
<p>3) 추가 패키지</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[패스트캠퍼스] iOS 개발 강의 학습일지 _ 1주차]]></title>
            <link>https://velog.io/@oh_ji_0/%ED%8C%A8%EC%8A%A4%ED%8A%B8%EC%BA%A0%ED%8D%BC%EC%8A%A4-iOS-%EA%B0%9C%EB%B0%9C-%EA%B0%95%EC%9D%98-%ED%95%99%EC%8A%B5%EC%9D%BC%EC%A7%80</link>
            <guid>https://velog.io/@oh_ji_0/%ED%8C%A8%EC%8A%A4%ED%8A%B8%EC%BA%A0%ED%8D%BC%EC%8A%A4-iOS-%EA%B0%9C%EB%B0%9C-%EA%B0%95%EC%9D%98-%ED%95%99%EC%8A%B5%EC%9D%BC%EC%A7%80</guid>
            <pubDate>Tue, 06 Dec 2022 13:48:41 GMT</pubDate>
            <description><![CDATA[<h2 id="학습일지-시작">학습일지 시작</h2>
<p>패스트캠퍼스에서 ios 앱개발 강의를 시작했다. 내일배움카드로 하는 국비지원교육, 중에서도 K디지털기초역량훈련 과정을 통해서 해당 강의를 수강하기 시작했다.</p>
<h2 id="1주차-커리큘럼-소개">1주차 커리큘럼 소개</h2>
<ul>
<li>앱기획</li>
<li>플러터 소개 및 앱 개발 도구 (vscode, git)</li>
<li>개발언어 Dart 학습<ul>
<li>main(), print, 주석, 변수, Map, nullable 변수와 상수, 조건문, 반복문, 함수 선언 반환타입, 클래스, getter, setter, 접근제한자, 상속, super, override, 추상화.</li>
</ul>
</li>
</ul>
<h2 id="본격-학습일지">본격 학습일지</h2>
<p>1) 앱기획</p>
<ul>
<li><p>앱을 만드는데 필요한 기획.</p>
<ul>
<li>기획의 정의<ul>
<li>문제를 정의하고 정의한 문제를 해결해 나가는 것.</li>
</ul>
</li>
<li>기획의 절차<ul>
<li>목적 기반 기능 나열 → 화면 설계서 → 디자인 &amp; 개발</li>
</ul>
</li>
<li>좋은기획<ul>
<li>논리적 흐름이 끊기지 않는 기획</li>
<li>검증조건이 누락되지 않은 꼼꼼한 기획</li>
<li>빈틈없이 완벽한 기획.</li>
</ul>
</li>
</ul>
</li>
<li><p>서비스 만들때 중요한 6가지</p>
<ul>
<li>불편함에 집중하자 (예민함) / 페인포인트 찾아내자<ul>
<li>좋은 문제를 정의하는 것.</li>
</ul>
</li>
<li>많은 앱 서비스 경험.<ul>
<li>여러앱들이 같은 문제를 어떻게 풀었는지 관찰</li>
</ul>
</li>
<li>내가 첫번째 유저라고 생각하고 접근.<ul>
<li>핵심 타겟,  어디로 유입되고 어디서 만족을 느낄지를 생각.</li>
</ul>
</li>
<li>오프라인 행동도 관찰.</li>
<li>린하게 자주 내보내자<ul>
<li>서비스의 주기능에만 집중하여 작은 단위로 노출시킨다.</li>
<li>최소한의 리소스로 가설 검증 후 개선</li>
</ul>
</li>
<li>작은 문제에 집중하자</li>
</ul>
</li>
</ul>
<p>2) 앱개발 도구</p>
<ul>
<li>앱 개발 도구 관련은 이미 기존에 알고 있던 내용이므로, 학습 일지 작성 없이 최대한 너프하고 빠르게 수강했다.</li>
</ul>
<p>3) 플러터 설치 및 플러터 개발 환경 세팅</p>
<ul>
<li><p>플러터 설치</p>
<ul>
<li><p>x code 설치</p>
<pre><code class="language-jsx">$ sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer
$ sudo xcodebuild -runFirstLaunch

$ open -a Simulator</code></pre>
</li>
<li><p>안드로이드 설정</p>
<ul>
<li><a href="https://developer.android.com/studio">안드로이드 스튜디오 설치.</a><ul>
<li>설치후 more action &gt; SDK manager 에서 Android SDK &gt; Android SDK Command-line tools 설치.</li>
</ul>
</li>
</ul>
</li>
<li><p>flutter doctor 실행, 설치 확인.</p>
<ul>
<li>cocoapods 설치</li>
</ul>
</li>
</ul>
</li>
<li><p>mac 미러링 화면 출력.</p>
<ul>
<li><p>안드로이드 실 기기를 통해서, 개발자 옵션을 설정해준 뒤 usb 디버깅을 켜준다.</p>
</li>
<li><p>flutter에 select device 목록에 실 기기가 뜨는 것을 확인할 수 있다.</p>
<pre><code class="language-jsx">brew install scrcpy
brew install --cask android-platform-tools
scrcpy</code></pre>
</li>
</ul>
</li>
</ul>
<ul>
<li>안내대로 설치했으나 아이폰 버전 이슈로 (unsupported os) 실기기로 디버깅 모드 진입은 일단 보류하기로 했다. (해당 이슈 해결 뒤 수정 예정)</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[next.js Link 태그를 사용하면 document.referrer가 작동이 안되는 이유]]></title>
            <link>https://velog.io/@oh_ji_0/next.js-Link-%ED%83%9C%EA%B7%B8%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%98%EB%A9%B4-document.referrer%EA%B0%80-%EC%9E%91%EB%8F%99%EC%9D%B4-%EC%95%88%EB%90%98%EB%8A%94-%EC%9D%B4%EC%9C%A0</link>
            <guid>https://velog.io/@oh_ji_0/next.js-Link-%ED%83%9C%EA%B7%B8%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%98%EB%A9%B4-document.referrer%EA%B0%80-%EC%9E%91%EB%8F%99%EC%9D%B4-%EC%95%88%EB%90%98%EB%8A%94-%EC%9D%B4%EC%9C%A0</guid>
            <pubDate>Sun, 20 Jun 2021 08:37:36 GMT</pubDate>
            <description><![CDATA[<p>작업을 하면서 document.referrer을 이용하여 뒤로 가기 버튼을 누를 때 우리 자사 사이트내로 이동하는 거면 이전 페이지로 이동을, 그게 아니라면 홈으로 돌아가는 로직을 사용하고 있었으나 이번에 개발하는 페이지들에서 이 로직이 예상한대로 작동하지 아니하고, 모두 홈으로 발견하는 버그가 발생됐다.</p>
<h3 id="이유">이유</h3>
<p>해당 원인을 서칭하던 중 아래 1) 기술 블로그 글을 발견하여 next/link 의 Link 태그 사용 시 document.referrer이 빈 문자열을 발생시킨 다는 사실을 알게 됐다.</p>
<p>Link 태그는 페이스북 픽셀 버튼 처리를 위해서 이번 태스크부터 적용하고 있었는데 사실 이 문제 말고도 동적 페이지 라우팅을 연결하는 부분 등 여러 군데에서 예상치 못한 버그를 발생시켜서 생각보다 작업시간을 잡아먹기도 했다. ( 시간에 쫓겨 작업하느라, 제대로 된 리서치를 하지 못하고 작업하다보니 Link 태그 연결로 인한 원인임을 파악하지 못했던 것이 아쉽다 )</p>
<p>태스크 끝내고 회고하며 주말에 다시금 Next.js Link 태그에 대해서 서칭하는 시간을 가졌다. 2) 기술 블로그 글은 그 중 Link 태그에 대해서 갖고 있던 고민에 대해 도움이 된 글이기에 같이 첨부한다.</p>
<p>참조: </p>
<p>1) <a href="https://www.grouparoo.com/blog/getting-previous-path-nextjs">Next.js 애플리케이션에서 이전 경로 가져 오기</a></p>
<p>2) <a href="https://uchanlee.dev/nextjs/Why-using-a-tag-in-nextjs-Link/">Next.js Link 태그안에 a tag를 안넣어도 왜 잘 작동될까?</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[비동기, 클로저]]></title>
            <link>https://velog.io/@oh_ji_0/%EB%B9%84%EB%8F%99%EA%B8%B0-%ED%81%B4%EB%A1%9C%EC%A0%80</link>
            <guid>https://velog.io/@oh_ji_0/%EB%B9%84%EB%8F%99%EA%B8%B0-%ED%81%B4%EB%A1%9C%EC%A0%80</guid>
            <pubDate>Tue, 01 Jun 2021 15:30:31 GMT</pubDate>
            <description><![CDATA[<p>코어 자바스크립트 : 핵심 개념과 동작 원리로 이해하는 자바스크립트 프로그래밍
( p. 136 / 213 )</p>
<h3 id="목표">목표</h3>
<ul>
<li>자바스크립트 코어 를 이해하기 위해 노력한다.</li>
<li>언어의 본질적 이해에 더 다가선다</li>
</ul>
<h2 id="요약">요약</h2>
<h3 id="비동기">비동기</h3>
<ul>
<li>cpu의 연산에 의해 즉시 처리가 가능한 대부분의 코드는 동기 코드</li>
<li>비동기 코드<ul>
<li>요청, 실행대기, 보류 등과 관련된 코드</li>
<li>사용자에 요청에의해 특정 시간이 경과되기까지 실행 보류</li>
<li>직접적인 사용자 개입 후에야 함수를 실행하도록 대기</li>
<li>웹브라우저 자체가 아닌 별도의 대상에 무언가를 요청하고 응답 받은 후 실행하는</li>
</ul>
</li>
<li>콜백함수 탈출<ul>
<li>Promise 활용법</li>
<li>ES6, Generator<ul>
<li>Generator 함수 실행 → Iterator 반환</li>
<li>Iterator는 next 라는 메서드를 가지고 있다.</li>
<li>yield에서 함수 실행을 멈추고, next 함수를 호출하면 멈췄던 부분부터 시작</li>
</ul>
</li>
<li>async/await<ul>
<li>await을 표기하는 것만으로 뒤의 내용을 Promise로 자동전환. 해당 내용이 resolve 된 후에야 다음으로 진행한다.</li>
</ul>
</li>
</ul>
</li>
<li>어떤 함수에 인자로 메서드를 전달하더라도 이는 결국 함수로서 실행된다.</li>
</ul>
<h3 id="클로저">클로저</h3>
<ul>
<li><p>A closure is the combination of a function and the lexical environment within which that function was declared</p>
<ul>
<li>lexical environment<ul>
<li>environmentRecord 와 outerEnvironmentReference에 의해 변수의 유효범위인 스코프가 결정된다.</li>
</ul>
</li>
<li>내부함수가 선언될 당시의 외부함수의 LexicalEnvironment와의 상호작용</li>
</ul>
</li>
<li><p>가비지 컬렉터의 동작 방식</p>
<ul>
<li>어떤 값을 참조하는 변수가 하나라도 있다면 그 값은 수집 대상에 포함되지 않는다.</li>
</ul>
</li>
<li><p>외부 함수의 LexicalEnvironment가 가비지 컬렉팅 되지 않는 현상</p>
</li>
<li><p>return 없이도 클로저가 발생하는 다양한 경우</p>
<ul>
<li>setInterval/setTimeout</li>
<li>eventListener</li>
</ul>
</li>
<li><p>객체 지향과 함수형 모두를 아우르는 개념, 클로저</p>
</li>
<li><p>메모리 소모 특성</p>
</li>
<li><p>클로저의 관리방법</p>
<ul>
<li>참조 카운트를 0으로 만들어주기<ul>
<li>참조형이 아닌 기본형 데이터 (undefined / null) 할당</li>
</ul>
</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[210202_TIL]]></title>
            <link>https://velog.io/@oh_ji_0/210202TIL</link>
            <guid>https://velog.io/@oh_ji_0/210202TIL</guid>
            <pubDate>Tue, 02 Feb 2021 14:51:42 GMT</pubDate>
            <description><![CDATA[<p>@@ 오늘은 컨디션 난조로, 프로그래머스 1단계 문제를 풀어보면서 시간을 보냈다. 이머시브 코스까지 잘 따라가다가 코플릿 토이프로그램 후반부부터 프로젝트 시작하며 놓아버려서인지. 아니면 이것이 아직 나의 한계인지... 특히 2단계부터는 굉장히 어렵게 느껴졌다. (풀긴 풀지만 마지막 제출에서 모든 단계가 통과되지 않는 경우가 많았다) 1단계는 실력 테스트에서 통과를 했지만 좀 더 기본기를 다지기 위해 다시 1단계 모든 문제들을 풀어보고 정리하기로 했다.</p>
<h3 id="today-i-learned">TODAY I LEARNED</h3>
<blockquote>
<p>프로그래머스 알고리즘 문제 풀이</p>
</blockquote>
<ul>
<li>level 1,2 단계 문제들 풀이</li>
<li>최대 공약수</li>
<li>정규식 공부</li>
<li>기능 구현 문제</li>
</ul>
<h3 id="정규식">정규식</h3>
<ul>
<li>.replace(/[^\w-.]/g, &#39;&#39;)</li>
</ul>
<p><code>^</code>는 부정표현으로 사용
<code>\w</code> 문자(숫자, 영문, 언더바) 하나
<code>\d</code> 숫자 하나</p>
<p>문자 (숫자, 영문, 언더바)에 해당하는 
[\w] 문자(숫자,영문,언더바)를 포함하는 문자열.
[^\w-.] 숫자,영문,언더바,-,.가 아닌 문자열.</p>
<ul>
<li><p>.replace(/.{2,}/g, &#39;.&#39;)
abc{2,}    ab 그리고 2개 이상의 c 를 포함한 문자열과 매칭합니다
.{2,} 2개 이상의 .을 찾아서 .로 치환한다</p>
</li>
<li><p>.replace(/^.|.$/g, &#39;&#39;)</p>
</li>
</ul>
<p><code>\.$</code> .로 끝나는 문자열과 매칭
<code>^\.</code> .로 시작하는 문자열
<code>|</code> OR, 또는</p>
<h3 id="메소드">메소드</h3>
<ul>
<li>String.prototype.padEnd()
<code>str.padEnd(targetLength [, padString])</code>
현재 문자열에 다른 문자열을 채워, 주어진 길이를 만족하는 새로운 문자열을 반환</li>
</ul>
<h4 id="parameter">parameter</h4>
<p>targetLength 목표 문자열의 길이
padString 채워넣을 다른 문자열. 옵션 값이기에 넣지 않으면 &quot; &quot; 빈문자열을 집어넣는다.</p>
<h3 id="참고">참고</h3>
<p><a href="https://chrisjune-13837.medium.com/%EC%A0%95%EA%B7%9C%EC%8B%9D-%ED%8A%9C%ED%86%A0%EB%A6%AC%EC%96%BC-%EC%98%88%EC%A0%9C%EB%A5%BC-%ED%86%B5%ED%95%9C-cheatsheet-%EB%B2%88%EC%97%AD-61c3099cdca8">정규식 핵심</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[210125_TIL]]></title>
            <link>https://velog.io/@oh_ji_0/210125TIL</link>
            <guid>https://velog.io/@oh_ji_0/210125TIL</guid>
            <pubDate>Tue, 26 Jan 2021 04:21:12 GMT</pubDate>
            <description><![CDATA[<h2 id="websocket">WebSocket</h2>
<p>ws 프로토콜을 기반으로 클라이언트와 서버 사이에 지속적인 완전 양방향 연결 스트림을 만들어 주는 기술. 
실시간 양방향 통신을 위한 노력. </p>
<p>웹소켓 이전의 방식은 서버가 클라이언트로 전송해주는 Push의 방법이 아닌 클라이언트가 서버에 요청하는 polling 방식이었다. 
이에 대한 보안, 진화로 진정한 실시간 양방향 통신, 웹 소켓이 등장.</p>
<p>순수 웹환경에서 실시간 양방향 통신을 위한 스펙, 웹소켓(Web socket)
웹서버와 웹 브라우저가 지속적으로 연결된 TCP 라인을 통해 실시간으로 데이터를 주고 받을 수 있게 한다. (연결지향, 양방향, 전이중 통신)</p>
<h3 id="웹소켓이-필요한-경우">웹소켓이 필요한 경우</h3>
<p>실시간 양방향 데이터 통신
다량의 접속자 수용
TCP 기반의 통신으로의 확장
개발자 친화적 API 사용
클라우드 환경, SOA로 확장</p>
<h3 id="참고">참고</h3>
<p><a href="https://m.mkexdev.net/98">[HTML5] WEB SOCKET (웹 소켓)</a>
<a href="https://socket.io/docs/v3/index.html#What-Socket-IO-is">socket.io 공식문서</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL_210119]]></title>
            <link>https://velog.io/@oh_ji_0/TIL210119</link>
            <guid>https://velog.io/@oh_ji_0/TIL210119</guid>
            <pubDate>Tue, 19 Jan 2021 11:58:56 GMT</pubDate>
            <description><![CDATA[<h2 id="today-i-learned">TODAY I LEARNED</h2>
<blockquote>
<ul>
<li>로컬스토리지, 세션, 쿠키</li>
</ul>
</blockquote>
<ul>
<li><p>쿠키
HTTP 쿠키(웹 쿠키, 브라우저 쿠키)는 서버가 사용자의 웹 브라우저에 전송하는 작은 데이터 조각.서버와 클라이언트가 대화하기 위한 수단 (서버와 클라이언트 간의 지속적인 데이터 교환을 위해 만들어짐).
사용자가 사이트 접속시 서버가 사용자의 컴퓨너테 저장하는 키와 값이 들어있는 작은 파일을 의미한다.
서버에서 응답 헤더에 Set-Cookie 속성을 이용하여 제공.
쿠키 안에서도 세션 쿠키와 지속 쿠키로 나뉜다. (만료날짜와 시간을 지정하지 않으면 세션 쿠키, 브라우저가 종료되면 사라진다. 그러나, 크롬과 같은 브라우저 등에서는 브라우저를 종료해도 세션 쿠키가 남아있을 수 있다.)
지속 쿠키는 파일로 저장되어, 만료일까지 지속된다. 보안에 취약하다.</p>
</li>
<li><p>세션
서버에 클라이언트 상태 정보를 저장하는 기술, 논리적 연결.
서버와 클라이언트가 연결되어있는 상태, 세션 활성화가 시작되면 해당 클라이언트에 대해 유일한 아이디를 부여한다.(세션 아이디)
서버에 저장해야 할 로그인, 장바구니, 게임 스코어 등의 정보를 관리.
쿠키를 기반으로하나 브라우저에 저장하는 쿠키와 달리 세션은 서버측에서 관리한다.
세션 스토리지에 이 세션 id를 쿠키를 통해 기억한다.
쿠키에 세션 id를 담아 전송하면 서버는 세션 아이디와 세션 스토리지에 저장된 세션 아이디를 대조하여 인증 상태를 판단한다. 
세션 관리가 제대로 이뤄지지 않으면 세션 아이디 훔치기(패킷 스니핑), 세션 하이재킹 등이 일어날 수 있다.</p>
</li>
</ul>
<p>(로컬 스토리지와 세션 스토리지의 차이점, 데이터의 영구성)</p>
<ul>
<li>로컬 스토리지 (window.localStorage)
사용자가 지우지 않는 이상 브라우저에 계속 남아있다.</li>
<li>세션 스토리지 (window.sessionStorage)
윈도우나 브라우저 탭을 닫을 경우 제거된다.</li>
</ul>
<p>쿠키는 데이터의 낭비가 발생한다. 필요하지 않은 쿠키도 자동으로 요청을 할때마다 전송된다.
이 때 로컬 스토리지와 세션 스토리에 저장된 것은 서버로 자동 전송되지 않기 때문에 활용할 수 있다.</p>
<p>스토리지는 모두 window 객체 안에 들어있으며, 도메인 별 (동일한 프로토콜, 호스트, 포트) 용량 제한도 있다.</p>
<p>*참고글
<a href="https://www.zerocho.com/category/HTML&amp;DOM/post/5918515b1ed39f00182d3048">제로초 블로그, 로컬스토리지, 세션스토리지</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL_200107]]></title>
            <link>https://velog.io/@oh_ji_0/TIL200107</link>
            <guid>https://velog.io/@oh_ji_0/TIL200107</guid>
            <pubDate>Fri, 08 Jan 2021 04:41:11 GMT</pubDate>
            <description><![CDATA[<h2 id="today-i-learned">Today I learned</h2>
<blockquote>
<ul>
<li>프로그래머스 알고리즘: 다른사람의 풀이</li>
</ul>
</blockquote>
<ul>
<li>첫번째 프로젝트 리팩토링 (react, express)</li>
</ul>
<h3 id="알고리즘">알고리즘</h3>
<pre><code class="language-js">
//슈도코드
//각 패턴을 배열로 만들어
//answers 값 같은 점수일때 점수를 하나씩 올린다.
//result에서 가장 점수가 높은 사람을 배열로 선정하여 내보낸다.

function solution(answers) {

    const pattern = [
        [1, 2, 3, 4, 5],
        [2, 1, 2, 3, 2, 4, 2, 5],
        [3, 3, 1, 1, 2, 2, 4, 4, 5, 5]
    ]
    let score = [0,0,0];

    for(let k=0; k&lt;3; k++){
        for(let i=0; i&lt;answers.length; i++){
            if(pattern[k][i] === answers[i]){
                score[k]++;
            }
            pattern[k].push(pattern[k][i]);
        }
    }

    let maxNum = 0;
    let answer = score.reduce((a,c,i)=&gt;{
        if(c&gt;maxNum){
            maxNum = c;
            a = [i+1];
        }else if(c === maxNum){
            a.push(i+1);
        }
        return a;
    },[])

    return answer;
}</code></pre>
<p>약간은 복잡하게 풀었다. 한번 검사할때마다 패턴 배열에 하나씩 숫자를 넣어서 answers의 길이가 패턴보다 길 때를 대비하고, score 배열에 숫자를 하나씩 플러스해준다. score 배열로 maxNum값에 값을 반영해주면서 maxNum보다 클때 answer 배열을 해당 currentValue로 리셋을 해주고 값이 그냥 같다면 answer 배열에 푸쉬를 해주도록 설정했다.</p>
<p>다른 사람의 풀이를 확인하니 filter 등과 max()값을 통해 좀 더 간단하게 풀 수도 있었을 것 같은데 너무 복잡하게 푼 것이 아쉽다. 고차함수를 활용하여 좀더 직관적으로 푸는 방법을 고민해봐야 겠다.</p>
<h3 id="첫번째-프로젝트-리팩토링">첫번째 프로젝트 리팩토링</h3>
<ul>
<li>리덕스에 액션함수 및 리듀서를 싹 갈아엎었다. 프로젝트 진행하면서 시간에 쫓겨서 투두리스트에 대한 데이터를 여기저기 덕지덕지 붙여놨더니 관리하기도 힘들고 비효율적으로 해당 값들을 업데이트해줘야해서 힘들었는데 끝나고보니 이게 왜 이렇게 됐을까 싶은 생각이 들어서 그냥 todo 전체 데이터 값을 날려주고 project 리듀서에서 투두리스트를 원소스로 관리하면서 뿌려주도록 바꿔줬다. 이렇게하니까 리덕스에 지저분한 데이터들이 많이 사라져서 보기 편해서 좋다.</li>
</ul>
<p><img src="https://images.velog.io/images/oh_ji_0/post/28d31266-e580-46b6-9a4a-f89403b0ece3/image.png" alt=""></p>
<ul>
<li>다만 코드 리팩토링하다가 맞닥뜨린 문제는 리덕스에 dispatch 를 통해서 값을 업데이트해줘도 컴포넌트에서 리렌더링이되지 않아서 체크박스가 체크 및 해제가 되지 않는 문제가 발생했다. 분명 mapStateToProps로 props연결을 해주어서 당연히 렌더링이 자동적으로 잘 일어날 것이라고 예측을 했는데... 여러가지 삽질하고 구글링해보면서 알아본 결과 내가 부모 컴포넌트에 mapStateToProps를 해주고 해당 값을 자식 컴포넌트에 props로 전달을 해줬는데 아마 이게 문제였던 것 같다. 리덕스값이 바뀌어도 자식 컴포넌트에선 해당 값에 대한 인식을 못하는? 문제가 발생하여서 <a href="https://github.com/uberVU/react-guide/issues/17">스택오버플로우</a>와 <a href="https://www.freecodecamp.org/news/re-render-react-component-when-its-props-changes/">블로깅글</a>을 참고하여 자식 컴포넌트에서 props값을 state로 마운트 때와 업데이트때 각각 setState해주는 방식으로 해줬더니 리렌더링이 정상적으로 잘 이뤄졌다. 결론은 부모가 보내준 props가 변경된다고 해서 자식 컴포넌트가 자동적으로 리렌더링을 진행하지 않는다는 것이다. 이는 리액트 <a href="https://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/">라이프사이클</a>을 참고해보면 더 명확하게 알 수 있다. props가 새로 전달되거나 할때는 업데이트가 일어나지만 그 이후 변경에 대해서는 자동적으로 리렌더링이 일어나지 않기 때문에 이럴 경우엔 자식 컴포넌트에서 mapStateToProps를 이용하거나 forceUpdate(), 혹은 setState를 통해서 리렌더링 조건을 맞춰줘야 한다. </li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL_200106]]></title>
            <link>https://velog.io/@oh_ji_0/TIL200106</link>
            <guid>https://velog.io/@oh_ji_0/TIL200106</guid>
            <pubDate>Wed, 06 Jan 2021 13:12:05 GMT</pubDate>
            <description><![CDATA[<h2 id="today-i-learned">Today I learned</h2>
<blockquote>
<ul>
<li>알고리즘 문제 : 프로그래머스 #크레인 인형뽑기 게임</li>
</ul>
</blockquote>
<ul>
<li>퍼스트 프로젝트 잔디, 서버 배포 및 코드 리팩토링 (기능 위주)</li>
</ul>
<h3 id="알고리즘">알고리즘</h3>
<ul>
<li>javascript, level1 -&gt; [<a href="https://programmers.co.kr/learn/courses/30/lessons/64061">해당 문제</a>]</li>
</ul>
<pre><code class="language-js">
//슈도코드
//moves의 배열 열을 돌아다니면서 0이 아닐때까지 찾는다.
//0이 아니면 arr에다가 push 로 열의 숫자를 넣어준다.
//이때 숫자가 연속으로 중복되면 넣지 말고, answer를 += 2 해준다

function solution(board, moves) {
  let answer = 0;
  let arr = [];

  for(let i=0; i &lt; moves.length; i++){
      moves[i] //ex) 1, 1-1=&gt; 0,0 , 1,0, 2, 0)
      for(let k=0; k&lt;board.length; k++){
          if(board[k][moves[i]-1] === 0){
              continue;
          }else{
            //arr의 마지막 숫자와 현재 넣을 인형이 같은 인형이라면
              if(arr.length&gt;0 &amp;&amp; arr[arr.length-1] !== board[k][moves[i]-1] ){
                  arr.push(board[k][moves[i]-1]);
              }else if(arr.length&gt;0 &amp;&amp; arr[arr.length-1] === board[k][moves[i]-1]){
                  arr.pop();
                  answer +=2;
              }else{
                arr.push(board[k][moves[i]-1]);
              }
              board[k][moves[i]-1] = 0;
              break;
          }
      }
  }
  return answer;
}</code></pre>
<h3 id="첫번째-프로젝트-리팩토링">첫번째 프로젝트 리팩토링</h3>
<p>우선 첫번째 했던 프로젝트인 잔디 사이트 배포를 개인 나스 서버를 통해 띄웠다. 첫번째 문제는 쿠키 및 세션부터 기능적인 문제가 많아서 깔끔하게 끝내지를 못했던 프로젝트였기 때문에 서버부터 리팩토링하면서 기능 위주로 구동이 되도록 만져줄 필요가 있었다.</p>
<p>일단은 로그인 기능이 정상적으로 되지 않아 jwt를 통한 세션 쿠키를 만들어서 클라이언트에 쿠키를 심어줬다. (현재 배포서버 말고 로컬에서 테스트를 거치며 구동을 확인하고 서버에 반영 작업을 해주고 있다.)</p>
<p>우선 어제는 클라이언트와 서버 /login , /signup 부분에서 athorization 쿠키 생성 작업을 끝냈고, /main 에서 날짜별 todolists들을 받아오는 작업을 진행했다. 날짜별로 투두리스트를 객체 형태로 뿌려주는 곳에서 에러 발생으로 정상적으로 작동하지 않아서 해당 문제를 오늘 수정했다. 
유저가 보기 편하도록 스크롤을 오른쪽으로 고정해두는 작업도 진행했다.
내일은 마이페이지와 메뉴화면에 대한 수정 작업을 할 예정이다.
요기까지 마치면, 배포 url 공개하고 포폴에 넣어둬야겠다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL_201229]]></title>
            <link>https://velog.io/@oh_ji_0/TIL201229</link>
            <guid>https://velog.io/@oh_ji_0/TIL201229</guid>
            <pubDate>Tue, 29 Dec 2020 11:36:28 GMT</pubDate>
            <description><![CDATA[<p>#Toy_1번 문항. rockPaperScissors
모든 경우의 수 중 바위,보,가위의 순으로 가중치 적용 정렬 (Weighted Sort)을 적용하여 해당 배열을 반환하는 문제
나는 해당 알고리즘이 가지는 패턴을</p>
<pre><code>let limit= 3 **함께 가위바위보하는 사람 수 -1</code></pre><p>으로 설정하여, 첫 번째 사람은 limit마다 한번씩바위,보,가위가 순차적으로 돌아가고 그 다음 사람은 limit/3 에 한번씩 바위,보,가위가 돌아가는 방식 또 그 다음은 limit/3/3 이 되는 방식으로 이해했다.</p>
<p>해당 패턴을 적용하려다보니까 코드가 상당부분 길어지게 됐는데 레퍼런스 코드를 적용하여 살펴보니 이것을 재귀함수를 통해서 풀면 비교적 더 짧게 간단하게 풀 수 있다는 사실을 알았다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[@@ 코드스테이츠 파이널 프로젝트 회고글]]></title>
            <link>https://velog.io/@oh_ji_0/%EC%BD%94%EB%93%9C%EC%8A%A4%ED%85%8C%EC%9D%B4%EC%B8%A0-%ED%8C%8C%EC%9D%B4%EB%84%90-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%ED%9A%8C%EA%B3%A0%EA%B8%80</link>
            <guid>https://velog.io/@oh_ji_0/%EC%BD%94%EB%93%9C%EC%8A%A4%ED%85%8C%EC%9D%B4%EC%B8%A0-%ED%8C%8C%EC%9D%B4%EB%84%90-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%ED%9A%8C%EA%B3%A0%EA%B8%80</guid>
            <pubDate>Tue, 29 Dec 2020 07:44:47 GMT</pubDate>
            <description><![CDATA[<p>영원히 안 갈 것만 같았던 4주의 시간이 정말 빠르게 지나갔다. 정말 힘든 순간도 있었고, 체력이 따라주지 않아서 괴로운 순간도 많았다. 커뮤니케이션 가운데 마음 상했던 적도 있어서 감정적으로 괴로운 적도 있었지만 무사히 프로젝트가 지나가고 원만하게 마무리 할 수 있음에 다행이라는 생각이 든다.</p>
<p>중간 회고글에 남겼었지만, 중반부까지는 API 문서로서의 커뮤니케이션의 어려움을 겪었고 서로의 일하는 방식을 맞춰나가는 과정, 기획에 대한 이견 차이를 서로 풀어나가는 과정이 어려웠던 것 같고 그 산들을 넘으니 중, 후반 부터는 비교적 원만하고 더 빠르게 작업이 이뤄지기 시작했다.</p>
<p>후반부까지 모두 마친 지금, 비로소 이 프로젝트를 돌아보며 나는 무엇이 부족했고, 또 어떤 교훈을 얻었는가 돌아보고자 한다.</p>
<h3 id="나의-부족했던-점-커뮤니케이션-스킬과-보완책">나의 부족했던 점, 커뮤니케이션 스킬과 보완책</h3>
<p>역시 커뮤니케이션 스킬이다. 어떤 지점에 대해서 전달하고 설명할 때 나는 핵심 키워드를 잡는 것이 스스로 힘들다는 판단이 들었다. 이것은 나의 언어적 습관인 것 같은데 직설적으로 말하지 않고 돌려 말하다 버릇하니까 아무래도 명확하게 전달해야할 부분도 설명하는데 길어지게 되고, 여러번 설명을 해야 뜻이 전달되는 것 같았다. </p>
<p>이 부분은 보완하기 위해 중,후반 부터는 문서를 많이 활용했다. 구글 독스를 이용해서 수정이 필요한 지점은 스크린 캡쳐 이미지와 함께 첨부한다든지 비교적 짧게 전달하기 위해 노력했다. </p>
<p>스스로 노력한 지점은 이와 같았지만 스스로 개인의 필요성을 느끼고 시행했던 탓에 다른 팀원들도 나와 같이 편리하다고 느꼈는지, 꼭 필요하다 느꼈는지는 확신하지 못하겠다. </p>
<p>다만, 스스로는 앞으로 해야하는 태스크들을 정리해나갈 때 많은 도움이 되었다. 어떤 것들이 해결이 되고, 앞으로 무엇에 집중을 해야하는지 문서화하기 시작했더니 일정 관리도 쉬워지고 누락된 전달 사항들을 체크하기 편리했다.</p>
<p><img src="https://images.velog.io/images/oh_ji_0/post/61f270cd-c6f3-42dc-8aca-550de60f4f78/image.png" alt=""> <p style="text-align:center; font-size:0.8rem;">(구글 문서 정리 예시)</p></p>
<h3 id="프로젝트에서-아쉬웠던-점">프로젝트에서 아쉬웠던 점</h3>
<p>사실 여러 아쉬움이 남는다. 기술적으로는 많이 합의하고 간 내용이기 때문에 큰 아쉬움은 아니지만 다양한 기술 스택을 도전해보는 것도 의미있었을 것 같다는 선택하지 못한 것에 대한 작은 아쉬움이 남는다.</p>
<p>커뮤니케이션 및 회의 사항에 대해서는 초, 중반 문서화하지 못했기 때문에 일어난, 협의 사항이 중간 중간에 흔들려서 소비했던 시간들에 대한 아쉬움이 남는다. 그런 의견 충돌들을 줄여나갔다면 감정 소비 및 피로도도 좀 더 줄어들었을 것 같고 시간 절약도 더 잘 됐을 것 같다. </p>
<p>또한 진행 과정에서 벌어진 이견에 대해서 빠르게 정리가 되지 않을땐 계속 붙잡고있기 보단 서로 정리할 시간을 갖고, 자신의 의견을 뒷받침할 문서들 위주로 근거 위주로 회의가 진행돼야 한다. 우리는 실무 경험이 없는 모두 수료생들이었기 때문에 이 점이 더욱 필요했는데, 서로가 원하는 지향점과 방향이 (예를 들면 코드 습관, API 처리 방식) 너무 달랐는데, 사실 내가 맞다 누가 맞다 할 수 없는 지점들이 많았다. </p>
<p>이 때 자신의 방식만이 맞다고 고집하는 것은 누구라도 쉽게 팀원들의 동의를 얻지 못할 것이다. 검색 및 문서 검토를 토대로 어떤 어떤 방식이 존재하고 이 방식엔 어떤 장,단점이 있는지 사실 위주로 검토를 하고 보다 우리 프로젝트에 적합한 방식(문법 오류가 아닌 이상 100% 옳은 방식은 없다 생각한다)에 대한 판단을 내리는 것이 가장 옳다고 생각이 든다. 사실 이 점은 겪지 않더라도 누구나 알 수 있는 지점이지만, 막상 어떤 일에 몰두할 때 우리는 이 명료한 사실들을 쉽게 잊게 되는 것 같다. </p>
<h3 id="코드스테이츠를-수료하며">코드스테이츠를 수료하며</h3>
<p>5개월이 빠르게 지나갔다. 이제는 정말 파이널 프로젝트까지 2개의 프로젝트를 마무리하며 모든 코스가 끝이 났다. 짧다면 짧고 길다면 긴 반년이 약간 안되는 시간동안 나는 스스로 많이 성장했다고 느낀다.</p>
<p>가장 통감하는 순간은 카카오 개발자 오픈 챗방에서의 대화들이 예전엔 외계어 수준으로 들렸다면 지금은 정확하게는 몰라도 어떤 뉘앙스에서 어떤 스택 관련인지 정도는 이해할 수 있다는 것. 이럴 땐, 스스로 입문 개발자로서의 문턱에 다다른 기분이 들어 새삼 신기하다.</p>
<p>이젠 신입 개발자로서 시작하기 위해 취업시장에 나서야 하는데, 나는 아직도 부족한 점이 너무 많다. 신입 개발자로서의 역량은 어느정도 갖춰야 할까 생각해보면 회사별로 원하는 그 기준치가 너무 달라서 정확한 기준이라는 것을 설정할 수 없을테지만 프로젝트를 경험하며 느낀 부족한 점을 다지며, 내실을 다져서 꼭 나와 Fit이 맞는 회사에서, 성장 가능성이 높은 개발자로서 회사와 함께 성장해나가고 싶다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[파이널 프로젝트 [오다맨] Web view]]></title>
            <link>https://velog.io/@oh_ji_0/%ED%8C%8C%EC%9D%B4%EB%84%90-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EC%98%A4%EB%8B%A4%EB%A7%A8-Web-view</link>
            <guid>https://velog.io/@oh_ji_0/%ED%8C%8C%EC%9D%B4%EB%84%90-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EC%98%A4%EB%8B%A4%EB%A7%A8-Web-view</guid>
            <pubDate>Mon, 28 Dec 2020 12:58:44 GMT</pubDate>
            <description><![CDATA[<p>@@ 우여 곡절 끝에 마무리 된 파이널 프로젝트 오다맨의 실제 웹 구동 gif를 정리해서 올리고자 한다.
프로젝트 관련 github 클라이언트 레포지토리는 [이곳] (<a href="https://github.com/codestates/OrderMan_client)%EC%97%90%EC%84%9C">https://github.com/codestates/OrderMan_client)에서</a> 참고 가능하다.</p>
<p>렌더링 프레임을 너무 짧게 잡은 점과 여러 기종으로 gif를 모은 탓에 사이즈 및 해상도, 
구동 모습이 매끄럽진 않다. 이 점은 양해를 부탁 드림.</p>
<h3 id="비회원-주문">비회원 주문</h3>
<p><img src="https://enwlen.synology.me/images/finalProject/webView/%EB%B9%84%ED%9A%8C%EC%9B%90%EC%A3%BC%EB%AC%B8.gif" alt=""></p>
<h3 id="오늘의-주문담기">오늘의 주문담기</h3>
<p><img src="https://enwlen.synology.me/images/finalProject/webView/%EC%98%A4%EB%8A%98%EC%9D%98%EC%A3%BC%EB%AC%B8%EB%8B%B4%EA%B8%B0.gif" alt=""></p>
<h3 id="주문내역">주문내역</h3>
<p><img src="https://enwlen.synology.me/images/finalProject/webView/%EC%A3%BC%EB%AC%B8%EB%82%B4%EC%97%AD.gif" alt=""></p>
<h3 id="소셜-로그인">소셜 로그인</h3>
<p><img src="https://enwlen.synology.me/images/finalProject/webView/%EC%86%8C%EC%85%9C%EB%A1%9C%EA%B7%B8%EC%9D%B8.gif" alt=""></p>
<h3 id="회원정보-수정">회원정보 수정</h3>
<p><img src="https://enwlen.synology.me/images/finalProject/webView/%ED%9A%8C%EC%9B%90%EC%A0%95%EB%B3%B4%EC%88%98%EC%A0%95.gif" alt=""></p>
<h3 id="비밀번호-수정">비밀번호 수정</h3>
<p><img src="https://enwlen.synology.me/images/finalProject/webView/%EB%B9%84%EB%B0%80%EB%B2%88%ED%98%B8%EC%88%98%EC%A0%95.gif" alt=""></p>
<h3 id="휴대폰-변경">휴대폰 변경</h3>
<p><img src="https://enwlen.synology.me/images/finalProject/webView/%ED%9C%B4%EB%8C%80%ED%8F%B0%EB%B3%80%EA%B2%BD.gif" alt=""></p>
<h3 id="관리자">관리자</h3>
<p><img src="https://enwlen.synology.me/images/finalProject/webView/%EA%B4%80%EB%A6%AC%EC%9E%90.gif" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[파이널 프로젝트 [오다맨] UI Design]]></title>
            <link>https://velog.io/@oh_ji_0/%ED%8C%8C%EC%9D%B4%EB%84%90-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EC%98%A4%EB%8B%A4%EB%A7%A8-UI-Design-Web-view</link>
            <guid>https://velog.io/@oh_ji_0/%ED%8C%8C%EC%9D%B4%EB%84%90-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EC%98%A4%EB%8B%A4%EB%A7%A8-UI-Design-Web-view</guid>
            <pubDate>Mon, 28 Dec 2020 12:38:04 GMT</pubDate>
            <description><![CDATA[<p>@@ 파이널 프로젝트 결과물을 토대로 정리한 UI 디자인 시안. 기본 컴포넌트를 완료한 뒤 자세한 디테일을 잡기 위해 Adobe XD를 이용하여 시안을 정리하고 그에 맞춰 프로젝트에 CSS를 잡아나갔다.</p>
<p>아무래도 퍼블리셔 출신이라 그런가 시안 없이 컴포넌트부터 잡아나가려니 좀 불안한 마음이 들기도 했던 게 사실이었다. </p>
<p>컴포넌트 잡을 때 CSS를 어떤식으로 그려나갈지 정해두고 잡아야 한다고 생각했기 때문에, 나중에가서 대대적으로 수정을 하게 돼야하지 않을까? 싶었다. </p>
<p>그래도 다행인 것은 모바일 환경이고, 타겟을 PC 웹까지 넓게 잡지 않았어서 CSS를 나중에 입힐 때 큰 문제나 어려움이 없이 진행됐다.
(초반 논의에서 아이패드 pro 까지 사이즈를 염두해두고, 더 넓은 pc 화면에서는 모바일 처럼 보이도록 처리하기로 했다)</p>
<p>Pc 사이즈까지 작성할수도 있었지만, 타겟 대상이 가게 사장님들이고 간편하게 모바일을 이용해 주문 넣는 서비스를 구상했던 것이기 때문에 반응형을 pc 웹까지 잡는 것은 과감히 제외시켰다. 간편하고 간단한 사용자 경험을 최대한 강조하며 기획 구상을 했기 때문이다.</p>
<h3 id="ui-디자인">UI 디자인</h3>
<h4 id="주문">[주문]</h4>
<details>
<summary><b>오늘의 주문</b></summary>  
<img src="https://images.velog.io/images/oh_ji_0/post/eacffc41-61f5-494e-a2dd-59bc034dd017/%EB%A9%94%EC%9D%B8%20-%20%EC%98%A4%EB%8A%98%EC%9D%98%20%EC%A3%BC%EB%AC%B8.png" alt="오늘의 주문"/>
<img src="https://images.velog.io/images/oh_ji_0/post/cf4ab10e-7e8a-44b1-9c3e-925ce30db5c3/%EB%A9%94%EC%9D%B8%20-%20%EC%98%A4%EB%8A%98%EC%9D%98%20%EC%A3%BC%EB%AC%B8%20(%EC%9E%90%EB%8F%99%EC%99%84%EC%84%B1).png" alt="오늘의 주문"/>
</details>

<details>
<summary><b>날짜별 주문 목록</b></summary>  
<img src="https://images.velog.io/images/oh_ji_0/post/cde84e36-3be2-4597-94ea-a32f9a46b68f/%EB%A9%94%EC%9D%B8.png" alt="날짜별 주문 목록"/>
</details>

<details>
<summary><b>비회원 주문 정보 입력</b></summary>  
<img src="https://images.velog.io/images/oh_ji_0/post/6d8c51c2-7e7c-47c7-80ae-9382ded6602c/%EB%B9%84%ED%9A%8C%EC%9B%90%20%EB%A1%9C%EA%B7%B8%EC%9D%B8.png" alt="비회원 주문 정보 입력"/>
</details>

<details>
<summary><b>주문 정보 입력</b></summary>  
<img src="https://images.velog.io/images/oh_ji_0/post/fcc4eda3-94e1-4c69-bfeb-f8fbfc68989a/%EC%A3%BC%EB%AC%B8%20%EC%98%B5%EC%85%98%20%EC%84%A4%EC%A0%95.png" alt="주문 정보 입력"/>
</details>

<details>
<summary><b>날짜 선택(캘린더)</b></summary>  
<img src="https://images.velog.io/images/oh_ji_0/post/9f9f474a-e2ca-454f-a4a9-26aea0fe64a9/%EC%A3%BC%EB%AC%B8%20%EB%8B%AC%EB%A0%A5%EC%BA%98%EB%A6%B0%EB%8D%94.png" alt="캘린더를 이용한 날짜 선택"/>
</details>

<h4 id="기타">[기타]</h4>
<details>
<summary><b>메뉴화면</b></summary>  
<img src="https://images.velog.io/images/oh_ji_0/post/e12fc53f-ad91-4f9c-9117-5e8013476af1/%EB%A1%9C%EA%B7%B8%EC%9D%B8%20%E2%80%93%201.png" alt="메뉴"/>
</details>

<details>
<summary><b>로그인</b></summary>  
<img src="https://images.velog.io/images/oh_ji_0/post/48aa81ad-a331-403a-ab2e-c1462c4fe8dd/%EB%A1%9C%EA%B7%B8%EC%9D%B8.png" alt="로그인"/>
</details>

<details>
<summary><b>회원가입</b></summary>  
<img src="https://images.velog.io/images/oh_ji_0/post/aca44901-c235-47d3-aef3-af2d465e6cdf/%ED%9A%8C%EC%9B%90%EA%B0%80%EC%9E%85.png" alt="회원가입"/>
</details>


<h4 id="마이페이지">[마이페이지]</h4>
<details>
<summary><b>마이페이지</b></summary>  
<img src="https://images.velog.io/images/oh_ji_0/post/6902ef84-b88c-420e-a246-7814f2a9a2ec/%EB%A7%88%EC%9D%B4%ED%8E%98%EC%9D%B4%EC%A7%80.png" alt="마이페이지"/>
</details>

<details>
<summary><b>구매내역</b></summary>  
<img src="https://images.velog.io/images/oh_ji_0/post/d2b23874-a97f-47be-b392-516616753417/%EC%A3%BC%EB%AC%B8%EB%82%B4%EC%97%AD.png" alt="구매내역"/>
</details>

<details>
<summary><b>회원정보 수정</b></summary>  
<img src="https://images.velog.io/images/oh_ji_0/post/815b76bc-f768-4db0-8067-744fd9598d9a/%ED%9A%8C%EC%9B%90%EC%A0%95%EB%B3%B4%20%EC%88%98%EC%A0%95.png" alt="회원정보 수정"/>
</details>

<details>
<summary><b>비밀번호 수정</b></summary>  
<img src="https://images.velog.io/images/oh_ji_0/post/46b8b727-0af5-4507-99ee-a73068bf7d61/%EB%B9%84%EB%B0%80%EB%B2%88%ED%98%B8%20%EC%88%98%EC%A0%95.png" alt="비밀번호 수정"/>
</details>

<details>
<summary><b>핸드폰 인증 변경</b></summary>  
<img src="https://images.velog.io/images/oh_ji_0/post/cc363314-f491-495d-bd76-2b396f4e440e/%EC%9D%B8%EC%A6%9D%ED%9C%B4%EB%8C%80%ED%8F%B0%20%EB%B3%80%EA%B2%BD.png" alt="핸드폰 인증 변경"/>
</details>




]]></description>
        </item>
        <item>
            <title><![CDATA[파이널 프로젝트 [오다맨] SR 정리]]></title>
            <link>https://velog.io/@oh_ji_0/%ED%8C%8C%EC%9D%B4%EB%84%90-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EC%98%A4%EB%8B%A4%EB%A7%A8-SR-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@oh_ji_0/%ED%8C%8C%EC%9D%B4%EB%84%90-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EC%98%A4%EB%8B%A4%EB%A7%A8-SR-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Mon, 28 Dec 2020 12:12:13 GMT</pubDate>
            <description><![CDATA[<p>@@ 프로젝트가 끝났다. 기획했지만 못 넣은 것들도 많고 했지만 그래도 테스트를 거치며 코드들을 정리해볼 수 있는 시간도 있었고 성공적으로 배포에 안착했기 때문에 다행이라는 생각이 든다. 또 모자란 점을 많이 느껴볼 수 있는 이 기간이 내겐 무엇보다 큰 자양분이 됐으리라고 믿는다. </p>
<p>우선 프로젝트를 마무리하면서 기획 단계에서 가졌던 SR에 대해서 기입해보고자 한다.</p>
<h3 id="프로젝트-스택">프로젝트 스택</h3>
<p><img src="https://images.velog.io/images/oh_ji_0/post/d1a51da3-d68e-477e-9f46-9363d87e7e0a/%EA%B8%B0%EC%88%A0%EC%8A%A4%ED%83%9D.png" alt=""></p>
<p>우리 프로젝트 스택은 위와 같다. 프론트 엔드 포지션을 맡은 나는 같은 포지션 팀원과 함께 초반에 리액트 네이티브, 타입스크립트, 리액트 훅스를 스택 검토를 했다. 짧은 시간이지만 리액트 네이티브도 선제적으로 먼저 공부해보고 하면서 적합한 스택을 고민했다.</p>
<p>결과적으로 우리 프로젝트는 1주라는 짧은 시간동안 Basic Requirements를 완료하여 배포를 하는 것을 최우선 점으로 두었기 때문에 리액트 네이티브는 과감하게 제끼기로 했다. 새로운 스택을 도입하는 것보다도 사용자가 원하는 서비스를 한번이라도 만들어보는 경험을 가져보는 것과 타입스크립트를 경험해보고, 리액트 훅스를 다뤄보는 것을 더 우선적인 과제로 받아들였기 때문이다.</p>
<h3 id="기능-플로우">기능 플로우</h3>
<p><img src="https://images.velog.io/images/oh_ji_0/post/d26046e2-8f79-4990-b59d-8a7828d18248/%EA%B8%B0%EB%8A%A5%ED%94%8C%EB%A1%9C%EC%9A%B0.png" alt=""></p>
<p>기능 플로우는 다음과 같다. 처음엔 비회원 로그인 기능을 고려하지 않았으나, 스프린트를 경험하면서 비회원도 경험해볼 수 있는 서비스가 접근성 면에서 훨씬 좋다는 것을 알게 됐다. 때문에 우리는 로그인을 하면 이용할 수 있는 서비스 (마이페이지, 구매내역) 등을 나누면서도 비회원도 주문 기능을 활용 할 수 있도록 진행했다.</p>
<p>추후에 소셜 로그인까지 적용을 하면서 우리가 관리하는 회원의 형태는 일반 회원/소셜 회원/비회원 이 3가지 형태로 나눠지게 되었다. 이 내용은 다음 DB Schema의 형태와도 이어진다.</p>
<h3 id="db-schema">DB Schema</h3>
<p><img src="https://images.velog.io/images/oh_ji_0/post/68777c8e-c57e-488d-a103-7a75754a26bd/db_schema.png" alt=""></p>
<p>다음은 DB 스키마다. 굉장히 테이블이 많아서 복잡해보일 수 있으나 왼쪽 상단부터 아래까지 oauths(소셜회원), user(일반 회원), unknowns(비회원) 의 3가지 형태의 유저에 관련된 테이블들이고 그 회원들과 관련된 주문(orders), 선호마켓정보(markets), 상품(items) 들의 테이블로 나눠지게된다. **_order_items 는 상품 목록과 주문 테이블의 조인 테이블이다.</p>
<h3 id="wire-frame">Wire Frame</h3>
<details>
<summary>메인</summary>  
<img src="https://images.velog.io/images/oh_ji_0/post/e34dc5bc-a435-4d0a-b69d-bfb6fff23066/%EB%A9%94%EC%9D%B8.png" alt="메인"/>
</details>

<details>
<summary>로그인</summary>  
<img src="https://images.velog.io/images/oh_ji_0/post/df11a00c-90e1-44ce-a351-044789eba938/%EB%A1%9C%EA%B7%B8%EC%9D%B8.png" alt="로그인"/>
</details>

<details>
<summary>비회원주문</summary>  
<img src="https://images.velog.io/images/oh_ji_0/post/f14b625a-29a5-496e-80f2-d949224773ed/%EB%B9%84%ED%9A%8C%EC%9B%90%EC%A3%BC%EB%AC%B8.png" alt="비회원주문"/>
</details>

<details>
<summary>소셜회원가입</summary>  
<img src="https://images.velog.io/images/oh_ji_0/post/62999f61-eb23-477a-b02c-7db9f4188790/%EC%86%8C%EC%85%9C%ED%9A%8C%EC%9B%90%EA%B0%80%EC%9E%85.png" alt="소셜회원가입"/>
</details>

<details>
<summary>주문옵션설정</summary>  
<img src="https://images.velog.io/images/oh_ji_0/post/c705a91e-8e4f-4321-8510-44521e5ae6fe/%EC%A3%BC%EB%AC%B8%EC%98%B5%EC%85%98%EC%84%A4%EC%A0%95.png" alt="주문옵션설정"/>
</details>
<details>
<summary>회원가입</summary>  
<img src="https://images.velog.io/images/oh_ji_0/post/64220e41-8795-468d-9cf1-ab5fda705415/%ED%9A%8C%EC%9B%90%EA%B0%80%EC%9E%85.png" alt="회원가입"/>
</details>

<p>다음은 와이어 프레임이다. 각 페이지별로 들어야하는 부분을 와이어프레임을 토대로 구성했다. 와이어프레임을 보면서 UI 디자인도 참고했는데 해당 디자인은 <a href="https://velog.io/@oh_ji_0/%ED%8C%8C%EC%9D%B4%EB%84%90-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-UI-%EB%94%94%EC%9E%90%EC%9D%B8">이 글</a>에서 참고 가능하다. 와이어프레임은 우리가 구성해야하는 BR을 토대로 최소한만을 잡았다. 보기엔 간단하지만 이 것들을 정리하는 과정에서 굉장히 많은 과정과 대화들이 이뤄졌고, 꼭 필요한 것만을 넣기 위해 가감하는 과정에 공을 많이 들였다. 어떻게 하면 연령대가 높은 분들이 편리하게 사용하고 꾸준히 편리하게 사용할까? 라는 것이 시작 모토였기 때문에 생각보다 힘든 과정이었다. 무언가를 붙이는 과정보다 빼는 과정이 더 힘들 수 있구나 라는 생각을 이 SR을 진행하면서 처음 느껴보았던 것 같다. 결과적으로 초반에 회의하는 과정에서 힘을 많이 쏟았기에 중간에 일어날 수 있는 혼동들이 많이 없어졌다. 팀원끼리 서로의 생각을 이해하는 과정이 작업에서 일어날 수 있는 오류들을 방지하기 위해서 꼭 필요하구나를 깨달은 시간이었다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[@코드스테이츠 파이널 프로젝트 중간 회고글]]></title>
            <link>https://velog.io/@oh_ji_0/%EC%BD%94%EB%93%9C%EC%8A%A4%ED%85%8C%EC%9D%B4%EC%B8%A0-%ED%8C%8C%EC%9D%B4%EB%84%90-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EC%A4%91%EA%B0%84-%ED%9A%8C%EA%B3%A0%EA%B8%80</link>
            <guid>https://velog.io/@oh_ji_0/%EC%BD%94%EB%93%9C%EC%8A%A4%ED%85%8C%EC%9D%B4%EC%B8%A0-%ED%8C%8C%EC%9D%B4%EB%84%90-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EC%A4%91%EA%B0%84-%ED%9A%8C%EA%B3%A0%EA%B8%80</guid>
            <pubDate>Tue, 15 Dec 2020 03:32:34 GMT</pubDate>
            <description><![CDATA[<p>파이널 프로젝트 마무리 단계에 들어섰다. 역시 3주라는 시간이 이전과 마찬가지로 너무도 정신없이 흘러갔다.</p>
<p>다음주 초에 프로젝트를 발표하는 데모데이가 발표가 남아있는데 아직 완전한 마무리는 아니지만 마무리 단계에 들어 섰으므로, 이쯤에서 중간 회고를 작성하고자 한다.
무엇이 좋았고, 무엇이 부족했는지에 따라 정리해보고자 한다.</p>
<h3 id="api-문서의-중요성">API 문서의 중요성</h3>
<p>첫번째 프로젝트가 끝나고 파이널 프로젝트에서 첫번째 프로젝트에서 후회했던 것들을 바로 잡기 위해 이번 프로젝트에선 SR에 더 많은 투자를 했다. </p>
<p>각자의 생각을 이야기하고, 이 시간이 굉장히 힘들게 느껴졌다. 서로 구상하는 생각이 너무도 다르고 각자의 언어로 설명하고 이해하고, 개인적으로 굉장한 에너지 소모가 들어가는 작업이라는 생각이 들었다. </p>
<p>그래도 덕분에 첫번째 프로젝트보다 더 견고한 SR을 완성할 수 있었다. 다만 그럼에도 완벽할 수는 없는 것 같다. 같이 얘기하고 정리를 해도 구현 방식이나 요청, 응답에 대한 생각이 완벽히 정리가 되진 않더라.</p>
<p>또한 SR가 다 중요하지만 그중에서 API 문서 작성이 정말 정말 너무너무 중요하다는 생각을 갖게 되었다. 사실 프로젝트 중반부가 넘어가고 초반 SR 에서 제대로 정하지 않은 기능 및 페이지들을 추가하는데 다른 논의 보다도 API 에 대한 것만을 정확히 픽스해놓고 갔는데 훨씬 수월하게 작업이 이뤄졌다. 초반 SR은 공을 들인데에 비해 API에 대한 고민은 상대적으로 적었고, 이에 대한 혼선과 변경에 대한 API 문서 반영이 제때 제때 이뤄지지 않으면서 중간,중간 작업할 때 애를 먹었다.</p>
<p>백과 프론트의 소통 API 문서만 제대로 돼있으면 불필요한 논의와 토론이 필요 없다는 것을 정말 많이 느꼈다.
결론은 API 문서가 너무너무 중요하다.</p>
<h3 id="쿠키-세션에-대한-이해">쿠키, 세션에 대한 이해</h3>
<p>그래도 프로젝트 진행하면서 가장 좋았던 점은 쿠키, 세션에 대한 방식에 대해 폭넓게 경험해볼 수 있었다는 점이다. 그전에 사실 배포하다가 https same-site 문제 때문에 로그인이 정상적으로 돌아가지 못하고 쿠키, 세션을 브라우저에서 제대로 통신하지 못한 채 마무리 지을 수 밖에 없었는데 이번 프로젝트에선 둘 째주에 배포에 공을 들여, same-site 문제를 우선 해결하고 주문을 넣는 각 페이지에서 temp 라는 쿠키를 사용하면서 사용자의 UX를 고민하는 시간을 가질 수 있었다. jwt 토큰은 이용한 쿠키를 이용하여 사용자는 주문 첫번째 단계부터 마지막 단계까지 주문 데이터를 안전하게 간직하고 활용할 수 있다.
이런 일련의 과정을 처음부터 끝까지 경험해 볼 수 있었다는 게 내게 큰 성장이 되었던 시간 같다.</p>
<h3 id="타입스크립트에-입문">타입스크립트에 입문</h3>
<p>이번 프로젝트는 타입스크립트에 처음 발을 들여놓는 좋은 시작점이 되었던 것 같다. 물론 결론적으로 타입스크립트에 대해서 수준 높은 이해를 하고 있는가? 라고 생각해보면 자신있게 네 라고는 못하겠다. </p>
<p>지금 현 수준은 최대한 any를 자제하고 API 요청, 및 응답, 리덕스 저장, 모듈 활용에서 타입을 지정하여 추후에 발생할 수 있는 타입 오류를 사전 방지하고, 제어할 수 있는 정도다. 이번 프로젝트에선 주로 type alias를 이용하여 타입을 지정해주고 useState 등에서 제너릭을 활용해보는 정도, 그리고 리액트 모던 캘린더 데이트피커(react-modern-calendar-datepicker) 라는 모듈을 사용할 때 타입스크립트에 맞게 연결해주는 작업정도를 해보았다. </p>
<p>사실, 4명이라는 소수가 참여하는 프로젝트에 2명이라는 프론트 포지션, 그리고 거기에서도 파트를 나눠서 작업에 들어갔기 때문에 작업하면서 타입스크립트가 얼마나 편리한지 왜 꼭 써야하는지 명확하게 느끼진 못했다. 내가 작성한 코드는 출력값과 입력값을 내가 이미 알고 있고, 구태여 어떤 값으로 받을지 지정하는 작업이 내겐 더 불편했기 때문이다. 그러나 만약 더 큰 프로젝트, 협업 인원이 더 늘어난다면, 그리고 다른 사람이 작성하 코드에 내가 들어간다면. 그땐 정말 타입스크립트로 작성된 코드가 굉장히 편하고 어디서 터질지 모르는 오류를 사전적으로 어느정도는 방지해주기때문에 필요하겠구나 간접적으로 느껴보는 시간을 가질 수 있었다. </p>
<h3 id="프로젝트를-돌아보며">프로젝트를 돌아보며...</h3>
<p>모든 프로젝트가 그러듯, 중반부를 넘어선 현재 돌아보면 아쉬운 점도 많았다. 서로의 부족한 점을 아마 일일이 나열하기 힘들 정도로.. 각자 서로가 준비가 정말 더 많이 필요하구나, 느낀 시간들이었을 것이다.</p>
<p>촉박한 시간 속에서, 코드에 대한 논의가 이루어지면서 사실은 서로의 코드 중 누가 정답이고, 누가 오답인지. 그리고 둘 중에 정답이 존재하긴 한지에 대한 확신이 스스로 없다는 생각이 들기도 했고, 같은 언어 혹은 모듈, 라이브러리를 다뤄도,  어디에 중점을 두는지에 대한 생각 자체도 굉장히 많이 다르구나 느껴볼 수 있는 시간이었다.
많은 사람들의 코드를 봐보고, 그 중에 좋은 방법을 택할 수 있는 힘을 길러야겠다는 생각이 들었다.</p>
<p>이제 일주일이란 시간도 채 남지 않았다. 로그인과 핸드폰 인증 등 나름 중요한 기능들이 남아있는 상태인데, 잘 마무리하여 성공적으로 프로젝트를 띄우고, 또 더 많은 것을 배우는 시간이 되었으면 한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[@코드스테이츠, 첫번째 프로젝트 회고글]]></title>
            <link>https://velog.io/@oh_ji_0/%EC%BD%94%EB%93%9C%EC%8A%A4%ED%85%8C%EC%9D%B4%EC%B8%A0-%EC%B2%AB%EB%B2%88%EC%A7%B8-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%ED%9A%8C%EA%B3%A0%EA%B8%80</link>
            <guid>https://velog.io/@oh_ji_0/%EC%BD%94%EB%93%9C%EC%8A%A4%ED%85%8C%EC%9D%B4%EC%B8%A0-%EC%B2%AB%EB%B2%88%EC%A7%B8-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%ED%9A%8C%EA%B3%A0%EA%B8%80</guid>
            <pubDate>Sat, 21 Nov 2020 15:15:02 GMT</pubDate>
            <description><![CDATA[<p>정신없는 2주가 순식간에 지나갔다.
아무리 바빠도 글 하나 적을 시간이 없을까 했는데 정말 시간이 없었다. 프로젝트가 끝나고 나서야 글을 적게 될 줄 나도 정말 몰랐다.</p>
<p>처음엔 약간 얼떨떨하게 시작했던 것 같다. SR을 짜는 시간이 주어졌고, 촘촘하게 짜여져있던 이전 스프린트 시간들과 마찬가지로 하루 혹은 이틀만에 개발 아이템 회의, 팀장 선정, 포지션 선정, 와이어프레임, 태스크 카드 작성, 컴포넌트 구성, UI 디자인을 완성시켜야 했다. </p>
<p>시간에 맞추려다보니 백/프론트로 나누어서 진행한 부분이 많았고 전체적으로 SR에 대한 깊은 고민과 회의를 진행하지 못했다. 지금 돌아보면 그것이 잘못된 선택이었다고 느낀다. 그래도 변명해보자면 사실 첫번째 프로젝트라 어떤 것들이 나중에 문제가 될지, 어떤 이야기를 더 깊게 나눠야 하는지 막막했다. 코드 짤 시간이 촉박하니 시간을 할애하기보단 일단 이렇게 마무리를 짓고 코드를 치면서 부딪쳐보자 생각했다. </p>
<p>이부분은 나중에 가서 문제가 되는데 백/프론트가 서로 생각한 API 응답값이 제각각이여서, 나중에 가서 API를 대거 수정하고, 프론트에서도 코드 구현에 시간을 더 잡아먹게 됐다. 같은 곳에 활용해야 할 데이터의 형태가 다르다보니 개별적으로 축약할 수 있었던 코드가 늘어나고, 복잡해져만 갔다. </p>
<p>그리고 또 아쉬운 게 있었다면 사실 나는 이번 프로젝트가 진행되면서 좀 더 피드백 다운 피드백을 중간 중간 받을 수 있지 않을까 생각했다. 그러나 주관이 들어갈 수 있는 아이템에 대한 부분은 차치하더라도 SR 작성에 대한 부분이나 나중에 코드에 대한 피드백이 자세하지 않거나 없었던 점이 아쉬움으로 남는다.</p>
<p>물론, 몸으로 부딪치면서 겪는 실제 경험이 더 오래가고 기억에 오래 남는다, 라는 것이 코드스테이츠에서 코스 진행하면서 항상 가르친 생각이었고 이번에도 그랬을 수 있다는 생각, 그리고 그 생각이 틀린 생각은 아니라는 점에 동의한다. 그래도 2주동안 몰두해서 작업하는 프로젝트이니만큼 그에 대한 피드백을 들을 기회를 더 가질 수 있었다면 더 좋지 않았을까 하는 아쉬움이 남는다. 헬프 데스크를 통해서 질문을 던졌다면 물론 그에 대한 답변을 받아갈 수 있었겠지만, 코스 진행을 하면서 집중을 하느라 놓친 부분에 대해서라든지, 잘못 진행되는 부분에 대한 간단한 피드백이라도 주에 한번쯤은 팀별로 받아볼 수 있었으면 좋았겠다는 건 개인 욕심일까.</p>
<p>개인적으로 아쉬움이 남는 점은 또 있다. 이번 프로젝트는 개인적으로 좋으면서도 참 힘든 프로젝트였는데 프론트 엔드 개발자로서 취업을 하는 것이 내 목표이기 때문에 프론트 관련, 팀원과 코드에 대한 것도 맞춰보고 서로 많은 소통을 했으면 하는 기대가 있었다. 그러나 이번 프로젝트에선 그런 것들이 제대로 이뤄지지 않았고, 혼자 작업을 한다는 생각이 전반적으로 더 많은 프로젝트였던 것 같다. 중간엔 코스 진행 이전에 일하던 시절이 생각나기도 했다. 팀원이 포기한 영역에 대한 코드를 중반부터 기계적으로 찍어내느라 고민하지 않고 마구 담은 리덕스 데이터와 마크업들 CSS 모듈 들에 대해서 스스로도 이게 정말 이렇게 해도 되는건지 모르겠다는 생각이 들었고, 먼저 적었던 코드들에 대해서도 리팩토링, 최적화 등을 고민해볼 수 없이 그냥 흘러가버렸다. 리덕스를 사용했지만, 구현에만 성공했을 뿐 리덕스를 이렇게 활용하는 것이 맞는가하는 생각이 많이 들었다. 리덕스를 활용하여 상태를 관리하고, api 요청을 보내 db 데이터를 수정하고, 일련의 과정이 시간에 좇겨 생각보다 더 많은 api 요청을 보냈던 것 같다. (사실 이게 맞는 형태인지, 실무에선 어떤 형태로 그려지는지는 아직도 궁금하다..)수료가 끝나고서라도 꼭 다시 고민해서 리팩토링을 해야겠다 마음을 먹고 있지만, 협업이 그때가서 이뤄질 수 있을까는 장담할 수 없기에 지나간 2주에 대해서 많은 아쉬움이 남는 것은 사실이다.</p>
<p>많은 것들에 대해 돌아보고 느낀 2주였다. 
개인적으로 아쉬움이 정말 큰 프로젝트였지만 그래도 성장한 부분이 있었다는 것에 의의를 두고 싶고, 이 경험을 잘 녹여서 파이널에선 좀 더 성장한 모습을 보여야겠단 생각이 든다.
당장 다음주부터 다시 파이널 프로젝트가 시작되는데 공부할 부분, 보완할 부분을 최대한 담아서 가야겠다고 다짐해본다. 우선은 후회를 했었던 SR에 대해서 더 깊이 고민해볼 차례다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[201105_TIL]]></title>
            <link>https://velog.io/@oh_ji_0/201105TIL</link>
            <guid>https://velog.io/@oh_ji_0/201105TIL</guid>
            <pubDate>Thu, 05 Nov 2020 12:43:11 GMT</pubDate>
            <description><![CDATA[<h3 id="today-i-learned">TODAY I LEARNED</h3>
<blockquote>
<ul>
<li>react 포트폴리오 웹페이지 리팩토링</li>
</ul>
</blockquote>
<ul>
<li>nodemailer 모듈 사용 (smtp)</li>
<li>ssl 인증서 적용 (미완료)</li>
<li>나스 시놀로지 웹서버 세팅 및 DNS 설정</li>
</ul>
<p>@@ 오늘은 마무리짓지 못했던 리액트 포트폴리오 페이지를 정리하고 마무리 짓는 시간을 가졌다.</p>
<p>페이지는 여기 참고 <a href="http://webdev.jiyoung5.com">포트폴리오 페이지</a></p>
<p>사실 아직도 군데군데 걸리고 마음에 안드는게 많다. 있던 페이지를 (원래는 nuxt.js로 돼있던) 리액트로 리팩토링했는데 급하게 가져오다보니까 ui도 너무 대강 만들고 모션이나 이런것도 넣어보고 싶었는데 넣지 못해서, 아직은 완성 아닌 완성 느낌.</p>
<p>그래도 정말 그저께부터 nodemailer모듈이 제대로 코드를 적어줘도 너무 안돼고 오류파티로 거부가 떠서 진짜 포기해야하나 싶었는데, 오늘 가까스로 적용이 돼서 너무 기뻤다. (정말 내가 본 오류들만,... 몇가지인지 기억도 안난다. 스택오버플로우글을 정말 종류별로 2-30개는 계속 보고 적용하고, 바꾸고를 반복했다)</p>
<p>어쨌든 결국은 구글 계정의 보안 세팅 문제와 CORS 보안 정책, 갖가지 오류들을 다 걷어내고 나서야 오늘 정상적으로 작동하기 시작했다.</p>
<p>배포부터 하는게 좋다는 말, 이번 기회에 너무 잘 깨달았다. 기분 좋게 다 작성하고 빌드하고 올렸는데 안돼서 너무나 망연자실... </p>
<p>아 그리고 nodemailer 때문에 시작한 것이었는 시놀로지 nas 웹서버에 https인증서를 발급받는데도 오늘 시간을 할애 많이 했는데 (결국엔 지금 잠시 중단됐지만)</p>
<p>let&#39;s crypto 를 통해서 쉽게 할 수 있었는데 다른 사이트에서 어렵게 돌아서 하느라고 애를 먹었다. 아직 나스 포트 문제 등 여러가지에 걸쳐서 적용은 못했는데 내일에 다시 한번 시도해서 ssl인증서 발급, 등록해야지 싶다.</p>
<p>내일은 ssl을 마무리 짓고, 
리액트 함수 컴포넌트와 리덕스를 좀 파볼 예정이다.</p>
<p>아래는 오늘 문제들을 해결하면서 유용하게 참고한 사이트들이다.</p>
<h3 id="나스-인증서-적용-관련">[나스 인증서 적용 관련]</h3>
<ul>
<li><a href="https://wp.shashasha.kr/synology-nas-virtual-hosting-certification/#%EA%B0%80%EC%83%81_%ED%98%B8%EC%8A%A4%ED%8A%B8_%EC%84%A4%EC%A0%95">시놀로지 나스 가상 호스트 설정과 인증서(Let’s Encrypt) 적용</a></li>
<li><a href="https://redmilk.co.kr/archives/2616/comment-page-2">시놀로지 NAS Let’s Encrypt 무료 SSL인증서 적용</a></li>
<li><a href="https://www.lifeformula.net/10298">Synology NAS / Let’s Encrypt 인증서 설치하고 설정하는 방법</a></li>
<li><a href="https://m.blog.naver.com/ronghuan/221905862569">let&#39;s encrypt 도메인 이름이 유효한지 확인하십시오</a></li>
<li><a href="https://eu4ng.tistory.com/12">[시놀로지] Let&#39;s Encrypt 인증받기 (오류 대처법 포함)</a></li>
</ul>
<h3 id="nodemailer">[nodemailer]</h3>
<ul>
<li><a href="https://nodemailer.com/usage/using-gmail/">Nodemailer - USING GMAIL</a></li>
<li><a href="https://blog.nodemailer.com/">nodemailer blog</a></li>
<li><a href="https://blog.mailtrap.io/nodemailer-gmail/">How to Set up Nodemailer with Gmail</a></li>
<li><a href="https://blog.naver.com/PostView.nhn?blogId=supr2000&amp;logNo=221468773834&amp;parentCategoryNo=&amp;categoryNo=85&amp;viewDate=&amp;isShowPopularPosts=true&amp;from=search">SMTP란? - Gmail SMTP를 이용해 메일 보내기</a></li>
<li><a href="https://velog.io/@jiwon/-Nodemailer%EB%A1%9C-%EC%9D%B8%EC%A6%9D-%EA%B4%80%EB%A0%A8-%EC%9D%B4%EB%A9%94%EC%9D%BC-%EB%B3%B4%EB%82%B4%EA%B8%B0-d4k4pqoot4">Nodemailer로 인증 관련 이메일 보내기</a></li>
<li><a href="https://velog.io/@josworks27/Back-end-Node.js%EC%97%90%EC%84%9C-%EB%A9%94%EC%9D%BC-%EC%A0%84%EC%86%A1%ED%95%98%EA%B8%B0-feat.-Nodemailer-Gmail">[Back-end] Node.js에서 메일 전송하기 (feat. Nodemailer &amp; Gmail)
</a></li>
<li><a href="https://github.com/nodemailer/nodemailer/issues/890">Gmail smtp # 890</a></li>
<li><a href="https://stackoverflow.com/questions/59341238/nodemailer-querya-erefused-localhost-when-using-firebase-cloud-functions">Nodemailer queryA EREFUSED localhost when using Firebase Cloud Functions</a></li>
<li><a href="https://privatenote.tistory.com/entry/%EA%B5%AC%EA%B8%80-Gmail-SMTP-%EC%84%A4%EC%A0%95-%EB%B0%A9%EB%B2%95">Gmail 기본 SMTP 설정</a></li>
<li><a href="https://m.blog.naver.com/PostView.nhn?blogId=scw0531&amp;logNo=221170429866&amp;proxyReferer=https:%2F%2Fwww.google.com%2F&amp;view=img_5">Node.js - SMPT 연동</a></li>
<li><a href="https://support.google.com/accounts/answer/6010255?hl=ko">보안 수준이 낮은 앱 및 Google 계정</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[201103_TIL]]></title>
            <link>https://velog.io/@oh_ji_0/TIL201103</link>
            <guid>https://velog.io/@oh_ji_0/TIL201103</guid>
            <pubDate>Tue, 03 Nov 2020 06:00:00 GMT</pubDate>
            <description><![CDATA[<h2 id="today-i-learned">TODAY I LEARNED</h2>
<blockquote>
<ul>
<li>아마존 웹서비스와 클라우드</li>
</ul>
</blockquote>
<ul>
<li>S3</li>
<li>EC2</li>
<li>RDS</li>
</ul>
<p>@@ 오늘은 아마존 웹서비스에 클라이언트 애플리케이션(리액트 SPA)을 S3에 세팅하고, 서버 애플리케이션을 EC2에 셋팅, 접근 가능하게 퍼블릭 액세스를 적용하는 것과 RDS에 접근하는 방법을 스프린트를 통해서 익혀보았다.
아직은 기초적인 것들만을 배운 상태라서 그 개념들이나 확장된 활용성들에 대해서는 많이 모르는 상태지만, 나중에는 advanced한 아키텍쳐까지도 직접 활용해볼 수 있도록 접근을 해봐야겠다. 그치만 과금은 넘나 무서운 것... 너무 어마무시한 얘기를 많이 들어서 😂😂😂</p>
<h2 id="아마존-웹서비스와-클라우드">아마존 웹서비스와 클라우드</h2>
<ul>
<li>구름 위에 설치되어있는 컴퓨터를 이용해서 실제 작업 설치. 인터넷을 구름으로 비유했다.</li>
<li>인터넷, 인터넷에 연결되어 있는 거대한 컴퓨터를 사용한다라는 것이 클라우드 컴퓨팅의 가장 중심
적인 아이디어</li>
</ul>
<h2 id="s3simple-storage-service">S3(Simple Storage Service)</h2>
<ul>
<li>클라우드 데이터 저장소, 정보(파일)를 저장하는 서비스</li>
<li>서버를 클라우드 서비스가 대신 관리해주므로 개발자나 운영자가 서버를 관리하는데 드는 부담을 줄일 수 있다.</li>
<li>노드 서버가 다른 서버보다 정적 파일을 제공하는데 더 유리하지는 않으므로, 클라우드 데이터 저장소가 대신 정적 파일을 제공하도록 위임하기도 한다.</li>
</ul>
<h3 id="s3의-장점">S3의 장점</h3>
<ul>
<li><p>내구성 (파일 유실 가능성의 낮음)</p>
</li>
<li><p>비용의 절감(사용하는 만큼한 비용을 지불)</p>
</li>
<li><p>연중 99.9%의 객체 가용성 제공(항시 사용가능)</p>
</li>
<li><p>SSL, 암호화된 방식을 주고받아 보안적으로 보다 더 안전함</p>
</li>
<li><p>확장 가능성</p>
</li>
<li><p>이벤트 알림, 트리거를 사용하여 스토리지와 연계된 서비스 운영을 편리하게 사용 가능함</p>
</li>
<li><p>버킷을 만들때 지역을 선택하여 빠르게 데이터 전송 가능 (고성능)</p>
<p>  cloudFront라는 서비스와 통합하여 사용할 수 있다</p>
</li>
</ul>
<h2 id="ec2-elastic-compute-cloud">EC2 (Elastic Compute Cloud)</h2>
<ul>
<li><p>AWS에서 제공하는, 크기 조정이 가능한 컴퓨팅 용량을 클라우드에서 제공하는 웹 서비스</p>
</li>
<li><p>한대의 컴퓨터를 임대하는 것으로 생각할 수 있다.</p>
</li>
<li><p>Elastic, 탄력적 운용이 특장점이다.
필요할때까지만 사용하고 인스턴스를 내리거나 삭제, 보관할 수 있고 원할때 복구도 가능하다.</p>
</li>
<li><p>이 컴퓨터엔 여러 가지 프로세서, 스토리지, 네트워킹, 운영 체제, 구매 모델을 선택할 수 있다.</p>
</li>
<li><p>100Gbps 이더넷 네트워킹을 제공한다.</p>
</li>
<li><p>프로그램 설치, 파일 저장, 설정 변경을 그대로 저장할 수 있다 ( AWS 머신 이미지 : AMI )</p>
<p>  새로운 컴퓨터를 만들면 이미지에 저장된 상태로 똑같이 생성 가능하다.
  AWS는 자주 사용하는 운영체제들에 대한 AMI를 만들어서 배포하고 있다.
  이들 AMI는 아마존에서 제공하는 툴들이 설치되서 배포되기 때문에, AWS의 다른 컴포넌트들과 쉽게 연동된다.</p>
<p>  AMI는 마켓플레이스와 연동할 수도 있다. 회사가 개발한 서비스를 배포하기위한 채널로도 사용된다.</p>
</li>
</ul>
<h3 id="ec2-과금-비용정책">EC2 과금, 비용정책</h3>
<ul>
<li><p>성능 좋은 인스턴스를 쓸수록 그만큼 과금액이 기하급수적으로 늘어난다.</p>
</li>
<li><p>성능별로 nano/micro/small/large/xlarge 등으로 세분화된다.</p>
</li>
<li><p>Auto Scaling</p>
<p>  트래픽이 몰리면 인스턴스를 자동으로 늘려서 대응하고 트래픽이 줄어들면 만들었던 인스턴스를 없애는 일을 할 수 있다.</p>
<p>  TIP: 작은 서버 여러 대로 분산처리를 하는 것이 필수고, 고성능이 필요한 연산이 있으면 필요할 때만 잠깐씩 서버를 생성했다가 작업이 끝나면 즉시 삭제해버리는 식으로 사용시간을 아껴야 한다</p>
</li>
<li><p>EC2의 대표 기능</p>
<ul>
<li>인스턴스: 가상 컴퓨팅 환경</li>
<li>인스턴스 유형: 인스턴스를 위한 CPU, 메모리, 스토리지, 네트워킹 용량의 여러 가지 구성 제공</li>
<li>키 페어를 사용하여 인스턴스 로그인 정보 보호</li>
</ul>
</li>
</ul>
<h3 id="ec2-네트워크">EC2 네트워크</h3>
<ul>
<li>인스턴스 시간 또는 데이터 전송같은 소비 리소스에 대한 비용이 지불된다.</li>
<li>EC2 인스턴스는 private ip와 public ip 그리고 [wikiSite/cloud/AWS/EIP EIP]를 가진다</li>
<li>인터넷 서비스를 하려면 고정된 IP가 필요한데, AWS는 EIP(Elastic IP)라는 이름의 고정아이피 서비스를 제공</li>
<li>인스턴스가 만들어지면 인터페이스에 AWS region에서 사용할 수 있는 private ip가 할당 된다. Private ip는 DHCP를 통해서 할당이 된다. 이 IP는 유저가 변경할 수 없다.</li>
<li>소규모에서는 EC2가 저렴하다가 대규모로 서비스가 발전하면 갑자기 확 비싸지는 게 EC2의 특징이다.</li>
</ul>
<h3 id="용어정리">용어정리</h3>
<ul>
<li><p>인스턴스
Amazon EBS 지원 인스턴스 (루트 볼륨이 EBS 볼륨임을 의미)</p>
</li>
<li><p>EBS</p>
<p>  루트 볼륨</p>
</li>
<li><p>마이크로 인스턴스</p>
<p>  저렴한 비용으로 사용가능한 저사양 인스턴스. </p>
</li>
<li><p>운영체제 auto provisioning</p>
<p>  운영체제 시스템 형상을 코드화 그 코드를 로직을 이용한 실행</p>
</li>
</ul>
<p>참고 문서</p>
<ul>
<li><a href="https://namu.wiki/w/%EC%95%84%EB%A7%88%EC%A1%B4%20%EC%9B%B9%20%EC%84%9C%EB%B9%84%EC%8A%A4?from=Aws#s-3.1.1">EC2 나무위키</a></li>
<li><a href="http://aws.amazon.com/ko/ec2/">EC2 공식 소개 문서</a></li>
<li><a href="http://aws.amazon.com/ko/documentation/ec2/">EC2 기술문서</a></li>
<li><a href="https://opentutorials.org/course/608/3004">생활코딩 EC2</a></li>
<li><a href="http://www.joinc.co.kr/modules/moniwiki/wiki.php/Site/cloud/AWS/EC2">EC2 자원의 특성</a></li>
<li><a href="http://www.phoronix.com/scan.php?page=article&amp;item=amazon_ec2_sep13&amp;num=1">EC2 벤치마킹</a></li>
<li><a href="https://www.joinc.co.kr/w/Site/cloud/AWS/EC2">EC2 블로깅 글</a></li>
</ul>
<h2 id="rds">RDS</h2>
<ul>
<li>인프라 및 데이터베이스 업데이트를 관리해주는 것 뿐만 아니라 까다로운 관계형 데이터베이스의 설치, 운영 그리고 관리를 지원하는 서비스</li>
<li>기업이 데이터베이스를 빌려 쓸 수 있도록 지원</li>
<li>현재 MySQL, Oracle, SQL Server, PostgreSQL, MariaDB, Aurora(MySQL과 호환)을 비롯한 총 6가지 데이터베이스 엔진을 지원</li>
<li>EC2인스턴스 위에서 돌아가는 서비스이기 때문에 해당 EC2인스턴스의 시간당 요금을 지불한다.</li>
</ul>
<h3 id="rds-요금">RDS 요금</h3>
<ul>
<li>RDS 인스턴스 요금은 기본 인스턴스 크기, 데이터 스토리지, 멀티 가용영역, 데이터 전송에 따라 달라진다.</li>
<li>자체 하드웨어 또는 인스턴스에서 운영하는 것보다 실제 성능이 훨씬 낮을 수 있다.</li>
</ul>
<h3 id="rds-사용의-이점">RDS 사용의 이점</h3>
<ul>
<li>RDS를 사용하게 되면, OS 및 데이터베이스의 설치 및 관리 그리고 업데이트를 따로 할 필요가 없어짐</li>
<li>AWS 콘솔이나 AWS API를 통해 손쉽게 백업이나 복구(recovery)가 가능</li>
<li>AWS의 RDS 업데이트를 통해 더 이상 사용 중이지 않을 때에 대한 불필요한 비용을 지불하지 않아도 됨</li>
</ul>
<p>참고문서</p>
<ul>
<li><a href="https://www.bespinglobal.com/bespins-pick-vol-11-aws-rds-vs-ec2/">AWS RDS vs EC2 차이점, 간단히 파악하기</a></li>
</ul>
]]></description>
        </item>
    </channel>
</rss>