├── .github
├── disabled-workflows
│ └── add_contributor.yml
└── workflows
│ └── update_readme_toc.yml
├── .gitignore
├── .log
└── readme_log.json
├── Javascript
├── Asynchronous.md
├── Basic_movement.md
├── DataType.md
├── ES2020.md
├── ES_Module.md
├── Es6_Spec.md
├── EventBubling.md
├── Garbage_Collector.md
├── Hoisting.md
├── Iterator_Generator.md
├── JIT.md
├── Number_Floating_Point.md
├── Prototype.md
├── Scope.md
├── Storing_Data_In_Browser.md
├── This_Keyword_Call_Apply.md
├── Throttling_Debouncing.md
├── V8_Engine.md
├── Web_Working_Concept.md
├── executionContextAndClosure.md
└── variable_tdz.md
├── README.md
├── S2_Round1
├── chart-library.md
├── introduction-to-stateManagementTools.md
├── lazyloading.md
├── nextjs_tutorial_ch1.md
├── rxjs.md
└── storybook.md
├── S2_Round2
├── code-splitting.md
├── css-bem.md
├── css_in_js.md
├── jsTDD.md
├── lighthouse.md
└── oop_vs_functional.md
├── S2_Round3
├── FID.md
├── LCP.md
├── core-web-vitals.md
└── web-vitals-best-practice.md
├── S2_Round4
└── Http-vs-Socket.md
├── _config.yml
├── interview
├── Nailer_interview1.md
├── Nailer_interview2.md
├── Nailer_interview3.md
├── Samslow_Interview1.md
├── Samslow_Interview2.md
├── Samslow_Interview3.md
├── Snowjang24_Interview1.md
├── Snowjang24_interview3.md
├── devowen_interview1.md
├── devowen_interview2.md
├── devowen_interview3.md
└── jinsunee_interview1.md
├── lib
├── __init__.py
├── gitlog.py
├── header.py
├── logger.py
└── rmd.py
├── py-package.txt
└── update_readme.py
/.github/disabled-workflows/add_contributor.yml:
--------------------------------------------------------------------------------
1 | # This is a basic workflow to help you get started with Actions
2 |
3 | name: add_contributor
4 |
5 | # Controls when the action will run. Triggers the workflow on push or pull request
6 | # events but only for the master branch
7 | on:
8 | push:
9 | branches: []
10 |
11 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel
12 | jobs:
13 | # This workflow contains a single job called "build"
14 | build:
15 | # The type of runner that the job will run on
16 | runs-on: ubuntu-latest
17 |
18 | # Steps represent a sequence of tasks that will be executed as part of the job
19 | steps:
20 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
21 | - uses: actions/checkout@v2
22 |
23 | # 팀원 자동 추가 액션
24 | - name: Contribute List
25 | uses: akhilmhdh/contributors-readme-action@v1.1
26 | env:
27 | GITHUB_TOKEN: ${{ secrets.ACTIONS_TOKEN }}
28 | with:
29 | header: Teammates
30 |
--------------------------------------------------------------------------------
/.github/workflows/update_readme_toc.yml:
--------------------------------------------------------------------------------
1 | name: update_md_title
2 |
3 | on:
4 | push:
5 | branches: [ master ]
6 | jobs:
7 | build:
8 | runs-on: ubuntu-latest
9 | steps:
10 | - name: Check out repo
11 | uses: actions/checkout@v2
12 | with:
13 | fetch-depth: 0
14 | - name: Set up Python
15 | uses: actions/setup-python@v1
16 | with:
17 | python-version: 3.8
18 | - name: Configure pip caching
19 | uses: actions/cache@v1
20 | with:
21 | path: ~/.cache/pip
22 | key: ${{ runner.os }}-pip-${{ hashFiles('**/py-package.txt') }}
23 | restore-keys: |
24 | ${{ runner.os }}-pip-
25 | - name: Update README
26 | run: |-
27 | python update_readme.py
28 | cat README.md
29 | - name: Commit files
30 | run: |-
31 | git diff
32 | git config --global user.email "readme-bot@example.com"
33 | git config --global user.name "README-bot"
34 | git diff --quiet || (git add README.md && git commit -m "Updated README")
35 | git push
36 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | *.png
3 | *.jpeg
4 | *.gif
5 | __pycache__/*
6 | lib/__pycache__/*
7 | /.idea
8 |
--------------------------------------------------------------------------------
/.log/readme_log.json:
--------------------------------------------------------------------------------
1 | {
2 | "data": "Hello"
3 | }
--------------------------------------------------------------------------------
/Javascript/Asynchronous.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 비동기(Asynchronous)
3 | date: 2020-06-19 00:00:00
4 | author: snowjang24
5 | category: Javascript
6 | ---
7 |
8 | # 비동기(Asynchronous)
9 |
10 | ## 여는 말
11 |
12 | 자바스크립트를 공부할 때, 비동기라는 단어를 접하는 순간이 오게 된다. 중요한 개념임에도 불구하고 비동기라는 말 자체에서 이미 좌절감을 겪는 사람들이 많다. 자바스크립트를 잘 활용하기 위해, 잘 작동하는 웹을 만들기 위해서는 필수적으로 이해해야 하는 과정이지만 그 벽이 높아 대충 이해하고 넘어가는 일이 부지기수다. 나 역시 처음에 대충 이해하고 넘어갔다. 이번 기회에 A to Z, 세부적인 이해하기 위해 이 글을 쓰려 한다.
13 |
14 | ## 비동기에 들어가기에 앞서
15 |
16 | 비동기와 동기에 대해 검색하면 가장 먼저 아래와 같은 사진을 마주치게 된다. 동기는 일이 끝나기를 기다렸다가 끝나면 다음 일을 순차적으로 처리하고, 비동기는 기다림 없이 다음 일을 바로 실행하는구나 라는 간단하게 이해했다. 하지만 그래서 자바스크립트는 동기로 작동하나? 비동기는 어디에 쓰이는 거지? 라는 의문이 든다.
17 |
18 | 
19 |
20 | [Synchronous, Asynchronous](https://velog.io/@cyongchoi/%EB%B9%84%EB%8F%99%EA%B8%B0asynchronous-%EA%B0%9C%EB%85%90)
21 |
22 | 이러한 의문을 해결하기 위해 필요한 개념과 원리에 대해 알아보며 자바스크립트에서의 비동기에 대해 자세히 알아보려 한다. 가장 먼저 아래의 개념들에 대해 자세히 알아보며, 자바스크립트의 비동기에 대한 오해를 풀어보자.
23 |
24 | - 자바스크립트는 Single Thread 기반 언어
25 | - 자바스크립트의 브라우저와 Node에서의 동작
26 |
27 | ## 자바스크립트는 Single Thread 기반 언어
28 |
29 | 자바스크립트는 **싱글 쓰레드(Single Thread)**기반의 언어다. 쓰레드가 하나라는 말은 한번에 하나의 작업만 처리 가능하다는 뜻이다. 하지만, 우리가 자바스크립트를 사용하는 환경인 Node는 여러 개의 HTTP요청을 처리하고, 브라우저는 이벤트 처리나 애니메이션 실행 등 다양한 일을 동시에 처리한다. 마치 싱글 쓰레드가 아닌 것처럼 여러 작업을 동시에 처리한다. 마치 멀티 쓰레드처럼 작동한다.
30 |
31 | 
32 |
33 | [싱글 스레드와 멀티 스레드](https://blog.lgcns.com/1084)
34 |
35 | ### 동시성과 병렬성
36 |
37 | 싱글 쓰레드와 비교 설명을 위해, 멀티 쓰레드에 대해 반드시 알고 넘어가야 하는 부분이 있다. 바로 **동시성(Concurrency)**과 **병렬성(Parallelism)**이다.
38 |
39 | **동시성(Concurrency, 병행성이라 부르기도 함)**은 싱글 코어에서 멀티 쓰레드를 동작 시키는 방식으로 멀티 태스팅을 위해 여러 개의 쓰레드가 번갈아가면서 실행되는 성질을 뜻한다. 보통 자바와 같은 객체 지향 언어들은 멀티 스레드를 통해 동시성을 진행한다.
40 |
41 | **병렬성(Parallelism)**은 한 개 이상의 스레드를 포함하는 각 코어들이 동시에 실행되는 성질을 뜻한다. 멀티 코어에서 멀티 스레드를 동작시키는 방식이다.
42 |
43 | 동시성은 동시에 실행되는 것 같지만 실제로는 그렇지 않고, 병렬성은 실제로 동시에 실행되는 차이가 있다. 결과적으로 둘 다 **멀티 쓰레드의 동작 방식**이다. 두 동작 방식의 차이에 대한 아래의 그림을 보면 이해가 빠를 것이다.
44 |
45 | 
46 |
47 | ### Single Thread와 Multi Thread
48 |
49 | 아래의 이미지는 싱글 쓰레드와 멀티 쓰레드의 작동 방식에 대해 잘 설명하고 있다. 여기서 Object는 쓰레드를 의미하는 것이 아니다.
50 |
51 | 
52 |
53 | [Performance comparison of single-threaded and multi-threaded execution](https://www.researchgate.net/figure/Performance-comparison-of-single-threaded-and-multi-threaded-execution_fig2_29528663)
54 |
55 | 위의 이미지와 아래의 이미지는 함께 보면 좀 더 이해가 편하다. 각각의 차이가 명확하게 보인다.
56 |
57 | 
58 |
59 | [Parallelism vs. Concurrency](http://www.dietergalea.com/parallelism-concurrency/)
60 |
61 | 이제 다시 돌아와서, 우리가 집중해야하는 부분은 **(a)single-threaded**와 **(b)multi-threaded(single active thread)**다.
62 |
63 | 
64 |
65 | [Performance comparison of single-threaded and multi-threaded execution](https://www.researchgate.net/figure/Performance-comparison-of-single-threaded-and-multi-threaded-execution_fig2_29528663)
66 |
67 | 어디서 많이 본 모양이다. 비동기와 동기...
68 |
69 | 
70 |
71 | [Synchronous, Asynchronous](https://velog.io/@cyongchoi/%EB%B9%84%EB%8F%99%EA%B8%B0asynchronous-%EA%B0%9C%EB%85%90)
72 |
73 | 일단 싱글 쓰레드, 멀티 쓰레드에 대해 이해를 했으면 다음으로 넘어가자.
74 |
75 | ## 자바스크립트의 브라우저와 Node에서의 동작
76 |
77 | 자바스크립트 엔진(V8)은 **단일 호출 스택(Single Call Stack)**을 사용한다. 요청이 들어올 때마다 요청을 하나씩 순차적으로 호출 스택에 담아 처리한다. 이 부분에서 자바스크립트가 싱글 쓰레드라는 말이 납득이 된다.
78 |
79 | 그럼 대체 비동기 처리는 어떻게 하는 걸까? 동시성은?
80 |
81 | 이 부분을 해결하는 것이 바로 브라우저와 Node다. 브라우저와 Node의 동작 원리는 아래와 같이 도식화가 되어 있다. 자바스크립트의 동작 원리에 대해 공부할 때 자주 보던 그림이다. 아래의 이미지에서 볼 수 있듯이 `XMLHttpRequest`, `setTimeout`과 같이 비동기 호출을 하는 메서드는 모두 자바스크립트 엔진 밖의 영역에 정의되어 있다.
82 |
83 | 
84 |
85 | 
86 |
87 |
88 | ## 드디어 비동기!
89 |
90 | 결국 자바스크립트를 구동하는 엔진은 싱글 쓰레드가 맞고, 그 외부인 구동 환경(브라우저, Node)이 멀티 쓰레드기 때문에 비동기 처리가 가능하게 되는 것이다.
91 |
92 | 아래의 비동기 처리의 대표적인 예시를 한 번 살펴보자.
93 |
94 | ```jsx
95 | function func1() {
96 | console.log('func1');
97 | func2();
98 | return "End"
99 | }
100 | function func2() {
101 | setTimeout(function() {
102 | console.log('func2');
103 | }, 1000);
104 | func3();
105 | }
106 | function func3() {
107 | console.log('func3');
108 | }
109 |
110 | func1();
111 | ```
112 |
113 | 결과는 아래와 같다. 실행 시 블로킹 없이 순차적으로 비동기 방식으로 호출한다.
114 |
115 | ```bash
116 | func1
117 | func3
118 | "end"
119 | func2
120 | ```
121 |
122 | ## 결론
123 |
124 | 자바스크립트 자체로만 놓고 봤을 때는 싱글 쓰레드 기반 언어이기 때문에 동기적으로 처리된다. 하지만 이 자바스크립트를 구동하는 브라우저나 Node와 함께이기 때문에 멀티 쓰레드 그 중에서 동시성을 지원하기 때문에 비동기 처리가 가능하다. 작동방식에 대해 유념하여 비동기와 관련된 Promise, async-await를 활용하면 좋을 것 같다.
125 |
126 | ## 참고
127 |
128 | - [동시성과 병렬성](https://yolojeb.tistory.com/10)
129 | - [테이터 홍수시대, 이제는 선택이 아닌 필수! 동시성 프로그래밍](https://blog.lgcns.com/1084)
130 | - [동시성 관련 개념](https://medium.com/@ahaljh/%EB%8F%99%EC%8B%9C%EC%84%B1-%EA%B4%80%EB%A0%A8-%EA%B0%9C%EB%85%90-d2f3e6a62b99)
131 | - [Parallelism vs. Concurrency](http://www.dietergalea.com/parallelism-concurrency/)
132 | - [자바스크립트와 이벤트 루프](https://meetup.toast.com/posts/89)
133 | - [자바스크립트는 어떻게 작동하는가: 이벤트 루프와 비동기 프로그래밍의 부상, async/await을 이용한 코딩 팁 다섯 가지](https://engineering.huiseoul.com/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%EB%8A%94-%EC%96%B4%EB%96%BB%EA%B2%8C-%EC%9E%91%EB%8F%99%ED%95%98%EB%8A%94%EA%B0%80-%EC%9D%B4%EB%B2%A4%ED%8A%B8-%EB%A3%A8%ED%94%84%EC%99%80-%EB%B9%84%EB%8F%99%EA%B8%B0-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D%EC%9D%98-%EB%B6%80%EC%83%81-async-await%EC%9D%84-%EC%9D%B4%EC%9A%A9%ED%95%9C-%EC%BD%94%EB%94%A9-%ED%8C%81-%EB%8B%A4%EC%84%AF-%EA%B0%80%EC%A7%80-df65ffb4e7e)
134 | - [동기와 비동기 방식(Asynchronous processing model)](https://webclub.tistory.com/605)
--------------------------------------------------------------------------------
/Javascript/Basic_movement.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 자바스크립트 동작 원리
3 | date: 2020-06-25 00:00:00
4 | author: jinsunee
5 | category: Javascript
6 | ---
7 |
8 | # 자바스크립트 동작 원리
9 |
10 | ## 브라우저 동작 원리
11 |
12 | 브라우저는 크게 렌더링 엔진, 자바스크립트 엔진으로 나뉜다.
13 | 사용자가 참조하고자 하는 페이지를 서버에게 요청 후 그에 대한 응답을 화면에 보여주는 일을 한다.
14 |
15 | - 렌더링 엔진 - 서버로부터 받은 HTML, CSS은 브라우저 렌더링 엔진의 HTML파서, CSS 파서에 의해 DOM, CSSOM 트리가 만들어지고 렌더 트리로 결합된다. 렌더 트리를 기반으로 브라우저는 웹페이지를 표시한다.
16 | - 자바스크립트 엔진 - JS로 작성한 코드를 해석하고 실행하는 인터프리터이다. 렌더링 엔진의 HTML 파서가 DOM 생성 프로세스를 하던 중 스크립트 태그를 만나면, 자바스크립트 코드를 실행시키기 위해 자바스크립트 엔진에게 제어권한을 넘겨주게 된다. - DOM 트리가 다 형성되지 않았는데 자바스크립트에서 해당 DOM을 조작하려고 하면 문제가 발생하기 때문에 `
128 |
129 | ```
130 |
131 | ### Generate Chart
132 |
133 | ```html
134 |
135 | ```
136 | 먼저 차트를 만들기 위해서 chart의 div 엘리먼트를 만들어줘야 한다.
137 |
138 | ```javascript
139 | var chart = c3.generate({
140 | bindto: '#chart',
141 | data: {
142 | columns: [
143 | ['data1', 30, 200, 100, 400, 150, 250],
144 | ['data2', 50, 20, 10, 40, 15, 25]
145 | ]
146 | }
147 | });
148 | ```
149 | 차트를 create 할 때에는 c3 의 generate 메소드를 사용하면 된다. bindto 속성에 chart 엘리먼드 id 를 넣어준다.
150 | data 의 column 속성에 data 값 들을 넣어준다.
151 |
152 | ```javascript
153 | var chart = c3.generate({
154 | bindto: '#chart',
155 | data: {
156 | columns: [
157 | ['data1', 30, 200, 100, 400, 150, 250],
158 | ['data2', 50, 20, 10, 40, 15, 25]
159 | ],
160 | axes: {
161 | data2: 'y2'
162 | },
163 | types: {
164 | data2: 'bar'
165 | }
166 | },
167 | axis: {
168 | y: {
169 | label: {
170 | text: 'Y Label',
171 | position: 'outer-middle'
172 | },
173 | tick: {
174 | format: d3.format("$,")
175 | }
176 | },
177 | y2: {
178 | show: true,
179 | label: {
180 | text: 'Y2 Label',
181 | position: 'outer-middle'
182 | }
183 | }
184 | }
185 | });
186 | ```
187 | 
188 |
189 | 위 처럼 axes, axis 를 활용 해서 축을 더 추가해줄 수도 있다. axis 내부적으로 x, y 축을 갖고 있다.
190 | 축에는 label 속성을 사용해서 라벨 이름도 붙여줄 수 있다. types 옵션을 이용해 데이터의 차트 표현 타입을 정해줄 수 있다.
191 | tick 은 축에 찍히는 값을 의미하는데 format이라는 속성을 통해서 각 축에 데이터를 어떤식으로 띄울지 설정할 수 있다.
192 | 차트 타입에는 Line Chart, Area Chart, Bar Chart, Donut Chart 등 다양한 차트들이 있다.
193 |
194 | ### 특징
195 | 1. D3 보다 사용하기 쉽다.
196 | 2. D3 보다 차트 표현? 에 더 특화되어 있는 느낌(?)
197 |
198 | ## [Chart.js](https://www.chartjs.org/)
199 |
200 | Chart.js 도 유명한 차트 라이브러리 중 하나이다. 사용법이 직관적이고 문서화도 잘 되어 있다. D3.js 는 러닝커브가 가파른데에 비해 Chart.js 는 Javascript 만 알고 있으면 몇분 안에 쉽게 차트를 만들 수 있다.
201 | Canvas 를 이용하여 그리기 때문에 반응형 레이아웃에서도 문제가 없다고 한다.
202 | (canvas를 div 로 감싸주고나 직접 width, height를 vw, vh 등으로 지정해준다.)
203 |
204 | 지원 브라우저 : Chrome, Firefox, Internet Explorer 11, Edge, Safari
205 |
206 | ### Creating a Chart
207 |
208 | ```html
209 |
210 |
249 | ```
250 |
251 | 위 코드는 Chart.js 홈페이지 Introduction 섹션에 있는 가장 기본적인 코드이다. Chart.js 를 이번에 처음 보게 된 나도 코드만 보고 어떻게 흘러가는지 쉽게 파악할 수 있었다.
252 | 일단 new 키워드로 Chart 를 생성하고 type 속성으로 차트 type 을 정할 수 있고, data 속성에 필요한 데이터들을 바인딩 할 수 있다.
253 |
254 | ### Line 차트
255 | 
256 |
257 | ### Bar 차트
258 | 
259 |
260 | ### Radar 차트
261 | 
262 |
263 | etc...
264 |
265 | ### 특징
266 | 1. 비교적 쉽다.
267 | 2. 문서화가 잘 되어 있다.
268 | 3. 차트가 단순하고 간결하다.
269 | 4. 단순하고 간결한 만큼 더 복잡한 표현을 하기 위해서는 다른 라이브러리를 사용해야 한다.
270 |
271 | ## [AmCharts](https://amcharts.com)
272 |
273 | Amcharts 도 나름 차트 라이브러리를 고려할 때 빠지지 않고 등장하는 차트 라이브러리이다.
274 | 앞서 소개한 라이브러리 3가지와는 다르게 유료로 제공하고 있다. (amcharts 워터마크를 지우지 않고 사용하면 무료로 쓸 수 있다.)
275 | 유료인만큼 지원 항목이 다양하다. 대부분의 차트 라이브러리가 기본 자바스크립트 언어로만 쓰여 있지만,
276 | AmCharts 같은 경우에는 React, Vue, Angular 에서 사용은 물론 TypeScript, 웹팩, 코도바, 폰갭 등에서의 사용 가이드도 제공하고 있다.
277 |
278 | ### Creating a chart
279 |
280 | ```javascript
281 |
282 |
283 |
284 |
285 |
286 |
289 |
290 |
291 |
292 |
293 |
335 |
336 |
337 | ```
338 | 기본적인 차트를 생성하려고 할 때 위처럼 html 을 작성한다. c3 와 비슷하게 chart div 엘리먼트를 만들어 차트를 그린다.
339 |
340 | ### 특징
341 | 1. 유료이다.
342 | 2. 학습 곡선이 가파르다.
343 | 3. 다양한 스타일의 차트를 사용할 수 있다.
344 | 4. 자유도가 높다. (자유도가 높은 만큼 커스터마이징을 하려면 학습이 필요하다.)
--------------------------------------------------------------------------------
/S2_Round1/introduction-to-stateManagementTools.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: JS 상태관리 도구 개론
3 | date: 2020-11-19 19:00:00
4 | author: wooooooood
5 | category: S2_Round1
6 | ---
7 |
8 | # JS 상태관리 도구 개론
9 | ## 상태관리의 필요성
10 | - 상태(데이터)가 언제, 어디서, 왜, 어떻게 변화했는지 알기 어렵다.
11 | - 다수의, 흩어진 Component가 같은 상태를 공유할 때 이를 관리하는 것이 복잡하다.
12 | - Component 단위에서는 props를 통해 하위 component로 상태를 전달한다. Component가 증가한다면 비효율적인 작업이 생길 수 있다.
13 | 
14 |
15 | => 이를 개선하기 위해 상태관리 도구 Redux, MobX, Recoil(React) 등이 나타났다.
16 | => 이 글에서는 FW에 구애받지 않는 JS 상태관리 도구인 Redux, MobX에 대해 간단하게 설명한다.
17 |
18 | ## Redux
19 | > A Predictable State Container for JS Apps
20 | - Functional Programming
21 | - Subscribe하는 모든 Component가 접근 가능한 Centralized global store로 상태를 관리한다.
22 | - `Immutability`를 유지하기 위해 원본 객체를 수정하는 것이 아닌, 객체의 복사본을 만들어 **복사된 객체**를 갱신한다.
23 |
24 | ex.
25 | ```js
26 | const arr = ['a', 'b']
27 | const arrCopy = arr.concat('c')
28 | ```
29 |
30 | ### 단방향 데이터 흐름
31 | 
32 | - **View**: 보여주기만 하는 순수 컴포넌트
33 | - **Action**: `Type`을 가진 JS객체로, User input, Trigger 등의 `Event`라고 생각할 수 있다.
34 | - **Reducer**: 현재 State와 Action을 감지하여 State를 갱신(바꿔치기)한다. `EventListener`와 유사하다.
35 | - **Store**: 현재 Redux의 State, 읽기 전용
36 | - **Middleware**: Action을 통해서 State를 바꾸기 전에 API호출 등 데이터가 변경되는 로직이 있을 때 비동기 작업 등을 처리할 수 있다.
37 |
38 | ### 단점
39 | - 애플리케이션이 복잡해질수록 `redux-saga`, `redux-thunk`, `redux-pack` 등의 라이브러리를 추가로 알아보는 것에 대한 부담?
40 |
41 | ## MobX
42 | > Simple, scalable state management
43 | - Object-Oriented Programming and Reactive Programming
44 |
45 | ### 데이터 흐름
46 | 
47 | - **Application state**: Objects, arrays, primitives 등의 model이며 이러한 값들을 `data cell`이라고 한다.
48 | - **Derivation**: Application에서 자동으로 계산되는 모든 값.
49 | - **Reaction**:Derivation과 비슷하다. 차이점은, 값을 생성하지 않는 함수이며 Task를 수행하기 위해 자동으로 수행되며 주로 I/O 작업과 연관된다. (ex. DOM update, Network ..)
50 | - **Action**: State를 변경할 수 있는 모든 것을 의미하며 동기적으로 처리된다.
51 |
52 | ### 장점
53 | - 쉬운 편이다!
54 |
55 | ### 단점
56 | - 문서가 부실하다..
57 | - 개발자 도구가 불편하다!
58 | - 애플리케이션이 커질수록 복잡해진다 (Store가 여러개이기 떄문에)
59 |
60 | ## Reference
61 | - [TECH CONCERT: FRONT END 2019 - 데이터 상태 관리. 그것을 알려주마](https://www.youtube.com/watch?v=o4meZ7MRd5o&feature=youtu.be)
62 | - [Why and When to use Redux](https://blog.usejournal.com/why-and-when-to-use-redux-b57f7dae9269)
63 | - [Redux overview](https://redux.js.org/tutorials/essentials/part-1-overview-concepts)
64 | - [MobX overview](https://mobx.js.org/getting-started)
65 |
--------------------------------------------------------------------------------
/S2_Round1/lazyloading.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: LazyLoading
3 | date: 2020-11-19 00:00:00
4 | author: chjjh0
5 | category: S2_Round1
6 | ---
7 |
8 | ## 👀특징
9 |
10 | 
11 |
12 | - 의미: 페이지 진입 또는 현재 보여지는 화면을 기준으로 필요하지 않은 자원들은 필요할 때 로드
13 | - 활용점: Pagination, Infinite Scroll, Code Splitting
14 | - 장점
15 | 1.서버 부하 감소 및 사용자 속도 개선
16 | - 단점
17 | 1.스크롤에 따라 이미지를 로딩하기에 부자연스럽거나 버벅이게 로딩되는 현상을 볼 수 있음
18 | 2.검색엔진에 걸리지 않아 SEO 취약하나 콘텐츠에 대한 링크를 제공하여 보완
19 | [https://scarlett-dev.gitbook.io/all/it/lazy-loading](https://scarlett-dev.gitbook.io/all/it/lazy-loading)
20 | - 주의사항
21 | [https://black7375.tistory.com/72](https://black7375.tistory.com/72)
22 | 1.첫 화면에는 하지 않는 것이 나음
23 | ( 콘텐츠 로드를 미뤄두기 때문에 SEO 좋지 않은 것으로 추정 )
24 | 2.스크롤을 내려야 이미지 로드를 시작해 느려보일수도 있음
25 | 3.자리 표시자가 없으면 레이아웃 변경이 생길 수 있음
26 | ( placeholder image가 없다면 브라우저 렌더링 악역향 )
27 | 4.JS로 이미지 크기가 큰 이미지를 로딩 시 잠시 반응하지 않을 수 있음
28 | ( 네트워크 환경에 따른 UX 저하 )
29 | 5.로드가 실패할 수 있음
30 | ( 네트워크 요청이 실패한 경우 placeholder image나 대체이미지가 없다면 UX 저하 )
31 | 6. JS를 사용하지 못할 수도 있음
32 | ( 브라우저의 JS 기능이 꺼있다면 동작X )
33 |
34 | ---
35 |
36 |
37 |
38 |
39 | > HTML or Vanilla
40 |
41 | ### 1. loading 속성을 활용한 방식
42 | * img, iframe 에서 loading='lazy' 속성 사용 가능
43 | * 현재 실험단계
44 |
45 | 관련 포스팅
46 |
47 | [https://meetup.toast.com/posts/183](https://meetup.toast.com/posts/183)
48 | [https://developer.mozilla.org/en-US/docs/Web/Performance/Lazy_loading](https://developer.mozilla.org/en-US/docs/Web/Performance/Lazy_loading)
49 | [https://github.com/mfranzke/loading-attribute-polyfill](https://github.com/mfranzke/loading-attribute-polyfill)
50 |
51 |
52 |
53 | ### 2. preload 속성을 활용한 방식
54 | * video 태그에 preload=none 설정으로 로드 지연
55 |
56 | 관련 포스팅
57 |
58 | [https://web.dev/lazy-loading-video/](https://web.dev/lazy-loading-video/)
59 | [https://scarlett-dev.gitbook.io/all/it/lazy-loading](https://scarlett-dev.gitbook.io/all/it/lazy-loading)
60 |
61 |
62 |
63 | ### 3. scroll, resize, orientationChange 이벤트를 활용한 방식
64 | * 코드 참고한 포스팅: [https://frontdev.tistory.com/entry/Image-Lazy-Loading-기법](https://frontdev.tistory.com/entry/Image-Lazy-Loading-%EA%B8%B0%EB%B2%95)
65 | * 코드 링크: [https://codepen.io/imagekit_io/pen/MBNwKB](https://codepen.io/imagekit_io/pen/MBNwKB)
66 | * 링크된 코드의 동작 설명
67 |
68 | ```javascript
69 | HTML구조는 여러 개의 img 요소로 되어 있고 상단 3개의 img 요소에만 src 속성이 설정되어 있어, 초기에 3개의 이미지만 노출
70 |
71 | 2 lazyloadImages 변수에 img.lazy 클래스명을 가진 img 요소들의 배열 할당
72 | 26~28 scroll, resize, orientationChange 이벤트가 발생하면, 5 lazyload 함수를 실행
73 | 10 lazyloadThrottleTimeout 변수에 setTimeout 을 할당하여 추후 6~8 clearTimeout에 활용
74 | 11~17 lazyloadImages 배열을 반복하며 img의 offsetTop이 window.innerHeight + scrollTop 보다 작으면 data-src에 할당된 이미지 URL을 img src 속성에 할당하고 class에서 lazy를 제거하여 이미지를 노출
75 | 18~22 lazyloadImages가 빈 배열이면 scroll, resize, orientationChange 이벤트를 제거
76 | ```
77 |
78 |
79 |
80 |
81 | > React
82 | ### 1. React.lazy
83 |
84 | * 컴포넌트 단위로 분리 가능
85 | * 라우트 단위로 도입하길 권장
86 | [https://ko.reactjs.org/docs/code-splitting.html#route-based-code-splitting](https://ko.reactjs.org/docs/code-splitting.html#route-based-code-splitting)
87 |
88 | * Img 태그에 적용한 사례
89 | [https://velog.io/@ansrjsdn/React.lazy-%EC%82%AC%EC%9A%A9%ED%95%B4%EB%B3%B4%EA%B8%B0](https://velog.io/%40ansrjsdn/React.lazy-%EC%82%AC%EC%9A%A9%ED%95%B4%EB%B3%B4%EA%B8%B0)
90 |
91 | * 주의사항
92 | - 아직 SSR에서는 지원 x
93 | [https://ko.reactjs.org/docs/code-splitting.html#reactlazy](https://ko.reactjs.org/docs/code-splitting.html#reactlazy)
94 | - Named Export 사용
95 | [https://ko.reactjs.org/docs/code-splitting.html#route-based-code-splitting](https://ko.reactjs.org/docs/code-splitting.html#route-based-code-splitting)
96 |
97 |
98 | ### 2. react-lazyload
99 |
100 | * resize, scroll 기반으로 작동되는 것으로 추정
101 |
102 | 관련 포스팅
103 |
104 | [https://github.com/twobin/react-lazyload](https://github.com/twobin/react-lazyload)
105 |
106 |
107 |
108 | ### 3. react-virtualized
109 |
110 | * 현재 사용자에 보여지는 부분만 렌더링하여 최적화
111 |
112 | 관련 포스팅
113 |
114 | [https://github.com/bvaughn/react-virtualized](https://github.com/bvaughn/react-virtualized)
115 | [https://bvaughn.github.io/react-virtualized/#/components/List](https://bvaughn.github.io/react-virtualized/#/components/List)
116 | [https://coffeeandcakeandnewjeong.tistory.com/52](https://coffeeandcakeandnewjeong.tistory.com/52)
117 |
118 |
119 |
120 | ### 4. react-window
121 |
122 | * react-virtualized와 같은 역할이며 보다 경량화
123 |
124 | 관련 포스팅
125 |
126 | [https://react-window.now.sh/#/examples/list/fixed-size](https://react-window.now.sh/#/examples/list/fixed-size)
127 | [https://velog.io/@pandati0710/React-Windowing](https://velog.io/%40pandati0710/React-Windowing)
128 |
129 |
130 |
131 |
132 |
133 | > Vue
134 | ### 1. Code Splitting with webpack
135 |
136 | * webpack으로 chunk 파일 분할하여 분할된 파일에 대한 요청이 들어왔을 때 서빙
137 |
138 | 관련 포스팅
139 |
140 | [https://gongzza.github.io/javascript/vuejs/vue-lazy-loading-with-webpack/](https://gongzza.github.io/javascript/vuejs/vue-lazy-loading-with-webpack/)
141 | [https://router.vuejs.org/kr/guide/advanced/lazy-loading.html](https://router.vuejs.org/kr/guide/advanced/lazy-loading.html)
142 |
143 |
144 | ### 2. vue-lazyload
145 |
146 | * resize, scroll 기반으로 동작하지만, intersection observer도 활용 가능
147 |
148 | 관련 포스팅
149 |
150 | [https://github.com/hilongjw/vue-lazyload#readme](https://github.com/hilongjw/vue-lazyload#readme)
151 |
--------------------------------------------------------------------------------
/S2_Round1/nextjs_tutorial_ch1.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: nextjs_tutorial_ch1
3 | date: 2020-11-17 12:00:00
4 | author: dev-owen
5 | category: S2_Round1
6 | ---
7 |
8 | # Next.js에 대해서 알아보자 #1. Intro
9 |
10 | Next.js는 React에서 기존에 CSR(Client Side Rendering)의 특징에 더하여 SSR(Servers Side Rendering)을 혼합하여 운영환경에서 최적의 퍼포먼스를 낼 수 있게 도와주는 프레임워크이다. 2020년 11월 현재 버전 10.0.1이 나와있으며 다음과 같은 기능들을 지원한다.
11 |
12 | - 페이지 기반 라우팅 (동적 라우팅)
13 | - 데이터 패칭
14 | - 빠른 성능을 위한 코드 스플리팅
15 | - CSS in JS
16 | - 이미지 최적화
17 | - 빠른 컴포넌트 재활성화
18 | - 정적 파일 처리
19 | - 타입스크립트
20 | - 환경 변수
21 | - 브라우저 지원
22 |
23 | 각각에 대한 자세한 사항들은 이후에 하나씩 알아보고자 한다.
24 |
25 |
26 |
27 | Next.js는 SPA에서 CSR이 가질 수 밖에 없는 한계들을 보완해 주는 도구이다. SSR과 CSR에 대한 포스팅 참고
28 |
29 | CSR은 초기 로딩 속도가 전통적인 SSR 방식에 비해 길다. 그 이유는 브라우저에서 화면을 렌더링하는데 필요한 모든 파일(HTML, CSS, JS, 이미지와 같은 대용량 파일 등)을 전부 받아온 다음 렌더링을 하기 때문이다. 그리고 이처럼 초기 로딩속도가 느리면 SEO(검색 엔진 최적화) 측면에서도 불리할 수밖에 없게 된다. 이러한 단점들을 극복하기 위한 도구 중 하나가 React에서는 Next.js인 것이다.
30 |
31 | Next.js를 통해서 Node 서버 기반의 페이지를 만들 수가 있는데 (SSR), 페이지를 이동할 때마다 필요한 JSON 데이터를 가져올 수도 있고 (CSR) 이 두 가지 렌더링 방식을 필요에 맞게 적절하게 섞어쓸 수 있다는 점이 장점이다. 예를 들어 블로그와 같이 정적인 컨텐츠가 많은 페이지는 SSR, 페이스북 뉴스피드 같이 실시간으로 사용자 인터랙션이 많은 페이지는 CSR을 사용할 수가 있다.
32 |
33 | 성능을 최적화 하는 과정에서도 Next.js가 많은 도움을 준다. 그 중 한 가지 방법은 pre-rendering이다. 서버사이드에서 빌드 중 실행되는 getStaticProps 함수를 통해 페이지 렌더링에 필요한 데이터를 받아오고 이와 같이 pre-rendering된 페이지는 초기 페이지 로딩이 CSR에 비해 빠르며, SEO 관점에서도 유리하다. 또 다른 방법은 code-splitting이다. 라우트 기반의 코드 스플리팅은 한 번에 파싱&컴파일 되어야 하는 코드의 양을 최소화 시켜주며 결과적으로 페이지 로드 시간의 단축을 이끌어낼 수 있다.
34 |
35 |
36 |
37 | 간단한 Next.js app을 만들면서 연습해 보자
38 |
39 | ```shell script
40 | mkdir nextjs-tutorial
41 | cd nextjs-tutorial
42 | npm init
43 | npm install --save next react react-dom
44 | ```
45 | package.json 파일에 간단한 스크립트를 추가한다.
46 |
47 | ```javascript
48 | // package.json
49 | {
50 | "scripts": {
51 | // ...
52 | "dev": "next",
53 | "build": "next build",
54 | "start": "next start"
55 | }
56 | }
57 | ```
58 |
59 | next.js는 pages 폴더에 route와 동일한 이름의 컴포넌트로 만들어야 한다는 규칙이 있다. 예를 들어 url이 /about 이면 해당 컴포넌트는 pages/about.jsx와 같이 만들어 져야 한다.
60 | ```javascript
61 | // pages/about.jsx
62 |
63 | import React from 'react';
64 |
65 | const About = (props) => {
66 | const {message} = props;
67 |
68 | return (
69 |
70 |
Hello World!
71 |
{message}
72 |
73 | );
74 | };
75 |
76 | export async function getStaticProps(context) {
77 | return {
78 | props: {
79 | message: `Next.js`
80 | }
81 | };
82 | };
83 |
84 | export default About;
85 | ```
86 |
87 |
88 | 이와 같이 컴포넌트를 하나 만들어 준 후
89 | ```shell script
90 | npm run build && npm run dev
91 | ```
92 |
93 | 빌드 후 실행하면 .next 폴더가 하나 생성된다. 그리고 나서 localhost:3000에 방금 만든 app이 실행되고 있는 것을 볼 수 있다.
94 |
95 | 이렇게 정말 간단한 next.js app을 하나 시작해 보았다. 다음 포스팅에서는 페이지를 추가하고, 동적 데이터를 추가하는 작업을 하는 튜토리얼을 포스팅 해 보려고 한다.
96 |
97 |
98 | ## 참고자료
99 | - [Next.js 공식문서](https://nextjs.org/)
100 | - [Next.js로 Static Site 만들기](https://medium.com/@pks2974/nextjs-%EB%A1%9C-static-site-%EB%A7%8C%EB%93%A4%EA%B8%B0-f9ab83f29e7)
101 | - [Next.js 튜토리얼](https://brunch.co.kr/@hee072794/81)
102 | - [nextjs는 어떻게 동작하는가?](https://blueshw.github.io/2018/04/15/why-nextjs/)
103 |
104 |
--------------------------------------------------------------------------------
/S2_Round1/rxjs.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: RxJS R아보기
3 | date: 2020-11-19 00:00:00
4 | author: symoon
5 | category: S2_Round1
6 | ---
7 |
8 |
9 | # RxJS R아보기
10 |
11 |
12 | ## RxJS란 무엇인가
13 |
14 | > "An API for asynchronous programming with observable streams"
15 |
16 | **R**eactive e**X**tensions Library for **J**ava**S**cript의 약자로, 옵저버 패턴을 통해 이벤트 스트림을 제어하여 비동기 프로그래밍을 처리하는 (API를 제공하는) 라이브러리이다. 현재 안정화 버전은 6이며, 베타 버전인 7까지 나와있다. Angular에는 이 RxJS가 기본적으로 내장되어 있다.
17 |
18 |
19 |
20 | ## Reactive? Stream? Observable? 그게 다 뭔데?!
21 |
22 | ### Reactive Programming
23 |
24 | 
25 |
26 | 리액티브 프로그래밍은 말그대로 "반응형"으로 프로그래밍하는 것이다.
27 | 명령형 프로그래밍은 개발자가 작성한 코드에 따라 순서대로 코드가 실행되며, 데이터가 필요하면 요청을 해야한다(외부 환경에서 데이터를 당겨오는 방식인 Pull). 반면, 리액티브 프로그래밍은 데이터 스트림을 구독하고 있다가 데이터에 어떠한 변화가 감지되었을 때 그것에 **반응**하여 데이터를 얻는 방식이다(외부 환경이 데이터를 내보내는 방식인 Push).
28 |
29 | ### Stream
30 | 데이터를 하나의 연속적인 흐름으로 보는 것이다. 위에서 언급했듯, 리액티브 프로그래밍 방식에서는 이 데이터 스트림을 구독한다. 리액티브 프로그래밍 방식에서 이 스트림은 Observable 객체로 만들어진다.
31 |
32 | ### Observable
33 | Observable은 데이터 스트림을 만들고 내보내는 객체이고, Observer는 이 옵저버블 객체가 내보낸 데이터를 받아 가공하는 역할을 하는 객체이다.
34 |
35 | #### Observable 생성
36 | Observable객체를 생성하는 연산자는 `create`, `from`, `fromEvent`, `fromPromise`, `of` 등이 있다.
37 | 이중 일반적으로 `from`, `fromPromise`, `of`가 많이 사용된다.
38 |
39 | 일반적으로 이벤트 리스너를 등록하는 방식은 아래와 같다.
40 |
41 | var button = document.querySelector('button');
42 | button.addEventListener('click', () => console.log('Clicked!')); //버튼 클릭 이벤트가 발생하면 콘솔로그에 'Clicked!'를 찍음
43 |
44 |
45 | RxJS에서는 연산자를 이용하여 아래와 같이 생성할 수 있다.
46 |
47 | var button = document.querySelector('button');
48 |
49 | Rx.Observable.fromEvent(button, 'click') //클릭 이벤트를 emit하는 Observable 객체를 생성함
50 | .subscribe(() => console.log('Clicked!')); //체이닝을 이용해 해당 Observable 객체를 구독하며, Observable에서 데이터 전달시 콜백함수
51 |
52 |
53 | * 참고
54 | fromEvent 연산자는 이벤트를 Observable 시퀀스로 만들어줌
55 | `fromEvent(target: EventTargetLike, eventName: string, selector: function): Observable`
56 |
57 |
58 | #### 옵저버 메소드
59 | `onNext` 새로운 데이터를 내보낼 때 호출되는 메소드. 파라미터를 통해 옵저버블을 전달한다.
60 | `onError` 데이터가 생성되지 않았거나 오류가 발생할 경우 호출되는 메소드. 이 메소드가 호출되면 `onNext`나 `onComplete`가 호출되지 않음.
61 | `onComplete` 오류가 없으면 마지막 `onNext`를 호출한 후 호출되는 메소드
62 |
63 |
64 | #### 연산자
65 | RxJS에서 제공하는 대부분의 연산자는 이 옵저버블 객체에서 동작하고, 옵저버블 객체를 반환한다. 즉, 연산자 체이닝이 가능하다. 이 연산자 체인은 순서에 따라 결과가 달라지므로 순서대로 실행되어야한다.
66 | 대표적인 연산자는 `create`, `map`, `merge` 등이 있다.
67 |
68 |
69 | #### 예제코드
70 | 코드
71 |
72 | import { Observable } from 'rxjs';
73 |
74 | //Observable 객체를 생성한다.(관찰 가능한 상태로 만드는 것)
75 | //해당코드를 구독하면 즉시 값(1,2,3)을 내보내고, 1초 후에 4를 내보낸뒤 완료처리된다.
76 | const observable = new Observable(subscriber => {
77 | subscriber.next(1);
78 | subscriber.next(2);
79 | subscriber.next(3);
80 | setTimeout(() => {
81 | subscriber.next(4);
82 | subscriber.complete();
83 | }, 1000);
84 | });
85 |
86 | console.log('just before subscribe'); //가장 먼저 실행된다.
87 |
88 | //위에서 생성한 observable을 구독한다.
89 | observable.subscribe({
90 | next(x) { console.log('got value ' + x); }, //새로운 값을 받아 콘솔을 찍는다.
91 | error(err) { console.error('something wrong occurred: ' + err); }, //에러가 발생했을 경우 콘솔을 찍는다.
92 | complete() { console.log('done'); } //마지막 next 실행 후 콘솔을 찍는다.
93 | });
94 | console.log('just after subscribe');
95 |
96 | 실행결과
97 |
98 | just before subscribe
99 | got value 1
100 | got value 2
101 | got value 3
102 | just after subscribe //RxJS는 동시에 여러 코드가 실행 가능하기 때문에, 1초 사에에 다음 코드가 실행됨.
103 | got value 4 //setTimeout으로 인해 1초 후 내보내짐
104 | done
105 |
106 |
107 | ## 그래서 RxJS, 뭐가 좋은건데?
108 | 콜백, 프로미스 방식의 한계를 보완할 수 있다. 한 번에 하나의 데이터만 처리할 수 있는 프로미스와 달리 데이터를 스트림으로 만들기 때문에 *동기 / 비동기에 관계 없이 데이터를 일관적으로 처리 가능*하며, *연속성을 가진 데이터를 처리*할 수 있다. 그러면서도 연산자 체이닝을 통해 비동기를 효과적으로 처리하며, 프로미스 방식은 한 번 실행되고 나면 요청을 취소할 수가 없지만 옵저버블은 취소가 가능하다.(`unsubscribe()`를 통해 구독 취소가 가능함)
109 | 또한 하나의 코드가 실행결과를 리턴할 때까지 기다릴 필요없이 다음 코드를 실행할 수 있어, *한 번에 여러 코드를 실행 가능*하다.
110 |
111 | 단점은, 초기 학습 비용이 크다는 점.
112 |
113 | ---
114 | ### 참고
115 |
116 | http://reactivex.io/
117 |
118 | https://velog.io/@dvmflstm/RxJS-Practice
119 |
120 | https://poiemaweb.com/angular-rxjs
121 |
122 | https://tienne.gitbooks.io/learnrxjs/content/
123 |
124 | https://hyunseob.github.io/2016/10/09/understanding-reactive-programming-and-rxjs/
125 |
126 | https://rxjs-dev.firebaseapp.com/
127 |
--------------------------------------------------------------------------------
/S2_Round1/storybook.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: storybook
3 | date: 2020-11-26 00:00:00
4 | author: chjjh0
5 | category: S2_Round1
6 | ---
7 |
8 | ## 특징
9 |
10 | - bootstrap, materialUI 같은 CSS 프레임워크에서 제공하는 요소 팔레트와 유사하게 컴포넌트를 관리
11 | - 컴포넌트 문서화를 통해 테스트, 유지보수에 유용
12 | - 다양한 환경에서 활용 가능 (HTML, React, Vue, Svelte 등)
13 |
14 |
15 |
16 |
17 | > 기본 사용법
18 |
19 | ```javascript
20 | // CRA로 React Project 생성
21 | npx create-react-app taskbox
22 |
23 | // 생성된 프로젝트에 스토리북 추가 & 초기화
24 | npx -p @storybook/cli sb init
25 |
26 | // 스토리북 실행
27 | npm run storybook
28 | ```
29 |
30 | ### sb init, 스토리북 초기화 [(링크)](https://storybook.js.org/docs/react/get-started/install)
31 |
32 | - 사용자가 직접 작성해야할 것들이 자동으로 추가됨
33 | 1. package.json에 dependencies, scripts 추가
34 |
35 | ```javascript
36 | "devDependencies": {
37 | "@storybook/addon-actions": "^6.1.3",
38 | "@storybook/addon-essentials": "^6.1.3",
39 | "@storybook/addon-links": "^6.1.3",
40 | "@storybook/node-logger": "^6.1.3",
41 | "@storybook/preset-create-react-app": "^3.1.5",
42 | "@storybook/react": "^6.1.3"
43 | }
44 | "scripts": {
45 | "start": "react-scripts start",
46 | "build": "react-scripts build",
47 | "test": "react-scripts test",
48 | "eject": "react-scripts eject",
49 | "storybook": "start-storybook -p 6006 -s public",
50 | "build-storybook": "build-storybook -s public"
51 | },
52 | ...
53 | ```
54 |
55 | 2. storybook 폴더에 storybook 설정 파일 추가
56 | 
57 |
58 |
59 | 3. stories 폴더에 보일러플레이트 파일들 추가
60 | 
61 |
62 |
63 |
64 |
65 | > 예제
66 |
67 | Button.js
68 |
69 | ```javascript
70 | export const Button = ({ primary, backgroundColor, size, label, ...props }) => {
71 | // primary or secondary 모드
72 | const mode = primary ? 'storybook-button--primary' : 'storybook-button--secondary';
73 |
74 | return (
75 |
83 | );
84 | };
85 | ```
86 |
87 | Button.css
88 |
89 | ```css
90 | .storybook-button {
91 | font-family: 'Nunito Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
92 | font-weight: 700;
93 | border: 0;
94 | border-radius: 3em;
95 | cursor: pointer;
96 | display: inline-block;
97 | line-height: 1;
98 | }
99 | .storybook-button--primary {
100 | color: white;
101 | background-color: #1ea7fd;
102 | }
103 | .storybook-button--secondary {
104 | color: #333;
105 | background-color: transparent;
106 | box-shadow: rgba(0, 0, 0, 0.15) 0px 0px 0px 1px inset;
107 | }
108 | .storybook-button--small {
109 | font-size: 12px;
110 | padding: 10px 16px;
111 | }
112 | .storybook-button--medium {
113 | font-size: 14px;
114 | padding: 11px 20px;
115 | }
116 | .storybook-button--large {
117 | font-size: 16px;
118 | padding: 12px 24px;
119 | }
120 | ```
121 |
122 | Button.stories.js
123 |
124 | ```javascript
125 | import React from 'react';
126 |
127 | import { Button } from './Button';
128 |
129 | export default {
130 | title: 'Example/Button',
131 | component: Button,
132 | argTypes: {
133 | backgroundColor: { control: 'color' },
134 | },
135 | };
136 |
137 | const Template = (args) => ;
138 |
139 | export const Primary = Template.bind({});
140 | Primary.args = {
141 | primary: true,
142 | label: 'Button',
143 | };
144 |
145 | export const Secondary = Template.bind({});
146 | Secondary.args = {
147 | label: 'Button',
148 | };
149 |
150 | export const Large = Template.bind({});
151 | Large.args = {
152 | size: 'large',
153 | label: 'Button',
154 | };
155 |
156 | export const Small = Template.bind({});
157 | Small.args = {
158 | size: 'small',
159 | label: 'Button',
160 | };
161 | ```
162 |
163 |
164 | 관련 링크
165 |
166 | - [args 설명](https://storybook.js.org/docs/react/writing-stories/args)
167 | - [control 설명](https://storybook.js.org/docs/react/essentials/controls#gatsby-focus-wrapper)
168 | - [storybook 5.2버전 이상부터 달라진 stories 작성 방법, CSF(Component Story Format)](https://storybook.js.org/docs/react/api/csf)
169 |
170 |
171 |
172 |
173 |
174 |
175 | > 실행 결과
176 |
177 | ### 화면 영역별 특징
178 |
179 | 실행결과 Sample
180 |
181 | - [react-dates](http://airbnb.io/react-dates/?path=/story/daterangepicker-drp--default)
182 | - [storybook](https://next--storybookjs.netlify.app/official-storybook/)
183 |
184 |
185 |
186 |
187 |
188 | - Preview 영역: Manager영역에서 선택한 story를 보여줌, iframe으로 되어있음
189 | - Manager 영역: story들을 폴더구조로 볼 수 있음
190 | - Preview, Manager 영역은 Storybook Communication Channel을 통해 데이터 전달
191 |
192 | 
193 |
194 | - manager 영역에 폴더 구조로 관리
195 | ( stories 파일에서 선언한 title: Example/Button )
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 | - stories파일과 컴포넌트의 props prototype을 참고하여 자동으로 아래와 같은 UI가 만들어짐
204 |
205 | 
206 |
207 |
208 |
209 | 관련 링크
210 |
211 | - [컴포넌트 공유 서비스](https://bit.dev/)
212 | - [공식문서의 예제](https://storybook.js.org/docs/examples/)
213 |
214 |
--------------------------------------------------------------------------------
/S2_Round2/css_in_js.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: CSS-in-JS
3 | date: 2020-12-03 12:00:00
4 | author: dev-owen
5 | category: S2_Round2
6 | ---
7 |
8 | # CSS in JS
9 |
10 | 기존에 CSS는 .css 파일에 작성해서 사용하였다. 프로젝트의 규모가 커지면서 항상 큰 스타일 시트를 유지하는 것이 번거로워졌고 그래서 새로운 아이디어가 나왔다. 스타일시트를 문서레벨이 아닌 컴포넌트 레벨로 추상화 하여 마치 모듈처럼 사용하는 것이다.
11 |
12 | CSS-in-JS는 JS를 사용하여 스타일을 선언적이고 유지보수가 가능한 방식으로 설명한다. JS를 CSS로 전환하는 고성능 컴파일러로, 런타임 및 서버 사이드에서 작동한다.
13 |
14 | 참고로 인라인 스타일과 CSS-in-JS는 다르다. 차이점이 있다면 인라인 스타일은 DOM 노드에 속성으로 추가하였고, CSS-in-JS는 DOM 상단에 `
51 |
52 |
Hello CSS-in-JS
53 | ```
54 |
55 | 기존에 CSS는 컴포넌트 기반을 고려하여 만들어진 적이 없었다. CSS-in-JS는 이러한 한계를 정확하게 해결할 수 있는 도구로 볼 수가 있다. 이 외에도 CSS-in-JS가 가진 장점은 다음과 같다.
56 |
57 | - 컴포넌트 단위의 추상화 (모듈화)
58 | - 진정한 분리 법칙
59 | - 부모 요소의 속성을 상속하지 않음
60 | - 스코프가 있는 선택자
61 | - 복잡한 어플리케이션에서 선택자 충돌을 피할 수 있다.
62 | - 현재 화면중에 사용중인 스타일만 DOM에 있음
63 | - 벤더 프리픽스(-webkit-, -moz, -webkit- 등)가 자동생성
64 |
65 | 현재 사용되고 있는 CSS-in-JS 라이브러리에는 다음과 같은 것들이 있다. (2020년 12월 기준)
66 | 
67 |
68 | ### styled-components (31.7K stars)
69 |
70 | ```jsx
71 | import React, { Component } from 'react';
72 | import styled from 'styled-components';
73 |
74 | const Title = styled.h1`
75 | color: white;
76 | `;
77 |
78 | const Wrapper = styled.div`
79 | background: black
80 | `
81 |
82 | class App extends Component {
83 | render() {
84 | return (
85 |
86 | Hello World!
87 |
88 | );
89 | }
90 | }
91 |
92 | export default App;
93 | ```
94 |
95 | ### emotions(12K stars)
96 |
97 | ```jsx
98 | // this comment tells babel to convert jsx to calls to a function called jsx instead of React.createElement
99 | /** @jsx jsx */
100 | import { css, jsx } from '@emotion/react'
101 |
102 | const color = 'white'
103 |
104 | const Box = css`
105 | padding: 32px;
106 | background-color: hotpink;
107 | font-size: 24px;
108 | border-radius: 4px;
109 | &:hover {
110 | color: ${color};
111 | }
112 | `
113 |
114 | render(
115 |
116 | Hover to change color.
117 |
118 | )
119 | ```
120 |
121 | ### 참고자료
122 |
123 | - [Thinking about emotion js vs styled component](https://ideveloper2.dev/blog/2019-05-05--thinking-about-emotion-js-vs-styled-component/)
124 | - [[번역] CSS-in-JS에 관해 알아야 할 모든 것](https://d0gf00t.tistory.com/22)
125 | - [Styled components vs Emotion js: A performance perspective](https://dev.to/meetdave3/styled-components-vs-emotion-js-a-performance-perspective-4eia)
126 |
--------------------------------------------------------------------------------
/S2_Round2/jsTDD.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: JS TDD 개론
3 | date: 2020-12-03 19:00:00
4 | author: wooooooood
5 | category: S2_Round2
6 | ---
7 |
8 | # JS TDD 개론
9 | ## TDD? Test-Driven-Development 테스트 주도 개발
10 | `테스트 케이스 생성→테스트→개발`의 짧은 개발 사이클을 반복적으로 수행하며 소프트웨어를 개발하는 프로세스.
11 | Red-Green Refactor 라고도 한다.
12 |
13 | 
14 |
15 |
16 | 1. 테스트 케이스 작성
17 | 2. 테스트 케이스를 통과하기 위한 최소한의 코드 작성
18 | 3. 표준에 맞도록 리팩토링
19 |
20 | *Uncle Bob describes TDD with three rules:*
21 | > 1. You are not allowed to write any production code unless it is to make a failing unit test pass.
22 | > 2. You are not allowed to write any more of a unit test than is sufficient to fail; and compilation failures are failures.
23 | > 3. You are not allowed to write any more production code than is sufficient to pass the one failing unit test.
24 |
25 | ### Why?
26 | 
27 | 기존의 개발 프로세스
28 |
29 | 
30 | TDD 프로세스
31 |
32 | - 설계 수정 시간 단축
33 | - 디버깅 및 버그 수정 시간 단축
34 | - 문제 발생 시 모듈별 테스트를 통해 문제 지점을 빠르게 파악 가능
35 | - Production 레벨에서 버그를 수정하는 것은 Software development lifecycle (SDLC)에서 버그를 수정하는 것보다 훨씬 큰 비용과 시간을 소모
36 | - Refactoring을 통해 Clean code를 유지
37 | - 객체지향적인 코드 개발
38 | - 세부 비즈니스 로직을 객체 내부로 숨겨 변경에 대응
39 | - 유지보수 및 재사용에 용이
40 |
41 | ### 단점
42 | - 테스트 코드를 작성, 유지하기 위한 비용과 시간
43 |
44 | ### How?
45 | - **Mock객체**를 생성하여 테스트
46 | - 변경할 수 없는 객체, 프레임워크, 외부 라이브러리는 Mock하지 않는다
47 | - ex. `Jest`에서 기본적으로 제공하는 mock functions
48 | ```js
49 | const myMockFunc = jest.fn().mockName("myMockFunc");
50 | const myExampleModule = jest.mock("./exampleModule");
51 | ```
52 | - **Private객체**의 테스트는?
53 | 1. Public 객체에서 커버되는 경우 테스트하지 않는다.
54 | 2. 리팩토링 고려. 해당 객체가 불필요한 책임을 가졌을 수 있다.
55 | 3. 접근 제한을 Public으로 변경 후 `@VisibleForTesting` 추가
56 | - 하나의 테스트에는 **하나의 기능**만 테스트한다
57 | - 대상 코드의 의도 표현
58 | - 데이터가 아닌 행위를 테스트한다 `given-when-then`
59 | - 테스트하기 어려운 코드가 있다면 *어떻게 하면 테스트할 수 있을까* 가 아닌, ***왜 테스트하기 어려울까***를 고민
60 |
61 | ### 종류
62 |
63 | 
64 |
65 | - **Unit Testing**: 가장 작은 단위 테스트(함수)
66 | - **Integration Testing**: 시스템 모델링에서 실제 기능, 퍼포먼스, 의존성, DB 데이터 등을 테스트
67 | - **UI Testing (E2E)**: 사용자 관점 테스트(UI)
68 |
69 | ## **Unit Test 단위 테스트**
70 | - 가장 작은 단위
71 | - 단위 테스트이므로 다른 Unit과 의존성이 있어서는 안된다.
72 | - 툴은 Mocha, Jasmine, Chai, Jest, Tape, Enzyme, Karma, Selenium, phantomjs 등 다양하며, 조합해서 사용할 수 있다.
73 |
74 | ### 예제 with `Jest`
75 | 1. `npm init -y` 으로 package.json을 생성한다.
76 | 2. `npm i -D jest` 로 development 모드로 jest를 실행한다.
77 | 3. package.json의 `test`를 수정한다. (test를 입력했을 때 jest를 실행하겠다는 의미)
78 |
79 | ```jsx
80 | "scripts": {
81 | "test": "jest"
82 | },
83 | ```
84 |
85 | 1. 테스트를 진행할 파일 `unit.test.js`를 생성한다.
86 | - `.test.js` suffix를 사용해야 한다.
87 | ```jsx
88 | const add = (a, b) => {
89 | return 1;
90 | };
91 |
92 | test('solution', () => {
93 | expect(add(1, 1)).toBe(2);
94 | });
95 | ```
96 | - 영어 문법과 비슷: expect ~ toBe (보통 value) / expect ~ toEqual (array 등의 object)
97 |
98 | 2. 테스트 `npm test ./unit.test.js` 결과는 반드시 실패한다. (Red)
99 |
100 | 
101 |
102 | 3. 성공하는 테스트 코드를 작성한다. (Green)
103 | ```jsx
104 | const add = (a, b) => {
105 | const num1 = a;
106 | const num2 = b;
107 |
108 | return num1 + num2;
109 | };
110 |
111 | test('solution', () => {
112 | expect(add(1, 1)).toBe(2);
113 | });
114 | ```
115 |
116 | 
117 |
118 | 4. 성공 확인 후 리팩토링한다. (Refactor)
119 | ```jsx
120 | const add = (a, b) => {
121 | return a+b;
122 | };
123 |
124 | test('solution', () => {
125 | expect(add(1, 1)).toBe(2);
126 | });
127 | ```
128 |
129 | ## **통합 테스트 Integration Test**
130 | - 앞서 unit테스트한 각각의 module들이 통합되었을 때 올바르게 동작하는지 확인하기 위함
131 | - 주요 목적은 module들 간의 인터페이스 동작 테스트
132 | - db, platform, environment등이 포함되어 테스트되므로 복잡해질 수 있음
133 |
134 | ### Integration Test with `Jest`
135 | 1. Unit test 방법과 거의 동일하며, [여기](https://gist.github.com/cowchimp/0158efe57df3b845927e450fc2b87eeb)에서 샘플 코드 일부를 가져왔다.
136 | ```js
137 | import { calculateTopEmployee } from './top-employee-provider';
138 | import { get } from './api-wrapper';
139 |
140 | jest.mock('./api-wrapper');
141 |
142 | test('returns the top-performing employee', async () => {
143 | mockApiResponse('/employees', [
144 | {name: 'foo', numOfSales: 1 },
145 | {name: 'bar', numOfSales: 2 }
146 | ]);
147 |
148 | const topEmployee = await calculateTopEmployee();
149 |
150 | expect(topEmployee).toEqual({ name: 'bar', numOfSales: 2 });
151 | });
152 |
153 | function mockApiResponse(endpoint, payload) {
154 | const successfulPromise = new Promise(resolve => process.nextTick(() => resolve(payload)));
155 |
156 | get.mockImplementationOnce(e => e === endpoint ? successfulPromise : Promise.reject());
157 | }
158 | ```
159 |
160 | ## **E2E테스트 (End to End Test)**
161 | - 사용자 입장 (환경 Latency, 관점 Workflow 등)에서의 테스트를 통해 사용자 경험 증대
162 | - Web, App 등에서의 시나리오, 기능 확인
163 | - 가장 확실하고 가장 필요한 테스트
164 |
165 | ### E2E with **`Cypress`**
166 | - [여기](https://softchris.github.io/pages/cypress.html)에 자세한 예제가 나와있어 일부 사진과 기능만을 가져왔다.
167 | - `Cypress`는 다양한 helper를 지원하여 사용자 action에 따른 테스트가 가능하다.
168 | - 현재는 Chrome과 Electron만 지원한다.
169 |
170 | 1. **Visit**
171 | ```js
172 | describe('My First Test', function() {
173 | it('Visits page', function() {
174 | cy.visit('https://example.cypress.io')
175 | })
176 | })
177 | ```
178 | 
179 |
180 |
181 | 2. **Interact**
182 | ```js
183 | cy.contains('type').click()
184 | ```
185 | 
186 |
187 |
188 | 3. **Debug**
189 | - 코드상에서 멈추고 싶은 위치에 `cy.pause()`를 삽입하여 디버깅할 수 있다.
190 | - `cy.debug()`를 삽입하면 개발자 도구에서 Args등의 로그를 추가로 확인할 수 있다.
191 | 
192 |
193 | ## Reference
194 |
195 | - [https://m.blog.naver.com/PostView.nhn?blogId=suresofttech&logNo=221569611618&proxyReferer=https:%2F%2Fwww.google.com%2F](https://m.blog.naver.com/PostView.nhn?blogId=suresofttech&logNo=221569611618&proxyReferer=https:%2F%2Fwww.google.com%2F)
196 | - [https://medium.com/hbsmith/e2e-test-알아보기-3c524862469d](https://medium.com/hbsmith/e2e-test-%EC%95%8C%EC%95%84%EB%B3%B4%EA%B8%B0-3c524862469d)
197 | - [https://velog.io/@rosewwross/unit-test](https://velog.io/@rosewwross/unit-test)
198 | - [https://www.slideshare.net/koreakihoon/tdd-112099012](https://www.slideshare.net/koreakihoon/tdd-112099012)
199 | - [https://docs.reactioncommerce.com/docs/testing-reaction](https://docs.reactioncommerce.com/docs/testing-reaction)
200 | - [https://www.softwaretestinghelp.com/what-is-integration-testing/](https://www.softwaretestinghelp.com/what-is-integration-testing/)
201 | - [https://gist.github.com/cowchimp/0158efe57df3b845927e450fc2b87eeb](https://gist.github.com/cowchimp/0158efe57df3b845927e450fc2b87eeb)
202 | - https://softchris.github.io/pages/cypress.html
203 |
--------------------------------------------------------------------------------
/S2_Round2/lighthouse.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: React 렌더링 측정(Lighthouse)
3 | date: 2020-11-26 00:00:00
4 | author: junCastle
5 | category: S2_Round2
6 | ---
7 |
8 | 이번에 다를 주제는 Lighthouse 라는 도구를 사용해서 React 웹의 렌더링 성능을 측정하는 방법과 프로파일링에 대해 알아보려고 한다.
9 |
10 | # React 렌더링 측정 with Lighthouse
11 |
12 | https://developers.google.com/web/tools/lighthouse?hl=ko 에 따르면
13 | Lighthouse는 웹 앱의 품질을 개선하는 오픈 소스 자동화 도구이다.
14 | Chrome 확장프로그램, 커맨드 라인에서, 노드 모듈에서 프로그램으로도 사용할 수 있다. Lighthouse에 확인할 URL을 지정하고, 페이지에 대한 테스트를 실행한 다음, 페이지에 대한 보고서를 생성한다. 여기에서 실패한 테스트는 앱을 개선하기 위해 할 수 있는 것에 대한 지표로 사용할 수 있다.
15 |
16 | Lighthouse가 생성해주는 지표에는 Performance, Accessibility, Base Practices, SEO, Progressive Web App 등이 있는데 React 웹의 렌더링 성능을 측정하기 위해서 Performance 지표를 중심으로 설명해보려 한다.
17 |
18 | ## Performance
19 |
20 | 
21 |
22 | 위 사진은 우리 회사 서비스의 웹 페이지를 Lighthouse 를 활용해 측정받은 결과이다.
23 | Lighthouse는 매번 성능을 측정받을 때마다 결과값이 다르게 나올수 있다고 한다. 왜냐하면
24 |
25 | - 게재되는 광고
26 | - 인터넷 트래픽 라우팅 변경
27 | - 고성능 데스크톱 및 저성능 노트북과 같은 다양한 장치에서 테스트
28 | - 바이러스 백신 소프트웨어
29 |
30 | 등 다양한 환경에 따라 영향을 받을 수 있기 때문이다.
31 |
32 | 위 사진에서 Performance 지표에는 27점이 나왔다.
33 | 각각의 지표들은 0-49, 50-89, 90-100 범위별로 나누어져 지표의 등급을 표시해주고 있다.
34 | 당연히 모든 지표가 90-100 범위에 들어 초록불이 나온다면 굉장히 좋을 것이다.
35 | 하지만 Lighthouse 가이드 문서에 따르면 그것은 굉장히 어려운 일이라고 한다. 99점에서 100점에 도달하는것은 90점에서 94점에 도달하는것과 비슷한 수준의 Metrics 개선이 필요하다고 설명해주고 있다.
36 |
37 | 지표 점수에 영향을 주는 것은 Metrics에 나와있는 목록들이다.
38 |
39 | - FCP(First Contentful Paint) - 브라우저에 첫번째 콘텐츠가 로딩되는 시간을 의미한다.
40 | - TTI(Time to Interactive) - 사용자가 웹에서 상호작용 할 수 있는데까지 걸리는 시점(클릭, 스크롤링 등) 을 의미한다.
41 | - SI(Speed Index) - 콘텐츠가 시각적으로 얼마나 빨리 표시되는지를 의미한다.
42 | - TBT(Total Blocking Time) - 웹을 로딩할 때 중간중간 Blocking 되는 시간의 총 합을 의미한다.
43 | - LCP(Largest Contentful Paint) - 가장 큰 콘텐츠가 렌더링 되는 시간을 의미한다.
44 | - CLS(Cumulative Layout Shift) - Visual stablity 즉, 시각적인 안정성을 측정한 점수를 의미한다.
45 |
46 | 
47 |
48 | 위 사진을 보면 각각의 지표들은 얼마의 가중치로 계산되어 점수가 측정되는지 알 수 있다.
49 | 각각의 Metrics 는 서로 연관되어 있는것 같다. 사용자가 웹에서 상호작용을 할 수 있는데 까지 걸리는 시간을 줄이려면(TTI) 웹을 로딩할 때 Blocking 되는 시간의 총 합을 줄여야 할 것으로 보인다.(TBT) 또한, TBT를 줄이면 FCP, LCP, SI 등에도 좋은 영향을 줄 수 있는것으로 보인다. CLS 는 가중치 비율이 5%인 것을 보면 유추할 수 있듯이 웹 렌더링 속도에 큰 영향은 주지 않는것 처럼 보인다.
50 |
51 | ## Opportunities
52 |
53 | 
54 |
55 | Performance 지표에서는 Opportunity 라는 항목으로 어떻게 하면 웹 페이지의 렌더링 속도를 개선시킬 수 있는지에 대한 설명도 함께 나와 있다. (하지만 성능 점수에는 직접적인 영향은 주지 않는다고 한다.)
56 |
57 | ### 1. Remove unused JavaScript
58 |
59 | 
60 | Lighthouse는 사용하지 않은 코드가 20KB 이상인 모든 JavaScript 파일을 표시한다.
61 | 사용하지 않는 Javascript 코드는 페이지 로드 속도를 느리게 할 수 있다. 왜냐하면 브라우저가 페이지를 로드하는 과정에서 Javascript 코드를 만나면 렌더링에 필요한 작업을 진행하기 전에 스크립트를 다운로드 하고 해석, 구문 분석, 컴파일 등 시간을 소요하기 때문이다. JavaScript가 비동기 코드인 경우에도 코드를 다운로드하는 동안 다른 리소스와 대역폭을 두고 경쟁하므로 성능에 상당한 영향을 미친다. 네트워크를 통해 사용하지 않는 코드를 보내는 것은 무제한 데이터 요금제가 없는 모바일 사용자에게도 낭비라고 한다.
62 | 개선 방법으로는 사용하지 않는 Javascript를 제거하기 위해 Chrome DevTools 의 Coverage 탭 에서는 사용하지 않는 코드를 한 줄씩 분석 할 수 있다.
63 | 한가지 의문인 점은 만약 유틸함수 같은 공톰 함수를 어떤 페이지에서는 사용하고, 어떤 페이지에서는 사용하지 않을 때, 사용하지 않는 페이지에서 coverage 분석을 돌려볼 경우 사용하지 않는 코드라고 나올까?
64 |
65 | ### 2. Preload key requests
66 |
67 | 
68 | Lighthouse는 나중에 요청되는 리소스를 `````` 를 사용해서 사전에 먼저 로드 되도록 지정해두라고 제안한다.
69 | index.html
70 | |--app.js
71 | |--styles.css
72 | |--ui.js
73 | 만약 파일구조가 위처럼 되어 있고 ```
114 |
115 | ··· 3
116 |
117 |
118 |
121 | ```
122 |
123 | 위 코드에서 log가 찍히는 결과는 ?
124 |
125 | 3. `null == undefined`의 결과와 이유는 ?
126 | 4. Array.prototype의 method중 concat()과 join()의 차이점은?
127 |
128 | # Reference
129 |
130 | - https://ko.javascript.info/onload-ondomcontentloaded
131 | - https://velog.io/@yejinh/CORS-4tk536f0db
132 | >>>>>>> 4da184a2980ba2b063f55a88b4e89e8b120ee436
133 |
--------------------------------------------------------------------------------
/interview/Samslow_Interview3.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: FE Interview 9
3 | date: 2020-08-12 00:00:00
4 | author: samslow
5 | category: Interview
6 | ---
7 |
8 | 최근 글을 팔로우 업 하기 위해 아래 주소로 글을 이동합니다.
9 |
10 | 아래 주소에서 게시글을 참고 해 주세요.
11 |
12 | [블로그 주소](https://samslow.github.io/development/2020/08/11/FE-interview-3/)
13 |
--------------------------------------------------------------------------------
/interview/Snowjang24_Interview1.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: FE Interview 4
3 | date: 2020-08-05 00:00:00
4 | author: snowjang24
5 | category: interview
6 | ---
7 |
8 | ## 오늘의 FE 질문
9 |
10 | 1. this는 JavaScript에서 어떻게 작동하는지 설명해주세요.
11 | 2. prototype 기반 상속은 어떻게 하는지 설명해주세요.
12 | 3. AMD와 CommonJS는 무엇이고, 이것들에 대해 어떻게 생각하시나요?
13 | 4. "호이스팅(Hoisting)"에 대해서 설명하세요.
14 |
15 | ## 1. this는 JavaScript에서 어떻게 작동하는지 설명해주세요.
16 |
17 | 자바스크립트에서 `this`는 함수 선언 위치가 아닌, 함수 호출을 기반으로 이뤄진다는 점이 가장 중요하다. 함수가 호출되는 실행 컨텍스트가 바로 `this`의 값이 된다. 이렇게 `this`의 값이 결정되는 것을 일컬어 **this binding** 이라고 한다.
18 |
19 | `this`의 값이 결정되는 this binding의 경우는 크게 5 가지로 나눌 수 있다.
20 |
21 | 1. Default Binding
22 | 2. Implicit Binding
23 | 3. Explicit Binding
24 | 4. Hard Binding
25 | 5. `new` Keyword
26 |
27 | ### a. Default Binding
28 |
29 | 가장 먼저 기본 바인딩이다. 보통, `strict mode` 가 아닌 경우(이 경우, `undefined`), `this`는 기본적으로 글로벌 객체를 참조한다(브라우저의 경우 `window`, Node의 경우 `global`).
30 |
31 | 아래의 예시를 실행해보면 과연 어떤 값이 나올까. 생각해보자.
32 |
33 | ```javascript
34 | function foo() {
35 | var a = 10;
36 | console.log(this.a);
37 | };
38 | var a = 5;
39 | foo();
40 | ```
41 |
42 | 결과는 `5`를 출력할 것이다. `foo()`가 호출되는 위치가 전역 객체의 컨텍스트에서 호출되기 때문에 `foo()` 내부의 `this`는 전역 객체를 참조하고 전역에 선언된 `a`를 출력한다.
43 |
44 | ### b. Implicit Binding
45 |
46 | 이번에는 아래와 같이 객체의 메서드를 호출해보자. 아래의 결과는 `10`일 것만 같다. 객체의 메서드기 때문에 `this` 는 객체 컨텍스트인, `obj` 객체가 될 것이라고 생각할 것이다.
47 |
48 | ```javascript
49 | function foo() {
50 | console.log(this.a);
51 | };
52 |
53 | var obj = {
54 | a: 10,
55 | foo: foo
56 | };
57 |
58 | var bar = obj.foo;
59 | var a = 5;
60 | bar();
61 | ```
62 |
63 | 예상과 달리 `5`가 출력된다. 맨 처음 말했듯, 함수가 선언되는 위치가 아닌 함수가 호출되는 위치가 중요하다. 이러한 결과가 나온 이유는, 메서드를 `bar`라는 변수에 할당하고 `foo` 함수에 대한 참조를 얻어 컨텍스트가 전역 객체로 변경되기 때문이다. 따라서, 아래와 같이 `obj`의 메서드를 바로 호출해야 우리가 예상했던 결과인 `10`을 얻을 수 있다.
64 |
65 | ```javascript
66 | function foo() {
67 | console.log(this.a);
68 | };
69 |
70 | var obj = {
71 | a: 10,
72 | foo: foo
73 | };
74 |
75 | var a = 5;
76 | obj.foo();
77 | ```
78 |
79 | 이처럼, 객체의 프로퍼티로 메서드를 가지고 있는 경우 메서드 내에서 `this`는 해당 객체에 대한 실행 컨텍스트를 가진다. 이를 **암시적 바인딩(Implicit Binding)** 이라고 부른다.
80 |
81 | ### c. Explicit Binding
82 |
83 | **명시적 바인딩(Explicit Binding)** 은 단어 뜻에서 볼 수 있듯 바인딩을 명시하여 `this`의 참조 값을 결정한다. `call`, `apply` 메서드를 통해 명시적 바인딩을 할 수 있다.
84 |
85 | 첫번째 파라미터로 넘겨준 객체에 `this`가 바인딩 된다.
86 |
87 | ```javascript
88 | function foo() {
89 | console.log(this.a);
90 | };
91 |
92 | var obj1 = {
93 | a: 10
94 | };
95 | var obj2 = {
96 | a: 20
97 | };
98 |
99 | var a = 5;
100 | foo.call(obj1);
101 | foo.call(obj2);
102 | ```
103 |
104 | ### d. Hard Binding
105 |
106 | Explicit Binding을 활용하여, 강제로 `this`가 참조하는 객체를 고정할 수 있다. 이를 **하드 바인딩(Hard Binding)** 이라고 한다. 아래의 예시를 먼저 살펴보자. 아래의 출력 결과를 예상해보자.
107 |
108 | ```javascript
109 | function foo() {
110 | console.log(this.a);
111 | };
112 |
113 | var obj1 = {
114 | a: 10
115 | };
116 | var obj2 = {
117 | a: 20
118 | };
119 |
120 | var bar = foo;
121 | foo = function() {
122 | bar.call(obj1);
123 | }
124 |
125 | foo();
126 | foo.call(obj2);
127 | ```
128 |
129 | 결과는 `foo()`와 `foo.call(obj2)`는 모두 `10`을 출력한다. 이러한 결과가 나온 이유는 아래의 코드에 있다. 내부적으로 명시적 바인딩을 하는 함수를 만들어, 함수 호출 위치와 상관 없이 `this`가 변하지 않고 동일한 결과를 얻을 수 있다.
130 |
131 | ```javascript
132 | var bar = foo;
133 | foo = function() {
134 | bar.call(obj1);
135 | }
136 | ```
137 |
138 | 이러한 하드 바인딩은 `.bind()` 가 나오기 이전에 사용하던 패턴으로 `.bind()`를 활용하여 위의 예시를 바꿔보면 아래와 같다. 이는 하드 바인딩과 똑같이 작동한다.
139 |
140 | ```javascript
141 | function foo() {
142 | console.log(this.a);
143 | };
144 |
145 | var obj1 = {
146 | a: 10
147 | };
148 | var obj2 = {
149 | a: 20
150 | };
151 |
152 | var bar = foo.bind(obj1);
153 |
154 | bar();
155 | bar.call(obj2);
156 | ```
157 |
158 |
159 | ### e. `new` Keyword
160 |
161 | 함수 앞에 `new` 키워드를 붙여 호출하면, 일반적인 함수 호출이 생성자 호출로 바뀐다. 이렇게 생성자 호출을 하게 되면 해당 함수는 새로운 빈 객체를 생성한다. 그리고 이 함수 내부에서 `this` 는 새로 생성된 빈 객체를 참조하게 된다.
162 |
163 | 아래의 예시에서 `foo()`와 `new foo()`결과를 한 번 예상해보자.
164 |
165 | ```javascript
166 | function foo() {
167 | var a = 10;
168 | this.b = 5;
169 | console.log(this.a, this.b);
170 | };
171 |
172 | var a = 20;
173 | var b = 15;
174 | foo();
175 | new foo();
176 | ```
177 |
178 | 일반 함수인 `foo()`의 경우 `this.a`가 `20`, `this.b`는 `5`가 출력된다. 함수 내부의 `this`는 전역 객체에 바인딩되었기 때문에 이러한 결과 값이 출력되고, `new foo()`의 경우, `this.a`는 `undefined` 그리고 `this.b`는 `5`가 출력된다.
179 |
180 | 새로운 객체가 생성 되면서 `this`가 새로운 객체에 바인딩 된다. 이 때 내부에 선언한 `a`의 경우 무시되기 때문에 `this.a`는 `undefined`의 값을 가지게 된다.
181 |
182 | ## 2. prototype 기반 상속은 어떻게 하는지 설명해주세요.
183 |
184 | 자바스크립트의 객체는 `[[Prototype]]` 이라는 숨김 프로퍼티를 갖는다. 이 프로퍼티는 `null` 혹은 참조하고 있는 객체를 가리키고 있다. 여기서 참조 대상을 프로토타입(prototype)이라 부른다.
185 |
186 | 또한, 자바스크립트에서는 객체애 찾고자하는 프로퍼티가 없을 경우 프로토타입 객체에서 해당 프로퍼티를 찾는데, 이러한 특징을 이용하여 prototype 기반 상속이 이루어지게 된다.
187 |
188 | `[[Prototype]]`은 `__proto__` 라는 예약어를 통해 값을 얻거나 설정할 수 있다. 이를 이용하여 아래와 같이 프로토 타입 객체를 설정하여 상속을 구현할 수 있다.
189 |
190 | ```jsx
191 | let animal = {
192 | eats: true,
193 | walk() {
194 | alert("동물이 걷습니다.");
195 | },
196 | };
197 |
198 | let rabbit = {
199 | jumps: true,
200 | __proto__: animal,
201 | };
202 |
203 | let longEar = {
204 | earLength: 10,
205 | __proto__: rabbit,
206 | };
207 |
208 | // 메서드 walk는 프로토타입 체인을 통해 상속받았습니다.
209 | longEar.walk(); // 동물이 걷습니다.
210 | alert(longEar.jumps); // true (rabbit에서 상속받음)
211 | ```
212 |
213 | ## 3. AMD와 CommonJS는 무엇이고, 이것들에 대해 어떻게 생각하시나요?
214 |
215 | CommonJS 와 AMD 모두 자바스크립트에서 모듈과 종속성을 선언하는 방법에 대한 명세다. 두 방식은 아래와 같은 차이가 있다.
216 |
217 | ### AMD
218 |
219 | * 브라우저 우선 접근 방식
220 | * 비동기 동작과 단순화된 이전 버전 호환성 선택
221 | * File I/O 개념이 없음
222 | * 객체, 함수, 생성자, 문자열, JSON 등 다양한 유형의 모듈을 지원
223 |
224 | ```javascript
225 | // package/lib is a dependency we require
226 | define(["package/lib"], function (lib) {
227 |
228 | // behavior for our module
229 | function foo() {
230 | lib.log( "hello world!" );
231 | }
232 |
233 | // export (expose) foo to other modules as foobar
234 | return {
235 | foobar: foo
236 | }
237 | });
238 | ```
239 |
240 | ### CommonJS
241 |
242 | * 서버 우선 접근 방식
243 | * 동기 동작이 기본
244 | * I/O, 파일 시스템, Promises 등과 같은 광범위하게 관심을 가짐
245 | * 객체만 모듈로 지원
246 |
247 | ```javascript
248 | // package/lib is a dependency we require
249 | var lib = require( "package/lib" );
250 |
251 | // behavior for our module
252 | function foo(){
253 | lib.log( "hello world!" );
254 | }
255 |
256 | // export (expose) foo to other modules as foobar
257 | ```
258 |
259 |
260 | ## 4. "호이스팅(Hoisting)"에 대해서 설명하세요.
261 |
262 | 호이스팅(Hoisting)은 코드에 선언된 변수 및 함수를 코드 상단으로 끌어올리는 것을 뜻한다. 여기서 함수 내에서 선언한 경우 해당 함수의 최상단으로, 전역인 경우에는 전역 범위의 최 상단으로 끌어 올려진다. 선언은 자바스크립트 엔진 구동시 가장 먼저 이뤄지고, 할당의 경우 런타임 과정에서 일어나기 때문에 선언만 호이스팅 된다.
263 |
264 | 아래와 같은 같은 코드가 에러를 발생시키지 않는 이유는 호이스팅 때문이다.
265 |
266 | ```jsx
267 | console.log(score); //undefined
268 | var score = 100;
269 | console.log(score); //100
270 | ```
271 |
272 | ```jsx
273 | var score;
274 | console.log(score); //undefined
275 | score = 100;
276 | console.log(score); //100
277 | ```
278 |
279 | 변수 호이스팅과 함수 호이스팅의 경우 전체적으로 동일하게 이뤄지지만, 함수 호이스팅에서 하나 주의해야할 점이 있다. 함수 호이스팅의 경우 함수 리터럴 방식으로 선언한 경우 호이스팅되지 않는다.
280 |
281 | ```jsx
282 | foo();
283 | var foo = function () {
284 | console.log("hello");
285 | };
286 | ```
287 |
288 | 또한, 호이스팅은 `var` 선언 뿐만 아니라 `const`와 `let`에서도 이뤄진다. 하지만 `var`과는 달리 `let`과 `const`는 TDZ(Temporal Dead Zone)에 의해 호이스팅이 이루어지지 않는 것처럼 보인다. `var`의 경우 선언과 동시에 초기화가 이루어지지만, `let`과 `const`의 경우 선언만 될 뿐 초기화가 이루어지지 않는다. 따라서, 메모리에 공간이 할당되어 있지 않게 되어 참조가 불가능하게 된다.
289 |
290 | ## Self Check
291 |
292 | - 자바스크립트의 실행 중인 모든 함수는 \_\_\_객체)에 대한 참조를 갖는다. `this`는 이러한 참조 값을 담고 있는 변수다.
293 | - 자바스크립트의 객체는 \_\_\_이라는 숨김 프로퍼티를 갖는다.
294 | - 자바스크립트에서 선언만 호이스팅 된다. (O, X)
295 |
296 | ## Reference
297 |
298 | - [JavaScript — all about “this” keyword](https://codeburst.io/all-about-this-and-new-keywords-in-javascript-38039f71780c)
299 | - [https://webclub.tistory.com/404](https://webclub.tistory.com/404)
300 | - [https://ko.javascript.info/prototype-inheritance](https://ko.javascript.info/prototype-inheritance)
301 | - [https://d2.naver.com/helloworld/12864](https://d2.naver.com/helloworld/12864)
302 | - [https://evan-moon.github.io/2019/06/18/javascript-let-const/](https://evan-moon.github.io/2019/06/18/javascript-let-const/)
303 | - [https://stackoverflow.com/questions/16521471/relation-between-commonjs-amd-and-requirejs](https://stackoverflow.com/questions/16521471/relation-between-commonjs-amd-and-requirejs)
304 |
305 |
--------------------------------------------------------------------------------
/interview/Snowjang24_interview3.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: FE Interview 10
3 | date: 2020-08-12 00:00:00
4 | author: snowjang24
5 | category: interview
6 | ---
7 |
8 | ## 오늘의 FE 질문
9 |
10 | 1. 전역 scope를 사용했을 때 장단점에 관해 설명해주세요.
11 | 2. 때때로 load event를 사용하는 이유에 관해 설명해주세요. 또 단점이 있다면 대안에 대해서도 설명해주세요.
12 |
13 | ## 전역 scope를 사용했을 때 장단점에 관해 설명해주세요.
14 |
15 | ### a. 장점
16 |
17 | - 제작한 어플리케이션의 모든 모듈과 함수에서 글로벌 변수에 접근할 수 있다.
18 | - 변수를 여러번 선언할 필요 없이, 모듈 밖에서 한 번만 선언해도 된다.
19 | - 일관성 유지에 유용하기 때문에, 상수에 해당하는 값을 저장할 때 사용할 수 있다.
20 | - 다양한 함수에서 공통으로 써야하는 변수가 있다면 유용하다.
21 |
22 | ### b. 단점
23 |
24 | - 글로벌로 여러 변수가 선언되면 프로그램 실행이 끝날때 까지 해당 변수의 메모리를 유지하기 때문에 메모리 문제를 유발한다.
25 | - 코드 리팩토링의 이유로 변수명을 변경해야할 때, 다른 모든 모듈 혹은 함수에서 해당 변수명을 직접 바꿔줘야하는 번거로움이 발생할 수 있다.
26 | - 모듈 단위로 코드를 작성 시, 변수명을 모두 기억하지 못하면, 모듈 혹은 함수 내에 선언된 지역 변수와 충돌할 수 있다.
27 | - 글로벌 변수는 모든 함수에서 수정이 가능하다. 따라서 다른 함수에서 수정이 이뤄지는 경우에 예상하지 못한 문제를 야기할 수 있다.
28 |
29 | 장점보다는 단점이 더 명확하기 때문에 상수 선언 이외에는 전역에 선언하는 것을 지양하는 것이 좋다.
30 |
31 | ## 때때로 load event를 사용하는 이유에 관해 설명해주세요. 또 단점이 있다면 대안에 대해서도 설명해주세요.
32 |
33 | ### `load` 이벤트를 사용하는 이유
34 |
35 | `load` 이벤트가 발생되는 시점은 객체가 모두 로드 되었을 때 발생한다. 보통 웹 페이지의 모든 콘텐츠(이미지, 스크립트 파일, CSS 파일 등)가 로드된 이후 스크립트를 실행하기 위해, `document` 혹은 ``에 Event Listener를 추가한다.
36 |
37 | ```javascript
38 | EventTarget.addEventListener("load", EventHandler);
39 | ```
40 |
41 | `document`, `` 외에도 `load` 이벤트는 아래의 태그들에서 사용이 가능하다.
42 |
43 | ```html
44 |