├── .gitignore ├── LICENSE ├── README.md ├── data-structure-and-algorithm └── README.md ├── database ├── Database 79d9527d1d534251afb6af40532b918b │ ├── 1-after.png │ ├── 1-before.png │ ├── 2-after.png │ ├── 2-before.png │ ├── 3-after.png │ ├── 3-before.png │ ├── Untitled 1.png │ ├── Untitled 2.png │ ├── Untitled 3.png │ ├── Untitled 4.png │ ├── Untitled 5.png │ ├── Untitled 6.png │ ├── Untitled 7.png │ ├── Untitled 8.png │ ├── Untitled.png │ ├── b+tree.png │ ├── b-tree.png │ ├── bcnf-after.png │ ├── bcnf-before.png │ └── index.png └── README.md ├── etc └── README.md ├── javascript ├── JavaScript f07b25d7438e4d0ca94bbc0c3231bc62 │ ├── Untitled 1.png │ └── Untitled.png └── README.md ├── network ├── Network 0208784d439545d2a6f93e6c5c4355bc │ ├── Untitled 1.png │ ├── Untitled 2.png │ ├── Untitled 3.png │ ├── Untitled.png │ ├── connection-termination.png │ └── osi-vs-tcp-ip.png └── README.md ├── os ├── OS e8aed882f45845d1a8fe27f71d71571b │ ├── Untitled 1.png │ ├── Untitled 2.png │ ├── Untitled 3.png │ ├── Untitled 4.png │ ├── Untitled.png │ ├── async.png │ ├── blocking&async.png │ ├── blocking&sync.png │ ├── blocking.png │ ├── non-blocking&async.png │ ├── non-blocking&sync.png │ ├── non-blocking.png │ ├── sync.png │ └── thread-by-level.png └── README.md ├── self-taught.jpg └── web ├── README.md └── Web a8bd6cb86f15403fa6e62833f6c3d9f2 ├── Untitled 1.png ├── Untitled 2.png ├── Untitled 3.png └── Untitled.png /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Heechang Shin 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

Study Note

2 | 3 |
4 | self-taught 5 | 6 |
7 |
8 | 9 | CS / Front-End를 공부하고 기록합니다. 10 | ( 2021.01 ~ 2021.11 ) 11 | 12 | > · 꼬리에 꼬리를 물고 `왜?`에 대해 탐구한다. 13 | > · 내용에 `핵심`만 담는다. 14 | > · 답안을 `병렬적`으로 작성한다. 15 | 16 |
17 | 18 |
19 | 20 |
21 | 22 | ## Table of Contents 23 | 24 | - [CS](#cs) 25 | - [Network](#network) 26 | - [OS](#os) 27 | - [Database](#database) 28 | - [Data Structure & Algorithm](#data-structure--algorithm) 29 | - [Etc](#etc) 30 | 31 | - [Front-End](#front-end) 32 | - [Web](#web) 33 | - [JavaScript](#javascript) 34 | 35 | - [Reference](#reference) 36 | 37 |
38 | 39 | ## CS 40 | 41 | ### Network 42 | 43 | ### [(답변 보러가기 →)](https://github.com/heech1013/tech-interview-handbook/blob/main/network/README.md) 44 | 45 | 일반 46 | 47 | - 주소창에 www.naver.com을 입력 후 접속했을 때의 무슨 일이 일어날까? 48 | 49 | OSI 7계층 50 | 51 | - OSI 7계층이란? 52 | - OSI 7계층이 필요한 이유는? 53 | - OSI 7계층과 TCP/IP 4계층을 비교해본다면? 54 | 55 | OSI Physical Layer(물리 계층, 1계층) 56 | 57 | - OSI Physical Layer란? 58 | 59 | OSI Data-link Layer(2계층) 60 | 61 | - OSI Data-link Layer란? 62 | - TCP/IP Network (Interface) layer(1계층)란? 63 | - 데이터 링크 계층의 주요 역할은? 64 | - 2계층에서 데이터가 hop-by-hop으로 전달된다는 것의 의미는 무엇일까? 65 | - 프레이밍이란? 66 | - 프레임의 구조(필드)는? 67 | - MAC 주소란? 68 | - MAC 주소와 IP 주소의 차이점은? 69 | - MAC 주소의 종류에는 어떤 것들이 있을까? 70 | - 스위치란? 71 | - 스위치의 포워딩 방식에 대해 설명해본다면? 72 | - MAC 주소 테이블이란? 73 | - MAC 주소 테이블이 동작하는 과정은? 74 | - LAN과 WAN의 차이점? 75 | - 접근 제어란? 76 | - 흐름 제어(Flow control)란? 77 | - 오류 제어란? 78 | - 이더넷이란? 79 | - 이더넷의 특징? 80 | - 이더넷의 장단점? 81 | 82 | OSI Network Layer(3계층) & TCP/IP Internet Layer(2계층) 83 | 84 | - OSI Network layer(TCP/IP Internet layer)란? 85 | - 라우터란? 86 | - 라우팅이란? 87 | - 정적 라우팅과 동적 라우팅이란? 88 | - 포워딩이란? 89 | - 포워딩 테이블이란? 90 | - 스위치와 라우터의 차이점은? 91 | - 스위치와 라우터의 공통점은? 92 | - AS(Autonomous System, 자치 시스템)란? 93 | - IP(Internet Protocol)란? 94 | - 네트워크에서 '신뢰성'이 의미하는 것은? 95 | - ICMP(Internet Control Message Protocol)란? 96 | - IP의 데이터그램 단편화(fragmentation)란? 97 | - IP 데이터그램 단편화/재조립에 사용되는 IP 헤더의 종류에는 어떤 것들이 있을까? 98 | - IPv6란? 99 | - ARP(Address Resolution Protocol)란? 100 | - ARP 테이블이란? 101 | - 같은 LAN 상에서의 전송에서 ARP가 진행되는 과정은? 102 | - DHCP(Dynamic Host Configuration Protocol, 동적 호스트 구성 프로토콜)란? 103 | - DHCP의 장단점? 104 | - DHCP에서 IP 주소를 할당 받으면 영원히 사용할 수 있을까? 105 | - DHCP가 ip주소를 임대해주는 절차? `보충` 106 | 107 | OSI Transport Layer(4계층) & TCP/IP Transport Layer(3계층) 108 | 109 | - Transport Layer란? 110 | - network layer(3계층)와 Transport Layer(4계층)와의 차이점은? 111 | - Transport Layer가 흐름 제어를 제공하는 방법? 112 | - 혼잡 제어(Congestion control란? 113 | - Transport Layer가 혼잡 제어를 제공하는 방법? 114 | - AIMD(합 증가/곱 감소)란? 115 | - Slow start(느린 시작)란? 116 | - Fast retransmit(빠른 재전송)이란? 117 | - Transport Layer가 오류 제어를 제공하는 방법은? 118 | 119 | TCP & UDP 120 | 121 | - TCP(Transmission Control Protocol)란? 122 | - UDP(User Datagram Protocol)란? 123 | - 연결형 서비스와 비연결형 서비스의 차이점은? 124 | - 데이터그램 방식과 가상 회선 방식이란? 125 | - 가상 회선 방식에서 논리적 연결이 설정되는 과정은? 126 | - 회선 구성 방식에는 어떤 것들이 있을까? 127 | - 전이중, 반이중, 단방향 방식에 대해 설명해본다면? 128 | - TCP와 UDP는 각각 어떤 특성의 서비스에 적합할까? 129 | - 3-way handshake의 과정에 대해 설명해본다면? 130 | - 4-way handshake의 과정에 대해 설명해본다면? 131 | - 왜 2-way handshake는 성립될 수 없을까? 132 | 133 | OSI Application Layer(응용 계층, 7계층) & TCP/IP Application Layer(4계층) 134 | 135 | - Application Layer란? 136 | 137 | DNS 138 | 139 | - DNS(Domain Name Server)란? 140 | - 도메인 네임(domain name)이란? 141 | - 도메인 네임의 구조? 142 | - DNS에서 도메인을 얻어오는 과정은? 143 | - PC는 local DNS의 ip 주소를 어떻게 알고 있을까? 144 | - DNS의 구성 요소는? 145 | - 도메인 네임 스페이스란? 146 | - 네임 서버란? 147 | - 네임 서버의 종류는? 148 | - resolver란? 149 | - DNS가 사용하는 전송 계층(Transport Layer)의 프로토콜은? 150 | - DNS에 UDP를 사용하는 이유? 151 | 152 | 로드 밸런싱(Load Balancing) 153 | 154 | - 트래픽이 증가해 기존의 컴퓨팅 자원으로 서비스할 수 없을 때, 대처할 수 있는 2가지 방법은? 155 | - 로드 밸런싱이란? 156 | - 로드 밸런싱 알고리즘에 대해 설명해본다면? 157 | - 각 계층의 로드 밸런서에 대해 설명해본다면? 158 | 159 | [(목차로 돌아가기)](#table-of-contents) 160 | 161 |
162 | 163 | --- 164 | 165 | ### OS 166 | 167 | ### [(답변 보러가기 →)](https://github.com/heech1013/tech-interview-handbook/blob/main/os/README.md) 168 | 169 | 운영체제 170 | 171 | - 운영체제란? 172 | - 운영체제의 역할은? 173 | 174 | 프로세스와 스레드 175 | 176 | - 프로세스란? 177 | - 메모리는 어떻게 구성되어 있을까? 178 | - 스레드란? 179 | - 스레드가 필요한 이유는? (스레드의 장점은?) 180 | - 프로세스와 스레드의 차이점은? 181 | - 스레드를 지원하는 주체에 따라 나눈다면 어떻게 나뉠까? 182 | - 사용자 레벨 스레드의 장단점? 183 | - 커널 레벨 스레드의 장단점? 184 | - 멀티 프로세스와 멀티 스레드의 차이점은? 185 | 186 | 스케줄링 187 | 188 | - Context Switching(문맥 교환)이란? 189 | - Context Switching이 필요한 이유는? 190 | - Context Switching이 진행되는 과정은? 191 | - Context에는 어떤 정보들이 있을까? 192 | - Context Switching는 어떤 상황에서 진행될까? 193 | - PCB(Process Control Block)란? 194 | - PCB가 가지고 있는 정보에는 어떤 것들이 있을까? 195 | - 프로세스의 상태가 전이되는 과정은? (프로세스 상태 전이도의 흐름은?) 196 | - 인터럽트(Interrupt)란? 197 | - 인터럽트의 종류에는 어떤 것들이 있을까? 198 | - 인터럽트가 동작하는 순서는 어떻게 될까? 199 | - 시스템 콜(System Call)이란? 200 | - 시스템 콜이 필요한 이유는? 201 | - 커널 모드(Kernel mode)와 사용자 모드(User mode)란? 202 | - 시스템의 성능을 어떤 기준으로 측정할까? 203 | - (참고) 용어 204 | - 스케줄링의 주기에 따라 3가지로 나눈다면 어떻게 나뉠까? 205 | - 선점형 스케줄링과 비선점형 스케줄링의 차이? 206 | - 자원 관리에 있어서 time sharing과 space sharing의 차이는? 207 | - FCFS(First Come First Service)란? 208 | - Round Robin이란? 209 | - SPN(Shortest Process Next)이란? 210 | - SRTN(Shortest Remaining Time Next)란? 211 | - HRRN(High Response Ratio Next)이란? 212 | - MLQ(Multi Level Queue)란? 213 | - MFQ(Multi level Feedback Queue)란? 214 | 215 | 동기화 216 | 217 | - 동기화란? 218 | - 동기화가 필요한 이유는? 219 | - Critical section(임계 구역)이란? 220 | - Race condition(경쟁 상태)이란? 221 | - Mutual exclusion(상호 배제)이란? 222 | - Mutual exclusion에 사용되는 기본 연산(primitive)의 조건은? 223 | - Mutual exclusion을 SW로 구현한 알고리즘에는 어떤 것들이 있나? 224 | - Dekker's algorithm을 설명해본다면? 225 | - Dekker's algorithm을 더 자세히 설명해본다면? (간단하게 코드로 표현해본다면?) 226 | - SW로 구현한 상호 배제 알고리즘의 단점은? 227 | - HW로 구현한 상호 배제 알고리즘에는 어떤 것들이 있나? 228 | - TAS(TestAndSet)란? 229 | - TAS를 이용해 ME가 보장되는 과정을 조금 더 자세히 설명? (코드로 설명?) 230 | - OS로 구현한 상호 배제 알고리즘에는 어떤 것들이 있나? 231 | - 스핀락이란? 232 | - 스핀락은 어떤 특성의 프로세스에서 사용하기 적절할까? 233 | - 뮤텍스란? 234 | - 뮤텍스는 어떤 상황에서 사용하기 적절할까? 235 | - 스핀락과 뮤텍스의 차이점은? 236 | - 세마포어란? 237 | - 세마포어에 사용되는 연산의 종류와 그 로직은? 238 | - 스핀락/뮤텍스와 세마포어의 차이는? 239 | 240 | 데드락 241 | 242 | - 데드락(dead lock, 교착 상태)이란? 243 | - 데드락이 발생하기 위한 조건은? 244 | - 데드락을 처리하는 방법은? 245 | - 데드락 회피 알고리즘 중 하나를 설명해본다면? 246 | - 데드락 탐지 알고리즘 중 하나에 대해 설명해본다면? 247 | 248 | 가상 메모리 249 | 250 | - 가상 메모리란? (메모리 가상화란?) 251 | - 메모리의 가상화가 필요한 이유는? 252 | 253 | 주소 변환(address translation) 254 | 255 | - 주소 변환이란? 256 | - 주소 변환이 필요한 이유는? 257 | - 주소 변환을 구현한 기술에는 어떤 것이 있는지? 258 | - base and bound란? 259 | - 베이스 레지스터란? 260 | - 바운드 레지스터(bound register)란? 261 | - 바운드 레지스터가 타 프로세스 메모리 침범을 막는 방법은? 262 | - base and bound에서 운영체제의 역할은? 263 | - base and bound에서 프로세스의 주소 공간을 옮기려면 어떻게 해야 하나? 264 | - base and bound의 장단점은? 265 | - base and bound의 내부 단편화 문제란? 266 | 267 | 세그멘테이션(segmentation) 268 | 269 | - 세그멘테이션이란? 270 | - 세그먼트란? 271 | - 세그멘테이션에서 가상 주소로부터 물리 주소를 얻는 과정은? 272 | - 세그먼트의 바운드 레지스터의 역할은? 273 | - 하드웨어가 가상 주소에서 세그먼트의 종류와 오프셋을 파악하는 방법은? 274 | - 가상 주소 변환에 있어서 스택과 나머지 종류의 세그먼트 간 차이는? 275 | - 하드웨어는 세그먼트가 어느 방향으로 확장해야 하는지 어떻게 알 수 있을까? 276 | - 세그멘테이션이 메모리 공유를 지원하는 방법은? 277 | - 세그멘테이션을 위한 운영체제의 역할은? 278 | - 세그먼트 테이블이란? `보충` 279 | - 세그멘테이션의 장단점은? 280 | - 외부 단편화란? 281 | - 외부 단편화에 대한 대응 방안은? 282 | - 압축이란? 진행되는 과정은? 283 | - 압축의 단점은? 284 | - 빈 공간 리스트를 관리하는 알고리즘에는 어떤 것들이 있으며, 각각의 장단점은? 285 | 286 | 페이징(Paging) 287 | 288 | - 페이징이란? 289 | - 페이징이 등장하게 된 배경은? 290 | - 페이징의 장단점은? 291 | - 페이징에서 물리 메모리의 구성은 어떻게 다른가? 292 | - 페이지 테이블(page table)이란? 293 | - 페이지 테이블 엔트리(PTE, Page Table Entry)란? 294 | - PTE의 구성 요소에는 어떤 것들이 있는지? 295 | - 페이징의 가상 주소에서 물리 주소를 얻어내는 과정은? 296 | - 현재 실행 중인 프로세스의 페이지 테이블 위치를 어떻게 알 수 있을까? 297 | 298 | TLB 299 | 300 | - TLB(Translation-Lookaside Buffer, 변환-색인 버퍼)란? 301 | - TLB가 필요한 이유는? 302 | - TLB가 도입된 상태에서 가상 메모리 참조 시 일어나는 과정은? 303 | - (TLB의) 지역성 2종류와 적용된 예시에 대해 설명? 304 | - TLB 미스를 처리하는 방법에는 어떤 것들이 있을까? 305 | - TLB 미스 트랩 핸들러가 실행될 때 TLB 미스가 나지 않도록 대응 방안? 306 | - TLB Cache가 설계된 방식은? (cache의 associativity와 관련하여) 307 | - TLB 각 항목의 구성은? 308 | - 페이지 테이블의 valid bit와 TLB의 valid bit 간 차이점은? 309 | - TLB에는 여러 VPN이 공존할 수 있다. 하지만 그럴 경우 여러 프로세스 간 VPN을 구분할 수 없다. 이에 대한 방안은? 310 | - 캐시 교체 정책에는 어떤 것들이 있나? 311 | - LRU란? 312 | - Random 정책이란? 장단점은? 313 | - TLB coverage를 벗어난다는 것의 의미는? 314 | 315 | 스와핑(Swapping) 316 | 317 | - 스와핑이란? 318 | - swap in과 swap out에 대해 설명? 319 | - page fault란? 320 | - 스와핑이 지원되는 상황에서 메모리가 참조되는 과정을 설명? 321 | - 운영체제가 Page fault를 처리하는 과정은? 322 | - 운영체제가 페이지 교체(스왑) 알고리즘을 작동시키는 시기는? 323 | - 페이지 교체(스왑) 알고리즘이 작동될 때(즉, 여유 공간이 최솟값보다 적어질 때) 일어나는 일은? 324 | 325 | Blocking/Non-Blocking & Synchronous/Asynchronous 326 | 327 | - Blocking과 Non-Blocking의 차이점? 328 | - Synchronous와 Asynchronous의 차이점? 329 | - Blocking + Sync 조합에 대해 설명해본다면? 330 | - Non-Blocking + Sync 조합에 대해 설명해본다면? 331 | - Blocking + Async 조합에 대해 설명해본다면? 332 | - Non-Blocking + Async 조합에 대해 설명해본다면? 333 | 334 | [(목차로 돌아가기)](#table-of-contents) 335 | 336 |
337 | 338 | --- 339 | 340 | ### Database 341 | 342 | ### [(답변 보러가기 →)](https://github.com/heech1013/tech-interview-handbook/blob/main/database/README.md) 343 | 344 | 인덱스 345 | 346 | - 인덱스(index)란? 347 | - 인덱스를 사용하면 검색 속도가 빨라지는 이유는? 348 | - 인덱스가 작동하는 과정(순서)은? 349 | - 인덱스를 Hash Table로 구현하지 않는 이유는? 350 | - B-Tree란? 351 | - B+Tree란? 352 | - B-Tree보다 B+ Tree가 갖는 이점은? 353 | - 범위 검색이 Hash table보다 B+ Tree에서 이점을 갖는 이유는? 354 | - 인덱스의 장단점은? 355 | - 인덱스를 생성하기에 적절한 컬럼의 특성은? 356 | - 인덱스를 생성하기에 적절하지 않은 컬럼의 특성은? 357 | - DML(INSERT, DELETE, UPDATE)을 수행할 때 인덱스를 사용하는 컬럼에 대해 추가로 해줘야 하는 작업은? 358 | - 인덱스를 생성/조회하기 위한 SQL문 작성 방법은? 359 | 360 | 트랜잭션 361 | 362 | - 트랜잭션이란? 363 | - 트랜잭션의 성질에는 어떤 것들이 있을까? 364 | - 트랜잭션의 연산에는 어떤 것들이 있을까? 365 | - 트랜잭션의 상태를 설명해본다면? 366 | - 트랜잭션의 고립 수준에 따라 발생 가능한 읽기 이상 현상(Read Phenomena)에 대해 설명해본다면? 367 | - 트랜잭션의 고립 수준 유형에 대해 설명해본다면? 368 | - 트랜잭션의 고립 수준과 동시성과의 상관 관계는? 369 | 370 | 정규화 371 | 372 | - 정규화란? 373 | - 제1 정규화에 대해 설명? 374 | - 제2 정규화에 대해 설명? 375 | - 제3 정규화에 대해 설명? 376 | - BCNF에 대해 설명? 377 | - 데이터베이스의 이상 현상(Anomaly)에는 어떤 것들이 있을까? 378 | - 정규화의 단점은? 379 | - 반정규화(De-normalization)란? 380 | 381 | 키 382 | 383 | - 키란? 384 | - 슈퍼키란? 385 | - 후보키란? 386 | - 기본키란? 387 | - 대체키란? 388 | - 외래키란? 389 | 390 | SQL Query 391 | 392 | - SQL이란? 393 | - JOIN이란? 394 | - INNER JOIN이란? 395 | - OUTER JOIN이란? 396 | - LEFT (OUTER) JOIN / RIGHT (OUTER) JOIN이란? 397 | - CROSS JOIN(카티전 조인)이란? 398 | - JOIN에서 ON과 WHERE의 차이점은? 399 | - (OUTER) JOIN에서 (ON과 WHERE를 이용해서) 차집합을 구하는 방법은? 400 | 401 | DBMS 402 | 403 | - DBMS란? 404 | - DBMS를 사용했을 때의 장점은? 405 | - RDBMS란? 406 | 407 | [(목차로 돌아가기)](#table-of-contents) 408 | 409 |
410 | 411 | --- 412 | 413 | ### Data Structure & Algorithm 414 | 415 | ### [(답변 보러가기 →)](https://github.com/heech1013/tech-interview-handbook/blob/main/data-structure-and-algorithm/README.md) 416 | 417 | Data Structure 418 | 419 | - 스택과 큐에 대해 설명해본다면? 420 | - 연결 리스트(Linked List)란? 421 | - 그래프와 트리란? 422 | - 이진 탐색 트리(Binary Search Tree, BST)란? 423 | - 이진 탐색 트리의 연산에 대해 설명해본다면? 424 | - 불균형한 이진 탐색 트리의 검색 연산을 보완하기 위한 방법은? 425 | - 힙이란? 426 | - 힙의 삽입과 삭제 연산에 대해 설명해본다면? 427 | - 우선순위큐를 구현하는 방법에는 어떤 것들이 있을까? 428 | - 해시 테이블(Hash Table)이란? 429 | - 해시 값의 충돌을 해결하는 방법에는 어떤 것들이 있을까? 430 | 431 | Algorithm 432 | 433 | - 코딩 인터뷰 팁 434 | - 정렬의 종류에는 어떤 것들이 있을까? 435 | - 퀵 소트의 피벗 지정 방식을 어떻게 개선할 수 있을까? 436 | - n번째 피보나치 수를 구하는 방법은? 437 | - DFS와 BFS의 시간 복잡도는? 438 | 439 | [(목차로 돌아가기)](#table-of-contents) 440 | 441 |
442 | 443 | --- 444 | 445 | ### Etc 446 | 447 | ### [(답변 보러가기 →)](https://github.com/heech1013/tech-interview-handbook/blob/main/etc/README.md) 448 | 449 | 객체 지향 프로그래밍(OOP) 450 | 451 | - 객체 지향 프로그래밍이란? 452 | - 객체 지향 프로그래밍의 장단점은? 453 | - 절차 지향 프로그래밍이란? 454 | - 클래스와 인스턴스(객체)란? 455 | - 오버로딩(Overloading)과 오버라이딩(Overriding)의 차이점은? 456 | - 객체 지향 5대 원칙에 대해 설명해본다면? 457 | 458 | [(목차로 돌아가기)](#table-of-contents) 459 | 460 |
461 | 462 | --- 463 | 464 | ## Front-end 465 | 466 | ### Web 467 | 468 | ### [(답변 보러가기 →)](https://github.com/heech1013/tech-interview-handbook/blob/main/web/README.md) 469 | 470 | 브라우저 471 | 472 | - 브라우저의 렌더링 과정에 대해 설명? 473 | - 레이아웃과 리페인트의 차이점은? 474 | - 레이아웃과 리페인트의 성능상 차이점은? 475 | - DOM이란? 476 | - DOM의 개체 구조에 대해 설명? 477 | - DOM은 HTML과 1:1로 매핑되는가? 478 | - HTML 문서에서 script 파일을 어디에 위치시키는 것이 좋을까? 479 | - 스크립트 로딩이 HTML 파싱을 방해하는 이유는? 480 | - script를 body 태그 최하위에 놓는 것의 한계는? 그 대안은? 481 | - script 태그의 defer 속성에 대해 설명? 482 | - 여러 defer script 간 script가 실행되는 순서는? 483 | - defer script를 사용할 때 주의해야 할 점은? 484 | - script 태그의 async 속성에 대해 설명? 485 | - 여러 async script 간 script가 실행되는 순서는? 486 | - defer script와 async script가 각각 어느 경우에 유용한가? 487 | 488 | 성능 489 | 490 | - 웹에서 서비스의 성능을 측정하는 방법은? 491 | - 브라우저에서 DOMContentLoaded와 load 이벤트가 발생하는 시점은? 492 | - 브라우저에서 이벤트가 발생하는 시점을 측정하는 방법은? 493 | - 브라우저 기준으로 성능을 측정하는 것의 한계(단점)은? 494 | - 사용자 기준에서 성능을 측정할 수 있는 지표들에 대해 아는 것이 있는지? 495 | - 사용자 기준에서 성능을 측정하는 방법은? 496 | - 웹 페이지 로딩을 최적화할 수 있는 방법에는 어떤 것들이 있을까? 497 | - 블록 리소스 최적화에 대해 설명? 498 | - 리소스 요청 수 줄이기에 대해 설명? 499 | - 리소스 용량 줄이기에 대해 설명? 500 | - 웹 페이지 렌더링을 최적화할 수 있는 방법에는 어떤 것들이 있을까? 501 | - 레이아웃 최적화에 대해 설명? 502 | - 애니메이션 최적화에 대해 설명? 503 | 504 | HTTP 505 | 506 | - HTTP란? 507 | - HTTP의 특징? 508 | - HTTP가 비연결성으로 설계된 이유가 뭘까? 509 | - HTTP의 비연결성으로 인한 단점이 뭐가 있을까? 510 | - HTTP의 비연결성을 해결하기 위한 방법? 511 | - Keep-Alive를 사용하는 방법? 512 | - Keep-Alive의 장점? 513 | - Keep-Alive의 단점? 514 | - 무상태성을 해결하기 위한 방법? 515 | - HTTP 요청/응답 메시지의 구성(형식)은? 516 | - HTTP Method에는 어떤 것들이 있나? 517 | - GET과 POST의 차이? 518 | - 멱등성이란? 519 | - GET과 HEAD의 차이? 520 | - POST와 PUT의 차이? 521 | - PUT와 PATCH의 차이? 522 | - OPTIONS 란? 523 | - OPTIONS가 언제 사용될까? 524 | - CORS의 preflight request의 목적은? 525 | - (참고) 주요 HTTP 응답 코드 526 | - 인증과 인가의 차이점은? 527 | - HTTP 헤더에는 어떤 것들이 있을까? `보충` 528 | - HTTP의 보안 취약점은? 529 | 530 | HTTPS 531 | 532 | - HTTPS란? 533 | - HTTPS를 통해 얻을 수 있는 이점은? 534 | - HTTPS가 암호화 채널을 수립할 때 사용하는 암호화 프로토콜은? 535 | - SSL 인증서란? 536 | - SSL 인증서의 역할은? 537 | - SSL 인증서에 포함된 정보는? 538 | - SSL 인증서가 서비스를 보증하는 과정은? 539 | - SSL 통신 과정을 설명해본다면? 540 | 541 | HTTP/2 542 | 543 | - HTTP/2 이전 버전들의 성능 제한 이슈는? (HTTP/2가 등장한 이유는?) 544 | - HTTP/2의 목적은? 545 | - HTTP/2가 제공하는 주요 기능에는 어떤 것들이 있나? 546 | - HTTP/2는 HTTP의 의미 체계를 대체(변경)하는지? 547 | - HTTP/2의 바이너리 프레이밍 계층이란? 548 | - HTTP/2의 스트림, 메시지, 프레임에 대해 설명? 549 | - HTTP/2가 요청, 응답 다중화를 지원하는 원리는? 550 | - HTTP/2의 요청, 응답 다중화를 통해 얻을 수 있는 이점은? 551 | - HTTP/2의 (출처당) 단일 연결을 통해 얻을 수 있는 이점은? 552 | - HTTP/2에서 스트림 우선순위를 지정하는 과정은? 553 | - HTTP/2의 서버 푸시에 대해 설명? 554 | - HTTP/2의 헤더 압축에 대해 설명? 555 | 556 | 쿠키 & 세션 557 | 558 | - 쿠키란? 559 | - 쿠키는 어떻게 구성되어 있나? 560 | - 쿠키를 생성하는 방법은? 561 | - 쿠키를 요청 메시지에 어떻게 설정하나? 562 | - 요청 메시지에 쿠키가 어디에 들어가있나? 563 | - 쿠키의 단점은? 564 | - 쿠키의 성능 상 단점을 보완하기 위한 대안은? 565 | - 쿠키의 보안적 취약점? 566 | - 쿠키의 보안적 취약점에 대한 대안은? 567 | - 쿠키가 만료되는 시점은? 568 | - 세션이란? 569 | - 세션을 생성하는 절차는? 570 | - 세션의 데이터가 유지되는 기간은? (만료되는 시점은?) 571 | - 쿠키와 세션의 차이점? 572 | - 세션의 장점에도 불구하고 쿠키를 사용하는 이유? 573 | 574 | localStorage & sessionStorage 575 | 576 | - localStorage(또는 sessionStorage)란? 577 | - 쿠키 대신 사용하는 이유는? 578 | - localStorage과 sessionStorage의 차이점은? 579 | 580 | CORS 581 | 582 | - CORS란? 583 | - origin(출처)이란? 584 | - 같은 출처, 다른 출처를 판단하는 기준은? 585 | - SOP(동일 출처 정책)란? 586 | - SOP가 존재하는 이유는? 587 | - SOP가 교차 출처로 삽입하는 리소스를 허용하는 경우는? 588 | - 브라우저와 서버 중 CORS를 판단하는 주체는? 589 | - CORS가 동작하는 방식은? (브라우저가 CORS를 판단하는 방법은?) 590 | - CORS가 동작하는 세 가지 시나리오에 대해 알고 있는지? 591 | - Simple Request란? (+ 과정을 설명해본다면?) 592 | - Simple Request를 사용할 수 있는 조건은? 593 | - Preflight Request란? (+ 과정을 설명해본다면?) 594 | - Credentialed Request란? 595 | - Credentialed Request를 사용하는 방법은? 596 | - credentials에 옵션이 same-origin(그리고 같은 출처 간 통신일 때)이거나 include일 때 브라우저가 추가로 확인하는 조건은? 597 | - CORS를 해결할 수 있는 방법은? 598 | - 프록시 서버를 활용해 CORS 에러를 해결하는 과정은? 599 | - CORS(혹은 Access-Control-Allow-Origin)의 단점? 600 | - JSONP란? 601 | - JSONP를 활용하는(동작하는) 과정에 대해 설명? 602 | - JSONP가 더 이상 사용되지 않는 이유는? 603 | 604 | REST 605 | 606 | - REST란? 607 | - REST의 특징은? 608 | - Uniform Interface란? (더 자세히 설명?) 609 | - Uniform Interface가 필요한 이유는 뭘까? 610 | - REST의 구성은? 611 | - REST에서 정의하는 CRUD Operation과 그에 해당하는 HTTP Method는? 612 | - REST의 장단점? 613 | - REST API란? 614 | - REST API의 규칙은? 615 | 616 | 보안 공격(XSS/CSRF/SQL Injection) 617 | 618 | - XSS란? 619 | - XSS를 방지하기 위한 방법은? 620 | - CSRF란? 621 | - CSRF를 방지하기 위한 방법은? 622 | - SQL Injection이란? 623 | - SQL Injection 중 아는 종류가 있는지? 624 | - SQL injection의 대응 방안은? 625 | 626 | Web Server & WAS 627 | 628 | - Static Page와 Dynamic Page의 차이점은? 629 | - 웹 서버란? 630 | - 웹 서버의 기능은? 631 | - WAS(Web Application Server)란? 632 | - WAS의 기능은? 633 | - 웹 서버가 필요한 이유는? 634 | - WAS가 필요한 이유는? 635 | - WAS로 웹 서버와 애플리케이션 서버 기능을 모두 수행하지 않는 이유는? 636 | 637 | CSR / SSR / SPA 638 | 639 | - CSR이란? 640 | - SSR이란? 641 | - SSR의 장점? 642 | - SSR의 단점? `보충` 643 | - SPA란? 644 | - 전통적인 웹 방식은 어땠나? 645 | - SPA의 장점? 646 | - SPA의 단점? 647 | - SPA를 하면 SEO에 문제가 생기는 이유? `보충` 648 | - SPA의 단점 - 초기 구동 속도를 극복하기 위한 방법? 649 | - SPA의 단점 - SEO 최적화 문제를 극복하기 위한 방법? `보충` 650 | - Routing이란? 651 | - SPA에서 routing이 어려울 수 있는 이유? 652 | 653 | 프론트엔드 개발의 흐름과 철학 654 | 655 | - 단방향 바인딩과 양방향 바인딩의 차이는? 656 | - 양방향 데이터 바인딩의 장단점은? 657 | - 단방향 데이터 바인딩의 장단점은? 658 | - (참고) 데이터 상태 관리의 흐름에 대하여 659 | 660 | 이벤트 버블링 & 캡처 & 위임 661 | 662 | - 이벤트 버블링이란? 663 | - 이벤트 캡쳐란? 664 | - 이벤트 캡쳐를 구현하는 방법은? 665 | - 이벤트 전파를 막는 방법은? 666 | - 이벤트 위임이란? 667 | - 이벤트 위임을 사용함으로써 얻을 수 있는 이점은? 668 | 669 | Ajax 670 | 671 | - Ajax란? 672 | - Ajax의 이점? 사용 이유? 673 | - Ajax를 사용하는 방법은? Ajax가 동작하는 원리는? 674 | 675 | JSON 676 | 677 | - JSON이란? 678 | - 다른 데이터 포맷과 비교하여 JSON의 이점? 679 | - JavaScript 객체를 JSON으로 변환하는 방법은? 그 반대는? 680 | 681 | 웹팩 & 바벨 682 | 683 | - 웹팩이란? 684 | - 모듈 번들러란? 685 | - 모듈이란? 686 | - 모듈 번들러(혹은 웹팩)이 필요한 이유는? 687 | - 파일 단위로 모듈을 관리하지 않을 때의 문제점? 688 | - 웹팩이 파일 단위로 모듈을 관리하기 위해 사용하는 방법은? 689 | - 웹을 개발할 때 반복되는 작업에는 어떤 것들이 있을까? 690 | - 모듈 번들러(혹은 웹팩)이 웹 로딩 속도를 어떻게 개선할 수 있을까? 691 | - 엔트리(entry)란? 692 | - 아웃풋(output)이란? 693 | - 로더란? 694 | - 로더의 예시에는 어떤 것들이 있을까? 695 | - 플러그인(plugin)이란? 696 | - 바벨이란? 697 | - 트랜스파일이란? 698 | 699 | 모듈 시스템 700 | 701 | - 모듈을 사용함으로써 얻을 수 있는 장점은? 702 | - 자바스크립트 모듈을 구현하는 대표적인 '명세'에는 어떤 것이 있을까? 703 | - AMD와 CommonJS가 어떻게 다를까? 704 | - ES2015(ES6)의 ES Module없이 모듈의 문제점을 어떻게 해결할 수 있을까? 705 | - IIFE 방식으로 모듈을 사용하는 방법은? 706 | 707 | 컴포넌트 708 | 709 | - 프론트엔드에서 컴포넌트란? 710 | - 좋은 컴포넌트를 설계하기 위해 따를 수 있는 원칙에는 어떤 것들이 있을까? 711 | 712 | 기타 713 | 714 | - URI와 URL의 차이는? 715 | - 웹 접근성(Web Accessibility) 716 | - HTML5 717 | 718 | [(목차로 돌아가기)](#table-of-contents) 719 | 720 |
721 | 722 | --- 723 | 724 | ### JavaScript 725 | 726 | ### [(답변 보러가기 →)](https://github.com/heech1013/tech-interview-handbook/blob/main/javascript/README.md) 727 | 728 | 언어의 특징 729 | 730 | - JS의 언어적인 특징? 731 | - 인터프리터 언어와 컴파일 언어의 차이점? 732 | - 인터프리터 언어와 컴파일 언어의 장단점? 733 | - 프로토타입 기반 언어란? 734 | 735 | 엔진 & 런타임 736 | 737 | - JavaScript 엔진의 구성은? 738 | - JavaScript 런타임이란? 739 | 740 | 객체(Object) 741 | 742 | - Object(객체)란? 743 | - 객체를 생성하는 방법은? 744 | 745 | 프로토타입(Prototype) 746 | 747 | - 클래스 기반의 객체지향 프로그래밍 언어와, 프로토타입 기반의 객체지향 프로그래밍 언어(JavaScript)의 차이점은? 748 | - prototype이란? 749 | - 프로토타입을 사용하는 이유는? (활용되는 예시는?) 750 | - (참고) `[[Prototype]]` & `__proto__` & `prototype` 751 | - 프로토타입이 결정되는 시기는? 752 | - prototype chain이란? 753 | - 프로토타입 객체를 확장하는 방법은? 754 | - 값을 할당할 때와, 참조할 때 프로토타입 체인이 동작하는 여부? 755 | - 프로토타입 객체를 동적으로 변경하는 방법은? 756 | - 프로토타입 객체를 동적으로 변경하기 이전에 생성된 객체와, 이후 생성된 객체의 차이점은? 757 | 758 | Class `보충` 759 | 760 | - (참고) Class의 constructor 761 | 762 | Closure 763 | 764 | - Closure란? 765 | - Closure의 동작 원리를 (실행 컨텍스트와 관련하여) 설명? 766 | - Closure의 활용법? 767 | - Closure의 상태 유지가 전역 변수에 비해 갖는 이점? 768 | - 렉시컬 스코핑(lexical scoping)이란? 769 | - Closure의 단점? 770 | - Closure가 참고하고 있는 메모리를 해제해주려면 어떻게 할까? 771 | - 클로저로 인해 자주 발생하는 실수에는 어떤 것들이 있을까? `보충` 772 | 773 | this 774 | 775 | - this란? 776 | - this의 값이 결정되는 방식을 설명? 777 | - 함수가 '일반 함수로서' 호출될 때 this가 바인딩되는 객체는? 778 | - 전역객체란? 779 | - Browser-side와 server-side에서의 전역객체가 어떻게 다른가? 780 | - 그러면 함수가 '일반 함수로서', 함수의 내부 함수나 메소드의 내부 함수, 콜백 함수 등으로서 호출될 때는? 781 | - 함수가 '일반 함수로서' 호출되었을 때 this가 전역 객체를 참조하는 것을 회피하는 방법이 있을까? 782 | - 함수가 '메소드로서' 호출될 때 this가 바인딩되는 객체는? 783 | - 그러면 함수가 '프로토타입 객체의 메소드로서' 호출될 때는? 784 | - 함수가 '생성자 함수로서' 호출될 때 this가 바인딩되는 객체는? 785 | - 객체 리터럴 방식과 생성자 함수 방식의 차이는? 786 | - 명시적으로 this를 바인딩하는 방법? 787 | - this를 사용할 때 자주 발생하는 실수에는 어떤 것들이 있을까? 788 | - apply, call, bind 메소드의 사용법에 대해 설명? 789 | - 유사 배열(arguments)이 배열의 메소드를 사용할 수 있도록(조작할 때) apply와 call을 사용하는 방법에 대해 아는지? 790 | - 암시적 바인딩과 명시적 바인딩의 우선 순위는? 791 | - arrow function에서의 this는 어떻게 동작하나? 792 | - arrow function을 사용하면 안되는 경우는? 793 | 794 | 비동기 처리 795 | 796 | - JavaScript에서의 비동기 프로그래밍이란? 797 | - JavaScript가 코드를 비동기적으로 실행하는 이유는 뭘까? 798 | - JavaScript에서 (시간이 오래 걸리는) 동기적인 코드가 blocking을 일으키는 이유는 뭘까? 799 | - 프론트엔드에서 비동기 처리가 중요한 이유는? 800 | 801 | 콜백 패턴 & Promise 802 | 803 | - Promise란? 804 | - 동기식 작업과 비동기식 작업이란? 차이점은? 805 | - Promise는 어떤 문제점을 해결하고자 등장했나? 806 | - 비동기 처리에 콜백 패턴을 사용해야 하는 이유는? 807 | - 콜백 방식의 비동기 처리가 에러 처리에 곤란한 이유는? 808 | - Promise를 생성하는 방법은? 809 | - Promise의 상태(state)는 어떤 것들이 있나? 810 | - Promise의 후속 처리 메소드에 대해 설명? 811 | - Promise의 에러 처리는 then과 catch 중 어떤 것으로 하는 것이 더 좋을까? 812 | - Promise의 정적 메소드에 대해 설명? 813 | - Promise.resolve와 Promise.reject에 대해 설명? 814 | - Promise.all과 Promise.race에 대해 설명? 815 | 816 | 이벤트 루프 817 | 818 | - 이벤트 루프란? 819 | - 이벤트 루프가 필요한 이유는? 820 | - Run-to-Completion이란? 821 | - 자바스크립트가 Run-to-Completion으로 동작하는 이유(원리)는? 822 | - 태스크 큐가 동작하는 과정은? 823 | - 태스크 큐와 마이크로 태스크 큐가 동작하는 과정은? 824 | - 이벤트 루프(혹은 태스크 큐의 우선 순위)로 인해 사용자 경험에 해가 되는 경우가 있을까? 825 | - 고비용 연산으로 인한 블로킹에 대응하는 방법은? 826 | - (참고) 활용 예시: progress bar 827 | 828 | 실행 컨텍스트 829 | 830 | - 실행 컨텍스트란? 831 | - 실행 가능한 코드란? 832 | - 실행에 필요한 환경이란? 833 | - 코드가 실행되고, 함수가 실행되고 끝나는 과정을 실행 컨텍스트 스택으로 설명해본다면? 834 | - 실행 컨텍스트의 (물리적인) 구조는? 835 | - Variable Object란? 836 | - 전역 컨텍스트와 함수 컨텍스트에서 VO가 가리키는 객체(내용)의 차이는? 837 | - 스코프 체인이란? 838 | - 특정 EC의 스코프 체인에는 어떤 스코프가 담겨있나? 839 | - 변수를 검색하는 과정을 스코프 체인과 연관하여 설명해본다면? 840 | - 실행 컨텍스트에 값이 채워지는 순서는? (실행 컨텍스트가 생성되는 순서는?) 841 | - 변수 객체화가 진행되는 과정은? 842 | - 클로저를 실행 컨택스트에 기반해 설명해본다면? 843 | - 함수 호이스팅이란? 844 | - 변수 호이스팅이란? 845 | 846 | 호이스팅 847 | 848 | - 호이스팅이란? 849 | - 호이스팅의 대상은? 850 | - 함수 선언문과 함수 표현식의 차이는? 851 | - 함수 선언문에 비해 함수 표현식이 가지는 장점은? 852 | - 호이스팅에서의 우선순위에 대해 설명해본다면? 853 | - 호이스팅은 지향해야 할까, 지양해야 할까? 854 | - 호이스팅을 방지하기 위한 방법은? 855 | - 호이스팅을 지양해야 함에도 불구하고, var와 호이스팅을 이해해야 하는 이유는? 856 | 857 | EcmaScript 858 | 859 | - EcmaScript란? 860 | - ECMAScript와 JavaScript의 관계는? 차이점은? 861 | - ES6에서 추가된 문법에 대해 아는 것이 있는지? 862 | 863 | 기타 864 | 865 | - 자바스크립트 배열도 객체일까? (배열의 내부 구조는?) 866 | - use strict란? 867 | 868 | [(목차로 돌아가기)](#table-of-contents) 869 | 870 |
871 | 872 | ## Reference 873 | 874 | - [CS144 Introduction to Computer Networking Fall 2016 Stanford University](https://www.youtube.com/playlist?list=PLvFG2xYBrYAQCyz4Wx3NPoYJOFjvU7g2Z) 875 | - [최희준 교수의 컴퓨터 일반](https://www.youtube.com/channel/UC7Gm_n3bUqqbOiDR3E1U2qg) 876 | - [Operating System, CPA310, KOREATECH](https://www.youtube.com/playlist?list=PLBrGAFAIyf5rby7QylRc6JxU5lzQ9c4tN) 877 | - [운영체제: 아주 쉬운 세가지 이야기](https://github.com/remzi-arpacidusseau/ostep-translations/tree/master/korean) 878 | - [별걸다하는 IT - 운영체제](https://jhnyang.tistory.com/category/%EB%B3%84%EA%B1%B8%EB%8B%A4%ED%95%98%EB%8A%94%20IT/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C%20OS) 879 | - [NHN TOAST FE Guide](https://ui.toast.com/fe-guide/ko) 880 | - [PoiemaWeb](https://poiemaweb.com/) 881 | - [Interview Question for Beginner](https://github.com/JaeYeopHan/Interview_Question_for_Beginner) 882 | - [Tech Interview for Developer](https://gyoogle.dev/blog/) 883 | - [Gidhub - Technology](https://goodgid.github.io/category/#Technology) 884 | 885 | --- 886 | 887 | [![Hits](https://hits.seeyoufarm.com/api/count/incr/badge.svg?url=https%3A%2F%2Fgithub.com%2Fheech1013%2Fstudy-note&count_bg=%2379C83D&title_bg=%23555555&icon=&icon_color=%23E7E7E7&title=hits&edge_flat=false)](https://hits.seeyoufarm.com) 888 | -------------------------------------------------------------------------------- /data-structure-and-algorithm/README.md: -------------------------------------------------------------------------------- 1 | # Data Structure & Algorithm 2 | 3 | ## Table of Contents 4 | 5 | Data Structure 6 | 7 | - 스택과 큐에 대해 설명해본다면? 8 | - 연결 리스트(Linked List)란? 9 | - 그래프와 트리란? 10 | - 이진 탐색 트리(Binary Search Tree, BST)란? 11 | - 이진 탐색 트리의 연산에 대해 설명해본다면? 12 | - 불균형한 이진 탐색 트리의 검색 연산을 보완하기 위한 방법은? 13 | - 힙이란? 14 | - 힙의 삽입과 삭제 연산에 대해 설명해본다면? 15 | - 우선순위큐를 구현하는 방법에는 어떤 것들이 있을까? 16 | - 해시 테이블(Hash Table)이란? 17 | - 해시 값의 충돌을 해결하는 방법에는 어떤 것들이 있을까? 18 | 19 | Algorithm 20 | 21 | - 코딩 인터뷰 팁 22 | - 정렬의 종류에는 어떤 것들이 있을까? 23 | - 퀵 소트의 피벗 지정 방식을 어떻게 개선할 수 있을까? 24 | - n번째 피보나치 수를 구하는 방법은? 25 | - DFS와 BFS의 시간 복잡도는? 26 | 27 | ## Data Structure 28 | 29 | ### 스택과 큐에 대해 설명해본다면? 30 | 31 | 스택 32 | 33 | - 가장 마지막에 삽입된 데이터가 가장 먼저 제거되는 자료구조 34 | - 변수 `TOP`이 스택의 가장 위를 가리키며, 이곳을 통해서만 삽입과 삭제가 이뤄진다. 35 | - 삽입/삭제하는 연산 `push`와 `pop`을 메소드로 가진다. 36 | - 활용 예시 37 | - 웹 브라우저 방문 기록 구현 38 | - 콜스택(Call Stack) 39 | - 후위 표기법 계산 40 | - 수식의 괄호 검사 41 | 42 | > - 후입선출(LIFO, Last-In-First-Out) 43 | 44 | 큐 45 | 46 | - 가장 먼저 삽입된 데이터가 가장 먼저 제거되는 자료구조 47 | - 삭제가 진행되는 `front`와 삽입이 진행되는 `rear`를 변수로 가진다. 48 | - 삽입 연산 `enqueue`와 삭제 연산 `dequeue`를 메소드로 가진다. 49 | - 활용 예시 50 | - 우선순위가 같은 task 간 실행 순서 관리 51 | - 프로세스 스케줄링 52 | - BFS 구현 53 | 54 | > - 선입선출(FIFO, First-In-First-Out) 55 | 56 | --- 57 | 58 | ### 연결 리스트(Linked List)란? 59 | 60 | - 연속적인 메모리 위치에 저장되지 않는 선형적인 자료구조 61 | - 포인터(다음 노드에 대한 참조)를 통해 노드(데이터)가 연결된다. 62 | 63 | > - 단일 연결 리스트(Single Linked List), 다중 연결 리스트(Doubly Linked List) 등이 존재한다. 64 | 65 | 장점(배열과의 차이점) 66 | 67 | - 배열은 고정된 크기로 할당이 되는 반면, 연결 리스트는 동적으로 노드를 추가할 수 있다. 68 | - 배열은 중간 위치에 삽입, 삭제가 `O(n)`의 시간 복잡도를 가지지만, 연결 리스트는 `O(1)`의 시간 복잡도를 가진다. 69 | 70 | > - 배열은 인덱스로 특정 위치의 데이터에 빠르게 액세스할 수 있다. (시간 복잡도: `O(1)`) 71 | 72 | 단점 73 | 74 | - 임의의 데이터에 액세스를 허용하지 않아 순차적으로 탐색해야 한다. (시간 복잡도: `O(n)`) 75 | - 각 노드마다 포인터 값을 위한 메모리 공간이 추가로 필요하다. 76 | 77 | --- 78 | 79 | ### 그래프와 트리란? 80 | 81 | 그래프 82 | 83 | - 정점(vertex)과, 정점을 연결하는 간선(edge)으로 구성된 자료구조 84 | - 네트워크 모델이다. 85 | 86 | > - 네트워크 모델: 하위 데이터가 여러 개의 상위 데이터를 가질 수 있도록 표현된 데이터 구조 87 | > - 차수(degree): 한 정점에 연결된 간선의 수 88 | 89 | > - 방향 그래프(Directed Graph)와 무방향 그래프(Undirected Graph)가 있다. 90 | > - 순환 그래프와 비순환 그래프(: 트리)가 있다. 91 | > - 간선에 비용이나 가중치가 할당된 경우 가중치 그래프(Weighted Graph)라 하며, '네트워크'라고도 한다. 92 | 93 | 트리 94 | 95 | - 사이클이 존재하지 않는(비순환) 그래프 96 | - 계층 모델이다. 97 | 98 | > - 계층 모델: 하나의 상위 데이터가 여러 개의 하위 데이터를 가질 수 있도록 표현된 데이터 구조 99 | > - 사이클(cycle): 한 정점에서 출발해 시작한 정점을 다시 돌아오는 경로 100 | 101 | > - 정점이 N개인 트리는 항상 N-1개의 간선을 가진다. 102 | > - 트리의 순회(traversal) 방법에는 preorder, inorder, postorder가 있다. 103 | 104 | --- 105 | 106 | ### 이진 탐색 트리(Binary Search Tree, BST)란? 107 | 108 | - 정렬된 이진 트리 109 | - 노드의 왼쪽 자식 트리에는 노드의 키보다 작은 키를 가지는 노드만 포함하며, 노드의 오른쪽 자식 트리에는 노드의 키보다 큰 키를 가지는 노드만 포함한다. 110 | 111 | > - 이진 탐색 트리는 중복된 키를 포함하지 않는다. 112 | > - inorder 순회로 모든 키를 정렬된 순서로 가져올 수 있다. 113 | 114 | > - Q. 이진 힙과 이진 탐색 트리의 차이점은? (용도, 연산의 시간 복잡도) 115 | 116 | --- 117 | 118 | ### 이진 탐색 트리의 연산에 대해 설명해본다면? 119 | 120 | 검색 121 | 122 | - 루트에서 시작해, 루트보다 작으면 왼쪽 자식 트리에 대해 재귀를 돌리고, 루트보다 크면 오른쪽 자식 트리에 대해 재귀를 돌린다. 일치하는 값을 찾을 때까지 반복한다. 123 | - 시간 복잡도: 이진 탐색 트리가 균형 상태일 경우 `O(logn)`, 불균형 상태일 경우 최악의 경우에 `O(n)`(트리의 높이가 `n`)의 시간 복잡도를 가진다. 124 | 125 | > - 균형 상태: 루트로부터, 왼쪽 자식 트리의 높이와 오른쪽 자식 트리의 높이 차이가 1 이하인 상태. 126 | 127 | 삽입 128 | 129 | - 루트에서 시작해, 루트보다 작으면 왼쪽 자식 트리에 대해 재귀를 돌리고, 루트보다 크면 오른쪽 자식 트리에 대해 재귀를 돌린다. 130 | - 리프 노드에 도착한 후, 노드보다 작으면 왼쪽에, 노드보다 크면 오른쪽에 리프 노드로 삽입한다. 131 | 132 | 삭제 133 | 134 | 1. 삭제할 노드가 리프 노드인 경우 135 | - 해당 노드를 삭제한다. 136 | 2. 삭제할 노드에게 자식 노드가 1개 있는 경우 137 | - 노드를 삭제한 후, 자식 노드를 삭제한 노드의 부모 노드에 연결한다. 138 | 3. 삭제할 노드에게 자식 노드가 2개 있는 경우 139 | - successor 노드(후임자 노드)를 찾는다. successor 노드는 왼쪽 자식 트리의 가장 오른쪽 노드, 혹은 오른쪽 자식 트리의 가장 왼쪽 노드이다. (정하기 나름) 140 | - 삭제할 노드와 successor 노드를 swap한다. 141 | - 삭제하려 했던 노드를 삭제한다. 142 | 143 | --- 144 | 145 | ### 불균형한 이진 탐색 트리의 검색 연산을 보완하기 위한 방법은? 146 | 147 | 자가 균형 이진 탐색 트리를 활용하면 된다. 148 | 149 | - 자가 균형 이진 탐색 트리란, 삽입과 삭제가 일어나는 경우에 자동으로 균형 상태를 유지하는 이진 탐색 트리를 말한다. 150 | - 자가 균형 이진 탐색 트리에는 AVL 트리, 레드 블랙 트리, B tree 등이 있다. 151 | 152 | --- 153 | 154 | ### 힙이란? 155 | 156 | - 최대값, 최소값을 빠르게 찾아내기 위해 고안된 완전 이진 트리. 157 | - 힙의 종류에는 최대 힙(max heap)과 최소 힙(min heap)이 있다. 최대 힙은 부모 노드의 키 값이 자식 노드의 키 값보다 크거나 같다. 최소 힙은 부모 노드의 키 값이 자식 노드의 키 값보다 작거나 같다. 158 | - 배열을 통해 쉽게 구현할 수 있다. 159 | 160 | > - 힙은 우선순위큐를 구현하는 데 사용될 수 있다. 161 | > - 힙은 중복된 값을 허용한다. 반면 이진 탐색 트리는 중복된 값을 허용하지 않는다. 162 | > - 형제 노드 간에는 우선순위의 대소관계가 정해지지 않는다. 이러한 특성을 '반정렬 상태'라고 한다. 163 | > - 구현을 쉽게 하기 위해 배열의 첫번째 인덱스(`[0]`)은 사용되지 않는다. 164 | > - 힙은 일반적으로 이진 힙을 가리킨다. 165 | 166 | > - 이진 트리: 각각의 노드가 최대 2개의 노드를 가지는 트리. 167 | > - 완전 이진 트리: 마지막 레벨을 제외한 모든 레벨이 완전히 채워져 있으며, 마지막 레벨의 모든 노드는 가능한 왼쪽에 위치한 이진 트리. 168 | 169 | --- 170 | 171 | ### 힙의 삽입과 삭제 연산에 대해 설명해본다면? 172 | 173 | 삽입 174 | 175 | - 배열의 마지막에 새로운 데이터를 삽입한다. 176 | - 삽입된 데이터의 우선순위가 부모 노드의 값보다 높지 않을 때까지 swap한다. (: `shiftUp()`) 177 | - `O(logN)`의 시간 복잡도를 가진다. 178 | 179 | 삭제 180 | 181 | - 배열의 첫번째 원소와 마지막 원소를 swap한다. 182 | - 배열의 마지막 원소를 삭제한다. 183 | - 배열의 첫번째 원소에 대해, 우선순위가 자식 노드의 값보다 낮지 않을 때까지 swap한다. (: `shiftDown()`) 184 | - `O(logN)`의 시간 복잡도를 가진다. 185 | 186 | --- 187 | 188 | ### 우선순위큐를 구현하는 방법에는 어떤 것들이 있을까? 189 | 190 | - 배열, 연결 리스트, 힙으로 구현할 수 있다. 191 | - 배열과 연결 리스트는 삭제 연산의 시간 복잡도에서 우위를 점하지만, 힙의 삽입 연산 시간 복잡도가 월등하기 때문에 힙으로 구현한다. 192 | 193 | 배열 194 | 195 | - 삽입: 위치를 찾기 위해 순차적으로 데이터를 순회해야 하며, 중간에 삽입할 경우 원소들을 뒤로 하나씩 미뤄야 하므로 `O(n)`의 시간 복잡도를 가진다. 196 | - 삭제: 가장 첫번째 원소를 반환하면 되므로 `O(1)`의 시간 복잡도를 가진다. 197 | 198 | 연결 리스트 199 | 200 | - 삽입: 위치를 찾기 위해 순차적으로 데이터를 순회해야 하므로 `O(n)`의 시간 복잡도를 가진다. 201 | - 삭제: 가장 첫번째 노드의 값을 반환하면 되므로 `O(1)`의 시간 복잡도를 가진다. 202 | 203 | 힙 204 | 205 | - 삽입과 삭제: 우선순위에 따른 위치를 탐색할 때 부모와 자식 간의 비교만 이뤄진다. 트리의 높이가 증가할 때마다 저장 가능한 데이터의 개수가 2배씩 증가하므로, 삽입과 삭제 모두 `O(log2n)`의 시간 복잡도를 가진다. 206 | 207 | > - 우선순위큐: 들어간 순서와 상관 없이 우선순위가 높은 데이터 먼저 삭제되는 큐 208 | 209 | --- 210 | 211 | ### 해시 테이블(Hash Table)이란? 212 | 213 | - key와 value의 형태로 데이터를 저장하는 자료구조 214 | - 평균적으로 상수 시간 내에 삽입, 삭제, 검색을 수행할 수 있다. 215 | 216 | > - 해시(hash, hash value): 임의의 데이터로부터 해시 함수를 통해 출력(매핑)된 데이터. 217 | > - 해시 함수(hash function): 임의의 길이의 데이터를 고정된 길이의 데이터로 매핑하는 것. 218 | > - 입력값이 같으면 출력값도 같다. 219 | > - 고정된 길이의 반환값을 가진다. 220 | > - 출력값을 토대로 입력값을 계산할 수 없어야 한다. 221 | > - 해시의 충돌: 서로 다른 두 개 이상의 키가 동일한 위치(동일한 해시값)을 가지는 경우를 말한다. 222 | > - 삽입, 삭제, 검색 연산은 평균 `O(1)`, 최악의 경우 `O(n)`의 시간 복잡도를 가진다. 223 | 224 | --- 225 | 226 | ### 해시 값의 충돌을 해결하는 방법에는 어떤 것들이 있을까? 227 | 228 | Chaining 방식과 Open Addressing 방식이 있다. 229 | 230 | Chaining 231 | 232 | - 테이블의 각 요소를 연결 리스트로 구성한다. 233 | - 충돌이 발생했을 경우, 새로 들어온 값을 연결 리스트의 가장 앞 노드로 추가한다. 234 | 235 | > - 연결 리스트는 선형 자료구조로, 삽입, 삭제, 검색 연산의 시간 복잡도가 최악의 경우 `O(n)`이다. 이를 개선하기 위해 각 요소를 연결 리스트 대신 이분 탐색 트리로 구성할 수 있다. 이 경우 시간 복잡도는 평균적으로 `O(logn)`이 된다. 236 | > (물론 이분 탐색 트리도 최악의 경우 `O(n)`의 시간 복잡도를 보일 수 있으며, 이는 자가 균형 이분 탐색 트리를 활용해 개선할 수 있다.) 237 | 238 | Open Addressing 239 | 240 | - (별도의 저장 공간을 늘리지 않고) 충돌이 발생한 경우 빈 공간을 찾을 때까지 탐색한다. 241 | - 3가지 방법이 있다: 선형 조사, 이차원 조사, 이중 해싱 242 | 243 | 1. 선형 조사(Linear Probing) 244 | 245 | - 충돌이 발생한 경우 충돌한 자리의 다음 값(혹은 `i`를 더한 다음 값)을 확인한다. 246 | - 특정 구간에 원소들이 몰리는 '1차 군집(primary clustering)' 현상이 발생한다. (군집의 크기가 확장되면 연산 성능이 저하된다.) 247 | 248 | > - 선형 조사의 방정식: `h_k = (h(x) + i) mod m` 249 | > - 삭제 연산 시, 값을 삭제한 후 해당 자리에 값이 존재했었다는 것을 표시(`DELETED` 등)해야 한다. 그렇지 않으면 선형 조사 중 중간에 빈 공간을 발견해, 실제로 존재하는 값임에도 존재하지 않는 것으로 판단할 수 있다. 250 | 251 | 2. 이차원 조사(Quadratic Probing) 252 | 253 | - 충돌이 발생한 경우 이차 함수 값만큼 크기를 늘려가며 빈 공간을 탐색한다. 254 | - 군집을 빠르게 탈출할 수 있다. 255 | - 그러나 선형 조사와 마찬가지로, 초기 해시값이 동일하면 '2차 군집(secondary clustering)' 현상을 겪는다. 256 | 257 | > - 이차원 조사의 방정식: `h_k(x) = h(x) + C1*i^2 + C2*i` 258 | 259 | 3. 더블 해싱(Double Hashing) 260 | 261 | - 두개의 해시 함수를 사용해 빈 공간을 탐색한다. 262 | - 첫 번째 해시 함수 값이 같아도, 두 번째 해시 함수로 인해 완전히 다른 해시값이 생성된다. 263 | - 군집 현상이 발생하지 않는다. 264 | 265 | > - 더블 해싱의 방정식: `h_k(x) = (h(x) + i*f(x)) mod m` 266 | 267 | --- 268 | 269 | ## Algorithm 270 | 271 | ### 코딩 인터뷰 팁 272 | 273 | > Reference: [https://www.mtu.edu/career/students/networking/interviews/prepare.pdf](https://www.mtu.edu/career/students/networking/interviews/prepare.pdf) 274 | 275 | Q. 문제를 어떻게 풀어야 할까? 276 | 277 | - 면접관에게는 언제든 질문해도 괜찮다. 278 | - 문제를 풀어보라는 지시를 받으면, 처음에는 바로 풀어보기 전에 먼저 문제를 정의하고 분석해야 한다. 279 | - 만약 잘 이해가 되지 않는다면, 면접관에게 도움을 청하거나 더 구체적인 설명을 요구해야 한다. 280 | - 만약 문제를 푸는 과정에서 무언가 추론을 해야할 일이 생긴다면, 추론한 내용을 말로 표현하고 면접관에게 해당 내용이 맞는지 확인해야 한다. 281 | - 문제의 각 파트에 대해 어떻게 생각하고 있고, 어떻게 문제를 해결해나가고 있는지 끊임없이 설명해야 한다. 그래야 면접관이 문제를 접근 방식과 생각의 흐름에 관심을 가질 수 있기 때문이다. 또한, 그래야 문제를 풀다가 막혔을 때 그 사실을 면접관이 알 수 있고, 적절한 힌트를 제공해줄 수 있기 때문이다. 282 | - 면접관이 제공하는 힌트를 절대 놓치지 않도록 주의를 기울여야 한다. 283 | 284 | Q. 면접관이 보고자 하는 것은 무엇일까? 285 | 286 | > 면접관들은 지원자의 '대답'만큼, 지원자의 '질문'에도 관심을 가진다. 287 | 288 | - 문제를 잘 듣고, 이해하는가? 289 | - **문제 푸는 것을 진행하기 전에 올바른 질문을 던지는가?** 290 | - brute-force 방식으로 문제에 접근하지는 않는가? 291 | - 제대로 체크하기 전에 섣불리 추론하지는 않는가? 292 | - 문제를 이해하거나 푸는 데 너무 오래 걸리지는 않는가? 293 | - 지원자가 최선의 답변을 선택하기 전에, 여러 해결책을 내놓는 과정을 즐기고 있는가? 294 | - 문제를 풀기 위한 새로운 방법이나 아이디어가 발견되었는가? 295 | - 지원자가 창의적이고 유연한 해결책을 내놓으며, 새로운 아이디어에 열려있는가? 296 | 297 | --- 298 | 299 | ### 정렬의 종류에는 어떤 것들이 있을까? 300 | 301 | 1. 거품 정렬(Bubble sort) 302 | 303 | - 서로 인접한 두 원소의 대소를 비교하고 교환하는 알고리즘 304 | - 매 순회마다 가장 큰 원소가 맨 뒤부터 순차적으로 쌓인다. 305 | 306 | ```jsx 307 | function bubbleSort(arr) { 308 | let temp; 309 | 310 | for (let i = 0; i < arr.length - 1; i++) { 311 | for (let j = 1; j < arr.length - i; j++) { 312 | if (arr[j - 1] > arr[j]) { 313 | [arr[j - 1], arr[j]] = [arr[j], arr[j - 1]]; // swap 314 | } 315 | } 316 | } 317 | } 318 | ``` 319 | 320 | 분석 321 | 322 | - 시간 복잡도: `(n-1) + (n-2) + ... + 2 + 1 = n(n-1)/2` 이므로, `O(n^2)` 323 | - 공간 복잡도: 주어진 배열 안에서 swap을 통해 정렬이 수행되므로, `O(n)` 324 | 325 | 장점 326 | 327 | - 구현이 간단하고 직관적이다. 328 | - 제자리 정렬로, 다른 메모리 공간을 필요로 하지 않는다. 329 | - 안정 정렬(stable sort)이다. 330 | 331 | 단점 332 | 333 | - 비효율적 시간 복잡도 334 | - 정렬되어 있지 않은 원소가 제자리를 찾아가기 위해 swap 연산이 많이 발생한다. 335 | 336 | -- 337 | 338 | 2. 선택 정렬(Selection sort) 339 | 340 | - 매 순회마다 원소를 집어넣을 위치를 정해놓고, 어떤 원소를 넣을지 선택하는 알고리즘 341 | 342 | ```jsx 343 | function selectionSort(arr) { 344 | for (let i = 0; i < arr.length - 1; i++) { 345 | // i: 원소를 집어넣을 위치의 인덱스 346 | let minIdx = i; 347 | 348 | for (let j = i + 1; j < arr.length; j++) { 349 | if (arr[j] < arr[minIdx]) { 350 | minIdx = j; // 가장 작은 값을 찾는다. 351 | } 352 | } 353 | 354 | [arr[i], arr[minIdx]] = [arr[minIdx], arr[i]]; // swap 355 | } 356 | } 357 | ``` 358 | 359 | 분석 360 | 361 | - 시간 복잡도: `(n-1) + (n-2) + ... + 2 + 1 = n(n-1)/2` 이므로, `O(n^2)` 362 | - 공간 복잡도: 주어진 배열 안에서 swap을 통해 정렬이 수행되므로, `O(n)` 363 | 364 | 장점 365 | 366 | - 구현이 간단하고 직관적이다. 367 | - 정렬을 의한 비교 횟수는 많으나, 교환 횟수가 적어 효율적이다. 368 | - 역순으로 정렬되어 있는 배열을 정렬할 때 좋은 효율을 보인다. 369 | - 제자리 정렬로, 다른 메모리 공간을 필요로 하지 않는다. 370 | 371 | 단점 372 | 373 | - 비효율적 시간 복잡도 374 | - 이미/거의 정렬되어 있는 배열을 정렬할 때 최악의 처리 속도를 보인다. 375 | - 불안정 정렬(unstable sort)이다. 376 | 377 | -- 378 | 379 | 3. 삽입 정렬(Insertion sort) 380 | 381 | - 2번째 원소부터 시작해, 매 순회마다 각 원소가 들어갈 위치를 찾아 삽입하는 알고리즘 382 | 383 | ```jsx 384 | function insertionSort(arr) { 385 | for (let i = 1; i < arr.length; i++) { 386 | let temp = arr[i]; // 현재 원소를 저장해놓는다. 387 | let prev = i - 1; // 원소를 삽입할 자리 388 | 389 | // 현재 원소보다 큰 값들을 모두 한 칸씩 뒤로 옮긴다. 390 | while (prev >= 0 && arr[prev] > arr[i]) { 391 | arr[prev + 1] = arr[prev]; 392 | prev--; 393 | } 394 | 395 | // 자기보다 작은 값 바로 뒤에 원소를 삽입한다. 396 | // 그 자리의 값은 한칸씩 미뤄져있어 비어있는 것과 마찬가지이다. 397 | arr[prev + 1] = temp; 398 | } 399 | } 400 | ``` 401 | 402 | 분석 403 | 404 | - 시간 복잡도 405 | - 평균의 경우와 최악의 경우(역순으로 정렬되어 있을 때): `(n-1) + (n-2) + ... + 2 + 1 = n(n-1)/2` 이므로, `O(n^2)` 406 | - 최선의 경우(거의 정렬되어 있는 경우): 각 순회마다 거의 단 한번씩 비교하므로 `O(n)` 407 | - 공간 복잡도: 주어진 배열 안에서 swap을 통해 정렬이 수행되므로, `O(n)` 408 | 409 | 장점 410 | 411 | - 구현이 간단하고 직관적이다. 412 | - 대부분의 원소가 거의 정렬되어 있는 경우 매우 효율적인 알고리즘이다. (이미 정렬된 요소는 한 번의 비교만 수행하고 교환 연산은 발생하지 않는다.) 413 | - 크기가 작은 배열에 대해 성능이 좋다. 414 | - 제자리 정렬이다. 415 | - 안정 정렬이다. 416 | > - 선택 정렬은 각 순회마다 적절한 원소를 선택하기 위해 모든 원소를 탐색하지만, 삽입 정렬은 필요한 만큼만 탐색하므로 비교적 더 효율적이다. 417 | 418 | 단점 419 | 420 | - 평균/최악의 경우 비효율적인 시간 복잡도 421 | 422 | -- 423 | 424 | 4. 퀵 정렬(Quick sort) 425 | 426 | - 피벗(pivot)을 기준으로 배열을 분할해, 재귀적으로 더 작은 단위의 배열을 정렬해나가는 알고리즘 427 | 428 | > - 분할 정복(Divide and Conquer)을 사용하는 정렬 알고리즘이다. 분할 정복이란 큰 문제를 작은 단위의 문제로 쪼개어 해결해나가는 방식이다. 429 | > - 피벗을 선택하는 방법에는 여러가지가 있다(첫번째 요소를 선택, 중간 요소를 선택, 마지막 요소를 선택, 랜덤으로 선택 등). 피벗 선택 방식은 시간 복잡도에 큰 영향을 줄 수 있다. 430 | > - 병합 정렬(Merge sort)와 비교했을 때, 퀵 소트는 배열을 비균등하게 분할한다는 차이점이 있다. 431 | 432 | ```jsx 433 | function quickSort(arr, left, right) { 434 | if (left >= right) { 435 | return; 436 | } 437 | 438 | const pivot = partition(arr, left, right); 439 | 440 | quickSort(arr, left, pivot - 1); 441 | quickSort(arr, pivot + 1, right); 442 | } 443 | 444 | function partition(arr, left, right) { 445 | let pivot = arr[left]; // 첫번째 요소를 피벗으로 설정하는 방식 446 | let i = left, 447 | j = right; 448 | 449 | while (i < j) { 450 | // 오른쪽에서 왼쪽으로 가면서, 피벗보다 작은 값을 찾는다. 451 | while (pivot < arr[j]) { 452 | j--; 453 | } 454 | 455 | // 왼쪽에서 오른쪽으로 가면서, 피벗보다 큰 값을 찾는다. 456 | while (i < j && pivot >= arr[i]) { 457 | i++; 458 | } 459 | 460 | [arr[i], arr[j]] = [arr[j], arr[i]]; // swap 461 | } 462 | 463 | // 마지막으로 첫번째 요소와 피벗값을 교환한다. 464 | // 이로써 피벗의 왼쪽에는 피벗보다 작은 값만, 피벗의 오른쪽에는 피벗보다 큰 값만 존재하게 된다. 465 | arr[left] = arr[i]; 466 | arr[i] = pivot; 467 | 468 | return i; 469 | } 470 | ``` 471 | 472 | 분석 473 | 474 | - 시간 복잡도 475 | - 평균: 배열의 파티션이 균등하게 분할(2분할)된다고 가정했을 때, 재귀 호출 횟수는 `logn`번이다. 각 호출 횟수에서 `n/2`번의 비교 연산을 수행한다. 따라서 `O(logn * n/2) = O(logn * n)` 이므로 `O(nlogn)`. 476 | - 최악의 경우: 이미 거의 정렬되어 있거나, 역순으로 정렬되어 있는 경우이다(더 일반적으로 말하자면, 피벗값이 매번 최소, 혹은 최대값으로 지정되어 파티션이 나뉘어지 않는 상황이라 볼 수 있다). 재귀 호출 횟수가 `n`번, 각 호출 횟수에서 `n/2`번의 비교 연산을 수행하므로 `O(n*n) = O(n^2)`이다. 477 | - 공간 복잡도: 주어진 배열 안에서 swap을 통해 정렬이 수행되므로, `O(n)` 478 | 479 | 장점 480 | 481 | - `O(nlogn)`의 효율적인 시간 복잡도 482 | (`O(nlogn)`의 시간 복잡도를 가지는 다른 정렬 알고리즘에 비해서도 더 효율적인 편에 속한다. 먼 거리의 요소를 비교/swap한다는 점과, 한번 피벗으로 설정된 요소는 이후에는 비교/swap에서 제외된다는 점에서 그렇다.) 483 | - 제자리 정렬이다. 484 | 485 | 단점 486 | 487 | - 최악의 경우 비효율적인 시간 복잡도(단, 개선이 가능하다.) 488 | - 불안정 정렬이다. 489 | 490 | -- 491 | 492 | 5. 병합(합병) 정렬(Merge sort) 493 | 494 | - 배열을 쪼갤 수 있는 만큼 쪼갠 후, 순서를 정렬해가며 다시 병합하는 알고리즘. 495 | 496 | > - 분할 정복(Divide and Conquer)을 사용하는 정렬 알고리즘이다. 497 | 498 | ```jsx 499 | function mergeSort(arr, left, right) { 500 | if (left < right) { 501 | const mid = (left + right) / 2; 502 | 503 | mergeSort(arr, left, mid); 504 | mergeSort(arr, mid + 1, right); 505 | merge(arr, left, mid, right); 506 | } 507 | } 508 | 509 | function merge(arr, left, mid, right) { 510 | const L = arr.slice(left, mid + 1); 511 | const R = arr.slice(mid + 1, right + 1); 512 | 513 | let i = 0, 514 | j = 0, 515 | k = left; 516 | 517 | while (i < L.length && j < R.length) { 518 | if (L[i] <= R[j]) { 519 | arr[k++] = L[i++]; 520 | } else { 521 | arr[k++] = R[j++]; 522 | } 523 | } 524 | 525 | // remain 526 | while (i < L.length) { 527 | arr[k++] = L[i++]; 528 | } 529 | while (j < R.length) { 530 | arr[k++] = R[j++]; 531 | } 532 | } 533 | ``` 534 | 535 | 분석 536 | 537 | - 시간 복잡도: 매 순회마다 1/2의 크기로 배열을 분할하므로, mergeSort()가 재귀적으로 `logn`번 호출, 각 호출에서 n개의 원소를 순회하며 정렬을 진행하므로 `O(logn * n)` = `O(nlogn)` 538 | - 공간 복잡도: 병합 과정에서 추가 배열이 필요하다. 상수항 제거로, `O(n)` 539 | 540 | 장점 541 | 542 | - 효율적인 시간 복잡도 543 | - 데이터의 특성과 별개로 일정한 시간 복잡도 `O(nlogn)`를 보인다. 544 | - 순차적으로 데이터를 비교하며 정렬하기 때문에, 연결 리스트를 정렬할 때 효율적이다. (반면 퀵 소트는 임의 접근으로, 연결 리스트를 정렬할 때 비효율적이다. 연결 리스트는 삽입과 삭제 연산은 효율적이지만 탐색/접근 연산은 `O(n)`으로 비효율적이기 때문이다.) 545 | - 안정 정렬이다. 546 | 547 | 단점 548 | 549 | - 제자리 정렬이 아니다. 550 | - 이동 횟수가 많아, 레코드의 크기가 큰 경우 상대적으로 시간이 더 소요된다. 551 | 552 | -- 553 | 554 | 6. 힙 정렬(Heap sort) 555 | 556 | - 최대 힙 트리, 또는 최소 힙 트리를 구축해 정렬을 수행하는 알고리즘 557 | 558 | > - 오름차순을 위해서는 **최대** 힙을, 내림차순을 위해서는 **최소** 힙을 구축한다. 559 | > - 힙 생성 알고리즘(heapify algorithm)은 하나의 특정 노드에 대해서만 수행하는 알고리즘이며, 해당 노드를 제외하고는 최대/최소 힙이 구성되어 있는 상태라는 전제가 필요하다. 특정 노드의 두 자식 노드 중 더 큰 자식과 자신의 위치를 바꾸는 알고리즘이다. 560 | > - 보통 힙을 구성할 때는 노드 조작을 편리하게 하기 위해 첫번째 인덱스를 비워둔다(인덱스 1부터 시작). 그러나 힙 정렬은 기존 배열을 정렬해야 하므로, 인덱스 0부터 시작한다. 561 | 562 | 힙 정렬 과정(오름차순 기준) 563 | 564 | 1. 오름차순일 경우, 기존 배열로 최대 힙을 구성한다. 565 | 566 | - 최소 힙은 그 자체로 오름차순 배열이 되지 못한다. 반정렬 상태이기 때문이다. 567 | - 가장 작은 서브 트리부터 순차적으로 최대 힙을 만족하도록 구성한다. 루트를 부모로 가지는 가장 큰 서브 트리를 마지막으로 전체 배열이 최대 힙을 만족하게 된다. (가장 작은 서브 트리의 루트는 가장 마지막 노드의 부모 트리이다.) 568 | - 특정 서브 트리에서 부모-자식 교환이 일어났을 경우, 교환된 자식 노드의 서브 트리에서 (재귀적으로, 혹은 순차적으로) 다시 heapify를 수행한다. 569 | 570 | 2. 루트 노드를 순차적으로 pop해, 배열의 맨 뒤부터 차례대로 삽입한다. 571 | 572 | ```jsx 573 | const parent = (i) => (i - 1) / 2; 574 | const left = (i) => i * 2 + 1; 575 | const right = (i) => i * 2 + 2; 576 | 577 | function heapSort(arr) { 578 | if (size < 2) return; 579 | 580 | // 가장 마지막(오른쪽 끝) 서브 트리의 부모 노드부터 시작해, 581 | // 루트 노드까지 순회하며 재귀적으로 heapify를 수행한다. 582 | for (let parentIdx = parent(arr.length - 1); parentIdx >= 0; parentIdx--) { 583 | heapify(arr, parentIdx, arr.length); 584 | } 585 | 586 | // 루트 노드와 마지막 요소를 교환함으로써, 587 | // 배열의 맨 뒤부터 가장 값이 큰 요소로 채운다. 588 | // (해당 노드는 다음 순회에서 제외된다) 589 | for (let i = arr.length - 1; i > 0; i--) { 590 | [arr[0], arr[i]] = [arr[i], arr[0]]; 591 | heapify(arr, 0, i - 1); 592 | } 593 | } 594 | 595 | function heapify(arr, parentIdx, lastIdx) { 596 | // 자식 인덱스가 마지막 인덱스를 넘지 않을 때까지 반복. 597 | // 단, 왼쪽 자식 인덱스를 기준으로 해야 왼쪽 자식이 마지막 인덱스인 경우를 조건에 포함할 수 있다. 598 | while ( 599 | left(parentIdx) <= lastIdx && 600 | // 부모 노드보다 더 큰 자식이 있을 때 601 | (arr[left(parentIdx)] > arr[parentIdx] || 602 | (right(parentIdx) <= lastIdx && arr[right(parentIdx)] > arr[parentIdx])) 603 | ) { 604 | const greaterChildIdx = 605 | right(parentIdx) <= lastIdx && 606 | arr[right(parentIdx)] > arr[left(parentIdx)] 607 | ? right(parentIdx) 608 | : left(parentIdx); 609 | 610 | // swap 611 | [arr[parentIdx], arr[greaterChildIdx]] = [ 612 | arr[greaterChildIdx], 613 | arr[parentIdx], 614 | ]; 615 | parentIdx = greaterChildIdx; 616 | } 617 | } 618 | ``` 619 | 620 | 분석 621 | 622 | - 시간 복잡도 623 | - heapify를 통해 최대/최소 힙을 구성하는 시간: 부모 노드의 개수는 `n/2`(소수점 절삭), heapify는 최대 트리의 높이만큼 수행하므로 `logn`의 시간이 소요된다. 따라서 `n/2*logn ~= nlogn` 624 | - 루트를 배열 끝으로 넘기고 heapify를 수행하는 시간: 모든 요소에 대해 heapify를 수행하므로, `nlogn` 625 | - 따라서, 시간 복잡도는 `O(nlogn + nlogn) = O(nlogn)` 626 | - 공간 복잡도: 제자리 정렬로, `O(n)` 627 | 628 | 장점 629 | 630 | - 효율적인 시간 복잡도 631 | - 최악의 경우에도 `O(nlogn)`의 시간 복잡도를 보인다. 632 | - 정렬된 상태의 전체 배열이 아니라, 가장 크거나 작은 값 몇개만 필요할 때 더 효율적이다. 633 | - 제자리 정렬이다. 634 | 635 | 단점 636 | 637 | - 일반적인 `O(nlogn)` 정렬 알고리즘에 비해 비교적 성능이 떨어진다. 638 | - 불안정 정렬이다(최대/최소 힙을 구성하는 과정에서 불안정 정렬 상태가 된다). 639 | 640 | --- 641 | 642 | ### 퀵 소트의 피벗 지정 방식을 어떻게 개선할 수 있을까? 643 | 644 | 1. 난수 분할 645 | 646 | - 피벗이 항상 편향되는 최악의 경우를 방지하기 위해 피벗 값을 매번 랜덤한 위치에서 지정한다. (이미 정렬된 배열이 들어왔을 때, 항상 편향된 피벗을 선택하게 되는 위험을 방지할 수 있다.) 647 | 648 | 2. 세 값의 중위(Median of Three) 649 | 650 | - 배열의 가장 첫번째 인덱스, 마지막 인덱스, 중간 인덱스를 선택한 후, 그 중 중간에 있는 값을 피벗으로 지정한다. 651 | 652 | > - (피벗 지정 방식과 별개) 특정 크기 미만으로 분할된 배열부터는 삽입 정렬을 수행하는 방식으로 퀵 소트를 개선할 수 있다. 재귀 호출되는 깊이를 줄여줘 메모리를 절약할 수 있으며, 삽입 정렬은 크기가 작은 배열에 대해 성능이 좋으므로 시간도 절약할 수 있다. 653 | 654 | --- 655 | 656 | ### n번째 피보나치 수를 구하는 방법은? 657 | 658 | > - 피보나치 수열: 첫번째, 두번째 항이 1이며, 그 뒤 모든 항은 바로 앞 두 항의 합인 수열. 659 | > - 처음 두 항은 `1`, `1`이며, 편의상 0번째 항을 `0`으로 두기도 한다. 660 | 661 | 1. 재귀적 풀이 662 | 663 | - 피보나치 수의 함수적 정의를 그대로 구현한 방법. 664 | 665 | ```jsx 666 | function fibo(n) { 667 | if (n < 2) return n; 668 | 669 | return fibo(n - 1) + fibo(n - 2); 670 | } 671 | ``` 672 | 673 | 분석 674 | 675 | - 시간 복잡도: 함수가 한 번 호출될 때마다 함수가 두 번 다시 재귀적으로 호출되므로, 지수적으로 증가해 `O(2^n)`이 된다. 676 | 677 | -- 678 | 679 | 2. 반복적 풀이 680 | 681 | - 0번째, 1번째 피보나치 수부터 계속 더하는 식으로 피보나치 수를 구할 수 있다. 682 | 683 | ```jsx 684 | function fibo(n) { 685 | if (n < 2) return n; 686 | 687 | let a = 0, 688 | b = 1; 689 | 690 | for (let i = 0; i < n; i++) { 691 | b = a + b; 692 | a = b; 693 | } 694 | 695 | return b; 696 | } 697 | ``` 698 | 699 | 분석 700 | 701 | - 시간 복잡도: n번의 반복으로 피보나치 수를 구할 수 있다. `O(n)` 702 | 703 | -- 704 | 705 | 3. 동적 계획법(DP)를 활용한 풀이 706 | 707 | - 재귀적 풀이에서 중복되는 sub problem이 계속 나타난다. 이를 메모이제이션으로 해결하는 방법. 708 | 709 | ```jsx 710 | function fibo(n) { 711 | if (n < 2) return n; 712 | 713 | const DP = [0, 1]; 714 | 715 | for (let i = 2; i <= n; i++) { 716 | DP[n] = DP[n - 1] + DP[n - 2]; 717 | } 718 | 719 | return DP[n]; 720 | } 721 | ``` 722 | 723 | 분석 724 | 725 | - 시간 복잡도: `O(n)` 726 | 727 | > - 행렬 곱셈을 이용한 풀이와 일반항을 이용한 풀이도 존재한다. 이 두 방법들은 `O(logn)`만에 피보나치 수를 구할 수 있다. 728 | 729 | --- 730 | 731 | ### DFS와 BFS의 시간 복잡도는? 732 | 733 | > - DFS(깊이 우선 탐색): 다음 브랜치로 넘어가기 전에 현재 브랜치를 모두 탐색하고 넘어가는 탐색. stack이나 재귀로 구현할 수 있다. 734 | > - BFS(너비 우선 탐색): 시작 노드를 방문 후, 해당 노드와 인접한 모든 노드를 우선적으로 방문하는 탐색. queue로 구현할 수 있다. 735 | 736 | 구현 방법에 따라 시간 복잡도가 다르다. 737 | 738 | 1. 인접 행렬(adjacent matrix)로 구현 739 | 740 | - 각 `DFS(v)`는 모든 정점을 순회하며 연결된 정점을 확인하므로 `O(V)`의 시간 복잡도를 가진다. 741 | - `DFS(v)`가 총 정점의 개수 V만큼 호출되므로, 최종 시간 복잡도는 `O(V^2)`가 된다. 742 | > - 인접 행렬: 그래프 이론에서 어느 정점들이 간선으로 연결되었는지를 나타내는 정사각 행렬 743 | 744 | 2. 인접 리스트(adjacent list)로 구현 745 | 746 | - 모든 정점을 한 번씩 방문하고, 각 정점에 연결된 간선을 한 번씩 검사하므로 `O(V+E)`의 시간 복잡도를 가진다. (인접 행렬을 사용한 구현과 다르게 `DFS(v)`가 일정한 시간 복잡도를 가지지 않는다. 정점마다 연결된 간선의 수가 각각 다르기 때문이다.) 747 | > - 인접 리스트: 그래프 이론에서, 한 정점에 연결된 다른 정점들을 연결 리스트로 표현하는 방법 748 | 749 | > - 인접 행렬은 정점의 수가 많은 그래프, 인접 리스트는 정점의 수가 적은 그래프에 효율적이다. 750 | 751 | --- 752 | -------------------------------------------------------------------------------- /database/Database 79d9527d1d534251afb6af40532b918b/1-after.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heech1013/study-note/9c5d4ee9887aed616e24701a9a43b1cd53dcf6a4/database/Database 79d9527d1d534251afb6af40532b918b/1-after.png -------------------------------------------------------------------------------- /database/Database 79d9527d1d534251afb6af40532b918b/1-before.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heech1013/study-note/9c5d4ee9887aed616e24701a9a43b1cd53dcf6a4/database/Database 79d9527d1d534251afb6af40532b918b/1-before.png -------------------------------------------------------------------------------- /database/Database 79d9527d1d534251afb6af40532b918b/2-after.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heech1013/study-note/9c5d4ee9887aed616e24701a9a43b1cd53dcf6a4/database/Database 79d9527d1d534251afb6af40532b918b/2-after.png -------------------------------------------------------------------------------- /database/Database 79d9527d1d534251afb6af40532b918b/2-before.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heech1013/study-note/9c5d4ee9887aed616e24701a9a43b1cd53dcf6a4/database/Database 79d9527d1d534251afb6af40532b918b/2-before.png -------------------------------------------------------------------------------- /database/Database 79d9527d1d534251afb6af40532b918b/3-after.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heech1013/study-note/9c5d4ee9887aed616e24701a9a43b1cd53dcf6a4/database/Database 79d9527d1d534251afb6af40532b918b/3-after.png -------------------------------------------------------------------------------- /database/Database 79d9527d1d534251afb6af40532b918b/3-before.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heech1013/study-note/9c5d4ee9887aed616e24701a9a43b1cd53dcf6a4/database/Database 79d9527d1d534251afb6af40532b918b/3-before.png -------------------------------------------------------------------------------- /database/Database 79d9527d1d534251afb6af40532b918b/Untitled 1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heech1013/study-note/9c5d4ee9887aed616e24701a9a43b1cd53dcf6a4/database/Database 79d9527d1d534251afb6af40532b918b/Untitled 1.png -------------------------------------------------------------------------------- /database/Database 79d9527d1d534251afb6af40532b918b/Untitled 2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heech1013/study-note/9c5d4ee9887aed616e24701a9a43b1cd53dcf6a4/database/Database 79d9527d1d534251afb6af40532b918b/Untitled 2.png -------------------------------------------------------------------------------- /database/Database 79d9527d1d534251afb6af40532b918b/Untitled 3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heech1013/study-note/9c5d4ee9887aed616e24701a9a43b1cd53dcf6a4/database/Database 79d9527d1d534251afb6af40532b918b/Untitled 3.png -------------------------------------------------------------------------------- /database/Database 79d9527d1d534251afb6af40532b918b/Untitled 4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heech1013/study-note/9c5d4ee9887aed616e24701a9a43b1cd53dcf6a4/database/Database 79d9527d1d534251afb6af40532b918b/Untitled 4.png -------------------------------------------------------------------------------- /database/Database 79d9527d1d534251afb6af40532b918b/Untitled 5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heech1013/study-note/9c5d4ee9887aed616e24701a9a43b1cd53dcf6a4/database/Database 79d9527d1d534251afb6af40532b918b/Untitled 5.png -------------------------------------------------------------------------------- /database/Database 79d9527d1d534251afb6af40532b918b/Untitled 6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heech1013/study-note/9c5d4ee9887aed616e24701a9a43b1cd53dcf6a4/database/Database 79d9527d1d534251afb6af40532b918b/Untitled 6.png -------------------------------------------------------------------------------- /database/Database 79d9527d1d534251afb6af40532b918b/Untitled 7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heech1013/study-note/9c5d4ee9887aed616e24701a9a43b1cd53dcf6a4/database/Database 79d9527d1d534251afb6af40532b918b/Untitled 7.png -------------------------------------------------------------------------------- /database/Database 79d9527d1d534251afb6af40532b918b/Untitled 8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heech1013/study-note/9c5d4ee9887aed616e24701a9a43b1cd53dcf6a4/database/Database 79d9527d1d534251afb6af40532b918b/Untitled 8.png -------------------------------------------------------------------------------- /database/Database 79d9527d1d534251afb6af40532b918b/Untitled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heech1013/study-note/9c5d4ee9887aed616e24701a9a43b1cd53dcf6a4/database/Database 79d9527d1d534251afb6af40532b918b/Untitled.png -------------------------------------------------------------------------------- /database/Database 79d9527d1d534251afb6af40532b918b/b+tree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heech1013/study-note/9c5d4ee9887aed616e24701a9a43b1cd53dcf6a4/database/Database 79d9527d1d534251afb6af40532b918b/b+tree.png -------------------------------------------------------------------------------- /database/Database 79d9527d1d534251afb6af40532b918b/b-tree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heech1013/study-note/9c5d4ee9887aed616e24701a9a43b1cd53dcf6a4/database/Database 79d9527d1d534251afb6af40532b918b/b-tree.png -------------------------------------------------------------------------------- /database/Database 79d9527d1d534251afb6af40532b918b/bcnf-after.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heech1013/study-note/9c5d4ee9887aed616e24701a9a43b1cd53dcf6a4/database/Database 79d9527d1d534251afb6af40532b918b/bcnf-after.png -------------------------------------------------------------------------------- /database/Database 79d9527d1d534251afb6af40532b918b/bcnf-before.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heech1013/study-note/9c5d4ee9887aed616e24701a9a43b1cd53dcf6a4/database/Database 79d9527d1d534251afb6af40532b918b/bcnf-before.png -------------------------------------------------------------------------------- /database/Database 79d9527d1d534251afb6af40532b918b/index.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heech1013/study-note/9c5d4ee9887aed616e24701a9a43b1cd53dcf6a4/database/Database 79d9527d1d534251afb6af40532b918b/index.png -------------------------------------------------------------------------------- /database/README.md: -------------------------------------------------------------------------------- 1 | # Database 2 | 3 | ## Table of Contents 4 | 5 | 인덱스 6 | 7 | - 인덱스(index)란? 8 | - 인덱스를 사용하면 검색 속도가 빨라지는 이유는? 9 | - 인덱스가 작동하는 과정(순서)은? 10 | - 인덱스를 Hash Table로 구현하지 않는 이유는? 11 | - B-Tree란? 12 | - B+Tree란? 13 | - B-Tree보다 B+ Tree가 갖는 이점은? 14 | - 범위 검색이 Hash table보다 B+ Tree에서 이점을 갖는 이유는? 15 | - 인덱스의 장단점은? 16 | - 인덱스를 생성하기에 적절한 컬럼의 특성은? 17 | - 인덱스를 생성하기에 적절하지 않은 컬럼의 특성은? 18 | - DML(INSERT, DELETE, UPDATE)을 수행할 때 인덱스를 사용하는 컬럼에 대해 추가로 해줘야 하는 작업은? 19 | - 인덱스를 생성/조회하기 위한 SQL문 작성 방법은? 20 | 21 | 트랜잭션 22 | 23 | - 트랜잭션이란? 24 | - 트랜잭션의 성질에는 어떤 것들이 있을까? 25 | - 트랜잭션의 연산에는 어떤 것들이 있을까? 26 | - 트랜잭션의 상태를 설명해본다면? 27 | - 트랜잭션의 고립 수준에 따라 발생 가능한 읽기 이상 현상(Read Phenomena)에 대해 설명해본다면? 28 | - 트랜잭션의 고립 수준 유형에 대해 설명해본다면? 29 | - 트랜잭션의 고립 수준과 동시성과의 상관 관계는? 30 | 31 | 정규화 32 | 33 | - 정규화란? 34 | - 제1 정규화에 대해 설명? 35 | - 제2 정규화에 대해 설명? 36 | - 제3 정규화에 대해 설명? 37 | - BCNF에 대해 설명? 38 | - 데이터베이스의 이상 현상(Anomaly)에는 어떤 것들이 있을까? 39 | - 정규화의 단점은? 40 | - 반정규화(De-normalization)란? 41 | 42 | 키 43 | 44 | - 키란? 45 | - 슈퍼키란? 46 | - 후보키란? 47 | - 기본키란? 48 | - 대체키란? 49 | - 외래키란? 50 | 51 | SQL Query 52 | 53 | - SQL이란? 54 | - JOIN이란? 55 | - INNER JOIN이란? 56 | - OUTER JOIN이란? 57 | - LEFT (OUTER) JOIN / RIGHT (OUTER) JOIN이란? 58 | - CROSS JOIN(카티전 조인)이란? 59 | - JOIN에서 ON과 WHERE의 차이점은? 60 | - (OUTER) JOIN에서 (ON과 WHERE를 이용해서) 차집합을 구하는 방법은? 61 | 62 | DBMS 63 | 64 | - DBMS란? 65 | - DBMS를 사용했을 때의 장점은? 66 | - RDBMS란? 67 | 68 | ## 인덱스 69 | 70 | ### 인덱스(index)란? 71 | 72 | 추가적인 저장 공간을 활용해 테이블의 검색 속도를 향상시키기 위한 자료구조. 73 | 74 | > - 인덱스를 저장하는 데 필요한 디스크 공간은 보통 테이블을 저장하는 데 필요한 디스크 공간보다 적다. 보통 인덱스는 키 - 필드만 가지고 있고, 테이블의 다른 세부 항목들은 가지고 있지 않기 때문이다. 75 | 76 | --- 77 | 78 | ### 인덱스를 사용하면 검색 속도가 빨라지는 이유는? 79 | 80 | ![Database%2079d9527d1d534251afb6af40532b918b/Untitled.png](Database%2079d9527d1d534251afb6af40532b918b/index.png) 81 | 82 | 비유하자면 인덱스는 책의 목차와 같은 역할을 하기 때문이다. 83 | 84 | 예를 들어 `SELECT` 문을 활용해 어떤 테이블의 A 컬럼이 x인 row를 조회한다고 가정해보자. 85 | 86 | - 인덱스가 없다면, 데이터베이스는 모든 row를 순회한다(어느 row가 마지막 row인지 알지 못한다. 이미 다 찾았음에도 끝까지 탐색한 후 종료한다). 87 | - 인덱스가 있다면, A 컬럼 값 기준으로 정렬된 인덱스들이 포인터로 해당하는 행을 가리키고 있으므로, 이분 탐색으로 빠르게 원하는 row들을 찾을 수 있으며 더 이상 탐색할 필요가 없다면 탐색을 중지한다. 88 | 89 | --- 90 | 91 | ### 인덱스가 작동하는 과정(순서)은? 92 | 93 | (A 컬럼에 대한 인덱스가 생성되어 있다) 94 | 95 | - A 컬럼이 포함된 `WHERE` 문 쿼리가 발생한다. 96 | - 인덱스 테이블에서 A 컬럼 값에 해당하는 PK를 가져온다. 97 | - 인덱스 테이블의 PK 값으로, 원본 테이블에서 값을 조회해온다. 98 | 99 | --- 100 | 101 | ### 인덱스를 Hash Table로 구현하지 않는 이유는? 102 | 103 | > 인덱스를 구현할 수 있는 자료구조에는 Hash Table, B+Tree 등이 있다. 104 | 105 | 해시 테이블은 등호(`=`) 연산에만 최적화되어 있기 때문이다. 106 | 해시 테이블은 값이 1만 달라져도 완전히 다른 해시 값을 생성하므로, 부등호 연산(`<`, `>`)이나 `between` 등이 자주 사용되는 DB 검색에는 적합하지 않다. 107 | 108 | > - 해시 테이블은 탐색, 삽입, 삭제를 `O(1)`로 수행할 수 있다. 109 | 110 | (`=`, `<`, `>`, `between` 연산의 예) 111 | 112 | ```sql 113 | -- = 114 | SELECT * FROM member WHERE age = 27; 115 | -- <, > 116 | SELECT * FROM member WHERE age < 30; 117 | -- BETWEEN 118 | SELECT * FROM member WHERE age BETWEEN 20 and 30; 119 | ``` 120 | 121 | --- 122 | 123 | ### B-Tree란? 124 | 125 | ![Database%2079d9527d1d534251afb6af40532b918b/Untitled.png](Database%2079d9527d1d534251afb6af40532b918b/b-tree.png) 126 | 127 | 한 노드 당 자식 노드의 개수가 2개 이상인 이진 탐색 트리. 128 | 129 | 특징 130 | 131 | - 데이터(노드, Node)가 정렬된 상태로 유지된다. 132 | - 가장 상단의 노드인 루트 노드(Root Node), 중간 노드인 브랜치 노드(Branch Node), 최하단의 노드인 리프 노드(Leaf Node)로 구성되어 있다. 133 | - 균형 트리(balanced tree)이다. 134 | 135 | 장점 136 | 137 | - 빠른 탐색 속도: 평균 `O(logN)` 138 | - 균일성: 어떤 값에 대해서도 같은 시간에 결과를 얻을 수 있다. (ex. 위 그림에서 `15`를 찾는 시간과 `28`을 찾는 시간이 거의 동일하다.) 139 | 140 | > - B-tree 뿐만 아니라 트리 구조는 데이터 저장에 자주 사용되는 자료구조이다. 탐색을 단시간 내에 수행할 수 있기 때문이다. 141 | > - 트리의 불균형 상태에 따라 최악의 경우 탐색이 `O(N)`의 시간 복잡도를 가질 수 있다. 이를 방지하기 위해 Balanced tree가 사용되며, 종류에는 B-tree, Red-Black tree 등이 있다. 142 | 143 | --- 144 | 145 | ### B+Tree란? 146 | 147 | ![Database%2079d9527d1d534251afb6af40532b918b/Untitled.png](Database%2079d9527d1d534251afb6af40532b918b/b+tree.png) 148 | 149 | - 확장된 버전의 B-tree. 150 | - B-tree는 모든 노드에 key와 data를 담을 수 있는 것에 반해, B+tree는 리프 노드에만 key와 data를 담을 수 있고, 나머지 노드에는 key만 담을 수 있다. 151 | - B+tree의 리프 노드들은 Linked List로 연결되어 있다. 152 | 153 | > - B+tree의 리프 노드들은 data로 실제 레코드를 찾아가기 위한 주소값을 가지고 있다. 154 | 155 | --- 156 | 157 | ### B-Tree보다 B+ Tree가 갖는 이점은? 158 | 159 | - 리프 노드를 제외하고는 key만 담고 있기 때문에, 더 많은 자료를 수용할 수 있다. 160 | (→ 더 많은 자식 노드 수용 → 더 낮은 트리 높이 → 더 높은 cache hit) 161 | - full scan이 발생할 때, B+tree는 리프 노드에 모든 데이터가 저장되어 있기 때문에 한 번의 선형 탐색이 필요하다. 반면 B-tree는 루트 노드와 브랜치 노드를 모두 확인해야 한다. 162 | 163 | --- 164 | 165 | ### 범위 검색이 Hash table보다 B+ Tree에서 이점을 갖는 이유는? 166 | 167 | - B+tree의 리프 노드들은 Linked List로 연결되어 있기 때문에, 부등호, 범위 연산 등의 검색에 유리하다. 168 | 169 | > - 물론 Hash Table의 검색 속도 `O(1)`에 비해 B+tree는 낮은 검색 속도 `O(logN)`을 가지고 있긴 하지만, 위의 장점으로 인해 B+tree를 사용한다. 170 | > - 실제 InnoDB의 B+tree 구현에서는 Doubly Linked List로 구현이 되어 있다고 한다. 171 | 172 | > Linked list라 부등호, 범위 연산 등의 검색에 유리하다? 173 | > 174 | > - 랜덤 I/O: 디스크 드라이브의 원판을 돌려 읽어야 할 데이터가 저장된 위치로 디스크 헤더를 이동시킨 후 읽는 것. (→ 디스크 헤더를 n번 움직인다.) 175 | > - 순차 I/O: 랜덤 I/O와 같지만, 연속된 페이지에 접근하는 것이기에 한 번의 시스템 콜을 요청한다. (→ 디스크 헤더를 1번 움직인다.) 176 | > - 디스크의 성능은 디스크 헤더의 위치 이동 없이 얼마나 많은 데이터를 읽고 쓰느냐에 따라 결정된다. 177 | 178 | - B+tree에서 자식 노드로 이동하는 것, 혹은 Hash Table에서 이전 값과 1이라도 다른 값을 찾는 것은 모두 랜덤 I/O에 해당한다. 179 | - B+tree에서 Linked List로 연결된 옆 자식 노드로 이동하는 것은 순차 I/O에 해당한다. 180 | 181 | --- 182 | 183 | ### 인덱스의 장단점은? 184 | 185 | 장점 186 | 187 | - 테이블을 조회하는 속도를 향상시킬 수 있다. 188 | 189 | > UPDATE와 DELETE의 성능도 함께 향상된다. UPDATE와 DELETE를 하기 위해서는 특정 대상을 조회해야 하기 때문이다. 190 | > ex) `UPDATE USER SET NAME = 'Lee' WHERE NAME = 'Shin';` 191 | 192 | 단점 193 | 194 | - 인덱스를 관리하기 위해 DB의 약 10%에 해당하는 저장 공간이 필요하다. 195 | - 인덱스를 관리하기 위해 추가 작업으로 인한 오버헤드가 발생한다. 196 | 197 | --- 198 | 199 | ### 인덱스를 생성하기에 적절한 컬럼의 특성은? 200 | 201 | - `WHERE`, `JOIN`, `ORDER BY`에 자주 사용되는 컬럼. 202 | (즉, 활용도가 높은 컬럼. 인덱스를 유지하는 오버헤드를 상회하는 활용도가 있어야 할 것이다.) 203 | - `UPDATE`, `DELETE`가 자주 발생하지 않는 컬럼. 204 | - 데이터의 중복도가 낮은(= Cardinality(분산도)가 높은 컬럼) 컬럼. 205 | - 외래키로 사용되는 컬럼. 206 | 207 | --- 208 | 209 | ### 인덱스를 생성하기에 적절하지 않은 컬럼의 특성은? 210 | 211 | - `UPDATE`, `DELETE`가 빈번한 컬럼. 212 | 213 | : UPDATE와 DELETE 시 기존 인덱스 값을 삭제하지 않고 '사용하지 않음' 처리를 하기 때문에, 실제 데이터에 비해 인덱스의 크기가 과도하게 비대해질 수 있다. 214 | 215 | - 데이터의 중복도가 높은 컬럼. 216 | 217 | : 인덱스를 생성, 유지하는 비용에 비해 조회에서 얻는 이점이 적을 수 있다. 218 | 219 | --- 220 | 221 | ### DML(INSERT, DELETE, UPDATE)을 수행할 때 인덱스를 사용하는 컬럼에 대해 추가로 해줘야 하는 작업은? 222 | 223 | - `INSERT`: 새로운 데이터에 대한 인덱스를 추가 224 | - `UPDATE`: 기존 데이터의 인덱스를 사용하지 않도록 조치하고, 갱신한 데이터에 대한 인덱스를 추가 225 | - `DELETE`: 삭제하는 데이터에 대한 인덱스를 더 이상 사용하지 않도록 조치 226 | 227 | > DML(Data Manipulation Language): 데이터 삽입, 수정, 삭제 228 | 229 | --- 230 | 231 | ### 인덱스를 생성/조회하기 위한 SQL문 작성 방법은? 232 | 233 | ```sql 234 | -- 생성 235 | CREATE INDEX [인덱스 명] ON [테이블 명]([컬럼 명]); 236 | -- ex) 237 | CREATE INDEX ind_email ON user(email); 238 | 239 | -- 조회 240 | $ SHOW INDEX FROM [테이블 명]; 241 | ``` 242 | 243 | > - 테이블 생성 시 PK를 설정해주면, 해당 컬럼이 자동으로 인덱스로 설정된다. 244 | 245 | ## 트랜잭션 246 | 247 | ### 트랜잭션이란? 248 | 249 | 데이터베이스의 상태를 변화시키기 위해 한번에 수행되어야 하는 일련의 연산들을 묶은 작업 단위 250 | 251 | - 하나의 트랜잭션은 commit되거나 rollback된다. 252 | 253 | --- 254 | 255 | ### 트랜잭션의 성질에는 어떤 것들이 있을까? 256 | 257 | Atomicity: 원자성 258 | 259 | - 트랜잭션의 연산은 데이터베이스에 모두 반영되거나, 모두 반영되지 않아야 한다. 260 | 261 | Consistency: 일관성 262 | 263 | - 트랜잭션이 실행을 성공적으로 완료한 후에도 시스템의 고정요소는 언제나 일관성이 있어야 한다. 264 | 265 | Isolation: 독립성 266 | 267 | - 어느 하나의 트랜잭션이 다른 트랜잭션의 연산에 끼어들 수 없다. 268 | 269 | Durability: 지속성 270 | 271 | - 성공적으로 완료된 트랜잭션의 결과는 영구적으로 반영되어야 한다. 272 | 273 | --- 274 | 275 | ### 트랜잭션의 연산에는 어떤 것들이 있을까? 276 | 277 | Commit 278 | 279 | - 트랜잭션 작업이 성공적으로 끝났음을 알리는 연산 280 | 281 | Rollback 282 | 283 | - 트랜잭션이 비정상적으로 종료되었을 때의 연산 284 | - 원자성을 위해 트랜잭션이 행한 모든 연산을 취소한다. 285 | 286 | > - Rollback 시에는 해당 트랜잭션을 재시작하거나 폐기한다. 287 | 288 | --- 289 | 290 | ### 트랜잭션의 상태를 설명해본다면? 291 | 292 | - 활동(Active): 트랜잭션이 실행 중인 상태 293 | - 실패(Failed): 트랜잭션 실행에 오류가 발생해 중단된 상태 294 | - 철회(Aborted): 트랜잭션이 비정상 종료되어 Rollback 연산을 수행한 상태 295 | - 부분 완료(Partially Committed): 트랜잭션의 마지막 연산까지 실행했고, Commit 연산이 실행되기 직전의 상태 296 | - 완료(Committed): 트랜잭션이 성공적으로 종료되어 Commit 연산을 실행한 후의 상태 297 | 298 | --- 299 | 300 | ### 트랜잭션의 고립 수준에 따라 발생 가능한 읽기 이상 현상(Read Phenomena)에 대해 설명해본다면? 301 | 302 | Dirty Read 303 | 304 | - 트랜잭션 T1에서 값을 update하고, 아직 commit하지 않았는데 다른 트랜잭션 T2가 해당 값을 읽을 수 있도록 허용하는 경우 발생. 305 | - 트랜잭션 T1이 rollback했을 경우, T2가 잘못된 값을 읽게 되는 현상이 발생한다. 306 | - 해결방안: T1이 특정 값에 접근하는 동안 lock을 걸어서, 다른 트랜잭션이 접근하지 못하게 한다. 307 | 308 | Non Repeatable Read 309 | 310 | - 트랜잭션 T1이 같은 쿼리를 두 번 실행했는데, 그 결과값이 다른 경우. 즉, T1이 select를 두 번 하는 사이 다른 트랜잭션이 update나 delete를 한 경우 발생. 311 | - 해결방안: 트랜잭션 T1이 작업을 완료할 때까지 다른 트랜잭션의 update/delete 제한 312 | 313 | Phantom Read 314 | 315 | - 트랜잭션 T1이 같은 쿼리를 두 번 실행하는 과정에서, 첫 번째 쿼리 실행 시 없던 레코드가 두 번째 실행에 튀어나오는 경우 발생. 316 | - 해결방안: 트랜잭션 T1이 작업을 완료할 때까지 다른 트랜잭션의 update/delete 뿐만 아니라 새로운 레코드 삽입(insert)도 제한. 317 | 318 | --- 319 | 320 | ### 트랜잭션의 고립 수준 유형에 대해 설명해본다면? 321 | 322 | 1. Read Uncommitted 323 | 324 | - 트랜잭션 T1이 아직 commit하지 않은 데이터를 다른 트랜잭션 T2가 Read하는 것을 허용한다. 325 | - 읽기 이상 현상: Dirty Read 발생 326 | 327 | 2. Read Committed 328 | 329 | - 트랜잭션 T1이 commit한 데이터만 다른 트랜잭션 T2가 Read하는 것을허용한다. 330 | - 읽기 이상 현상: Dirty Read 방지 / Non Repeatable Read, Phantom Read 발생 331 | 332 | > 대부분의 DBMS가 채택하는 고립 수준이다. 333 | 334 | 3. Repeatable Read 335 | 336 | - 선행 트랜잭션 T1이 읽은 데이터는 T1이 종료될 때까지 다른 트랜잭션이 수정/삭제할 수 없음. 337 | - 삽입은 허용. 338 | - 읽기 이상 현상: Dirty Read, Non-Repeatable Read 방지 / Phantom Read 발생 339 | 340 | 4. Serializable 341 | 342 | - 선행 트랜잭션 T1이 읽은 데이터는 T1이 종료될 때까지 다른 트랜잭션이 수정/삭제/삽입할 수 없음. 343 | - 읽기 이상 현상: Dirty Read, Non-Repeatable Read, Phantom Read 방지 344 | 345 | > 완벽하지만, 현실적으로는 불가능에 가까운 방법이다. 346 | 347 | --- 348 | 349 | ### 트랜잭션의 고립 수준과 동시성과의 상관 관계는? 350 | 351 | 고립 수준과 동시성은 음의 상관 관계를 가진다. 352 | 353 | - 고립 수준이 높으면(ex: Serializable) 모든 읽기 이상 현상을 방지할 수 있지만, 대신 트랜잭션들이 병렬적으로 실행되지 못하고 하나씩 순차적으로 실행되기 때문에 대기 시간이 늘어나고, 성능이 떨어진다. 354 | - 고립 수준이 낮으면(ex: Read Uncommitted) 트랜잭션을 동시에 수행 가능하기 때문에 동시성과 성능이 높아진다. 355 | 356 | ## 정규화 357 | 358 | ### 정규화란? 359 | 360 | 테이블 간 데이터의 중복을 최소화하기 위해 데이터를 구조화하는 프로세스 361 | 362 | - 데이터의 중복을 최소화함으로써 무결성(Integrity)을 유지할 수 있다. 363 | 364 | > - 무결성: 데이터베이스에 저장된 데이터 값과 그것이 표현하는 현실 세계의 실제값이 일치하는 정확성. 즉 데이터베이스의 값이 항상 정확하게 유지되고 있는 것을 말한다. 365 | 366 | --- 367 | 368 | ### 제1 정규화에 대해 설명? 369 | 370 | 테이블의 컬럼이 원자값을 갖도록 테이블을 구조화하는 것 371 | 372 | - 해결: 다른 컬럼은 같은 값을 가지고, 문제가 되었던 컬럼이 다른 값을 가지는 row를 추가한다. 373 | 374 | > - 해결책은 논리적 구성을 위해 데이터의 중복성을 증가시키는 것으로 볼 수 있다. 375 | 376 | (예시 - 정규화 전) 377 | 378 | ![Database%2079d9527d1d534251afb6af40532b918b/Untitled.png](Database%2079d9527d1d534251afb6af40532b918b/1-before.png) 379 | 380 | (예시 - 정규화 후) 381 | 382 | ![Database%2079d9527d1d534251afb6af40532b918b/Untitled.png](Database%2079d9527d1d534251afb6af40532b918b/1-after.png) 383 | 384 | --- 385 | 386 | ### 제2 정규화에 대해 설명? 387 | 388 | 제 1정규화를 진행한 테이블에 대해, 389 | 완전 함수 종속을 만족하도록 테이블을 구조화하는 것 390 | 391 | - 완전 함수 종속: 기본키의 부분 집합이 결정자가 되어서는 안된다는 것, 또는, 기본키 중 특정 컬럼에만 종속된 컬럼(부분 함수 종속)이 없어야 한다는 것이다. 392 | - 해결: 완전 함수 종속을 만족하도록 테이블을 분리한다. 393 | 394 | (예시 - 정규화 전) 395 | 396 | ![Database%2079d9527d1d534251afb6af40532b918b/Untitled.png](Database%2079d9527d1d534251afb6af40532b918b/2-before.png) 397 | 398 | > 기본키는 (Student, Subject)이다. 그런데 Age의 경우 Student에만 종속되어 있다. 즉, Student를 알면 Age를 알 수 있다. 399 | 400 | (예시 - 정규화 후) 401 | 402 | ![Database%2079d9527d1d534251afb6af40532b918b/Untitled.png](Database%2079d9527d1d534251afb6af40532b918b/2-after.png) 403 | 404 | --- 405 | 406 | ### 제3 정규화에 대해 설명? 407 | 408 | 제2 정규화를 진행한 테이블에 대해, 409 | 이행적 종속이 없도록 테이블을 구조화하는 것 410 | 411 | - 이행적 종속: A→B, B→C일 때 A→C가 성립되는 것. 즉, 기본키 이외의 다른 컬럼이 그 외 컬럼을 결정하는 것. 412 | - 해결: 이행적 종속이 없도록 테이블을 분리한다. 413 | 414 | (예시 - 정규화 전) 415 | 416 | ![Database%2079d9527d1d534251afb6af40532b918b/Untitled.png](Database%2079d9527d1d534251afb6af40532b918b/3-before.png) 417 | 418 | > Student_id가 기본키이다. 그런데 Zip을 알면 Street, City, State를 알 수 있다. 419 | 420 | (예시 - 정규화 후) 421 | 422 | ![Database%2079d9527d1d534251afb6af40532b918b/Untitled.png](Database%2079d9527d1d534251afb6af40532b918b/3-after.png) 423 | 424 | --- 425 | 426 | ### BCNF에 대해 설명? 427 | 428 | 제3 정규화를 진행한 테이블에 대해, 429 | 모든 결정자가 후보키가 되도록 테이블을 구조화하는 것 430 | 431 | - 일반 컬럼이 후보키를 결정하는 경우, BCNF를 만족하지 못하게 된다. 432 | 433 | (예시 - 정규화 전) 434 | 435 | ![Database%2079d9527d1d534251afb6af40532b918b/Untitled.png](Database%2079d9527d1d534251afb6af40532b918b/bcnf-before.png) 436 | 437 | > 후보키는 (학생, 과목)이다. 그런데 교수가 결정자이다. (교수는 한 과목만 강의할 수 있다는 가정) 즉, 교수가 정해지면 과목을 알 수 있다. 그런데 교수는 후보키가 아니다. 일반 컬럼이 후보키를 결정하고 있다. 438 | 439 | (예시 - 정규화 후) 440 | ![Database%2079d9527d1d534251afb6af40532b918b/Untitled.png](Database%2079d9527d1d534251afb6af40532b918b/bcnf-after.png) 441 | 442 | --- 443 | 444 | ### 데이터베이스의 이상 현상(Anomaly)에는 어떤 것들이 있을까? 445 | 446 | 삽입 이상(Insertion Anomaly) 447 | 448 | - 자료를 삽입할 때, 의도하지 않은 자료까지 삽입해야만 테이블에 추가가 가능한 현상 449 | 450 | 갱신 이상(Update Anomaly) 451 | 452 | - 중복된 데이터 중 일부만 수정되어 데이터 모순이 발생하는 현상 453 | 454 | 삭제 이상(Deletion Anomaly) 455 | 456 | - 어떤 정보를 삭제하면, 유용한 다른 정보까지 삭제되어 버리는 현상 457 | 458 | > - 이상 현상은 데이터베이스의 테이블 설계가 잘못되어 데이터의 중복이 생길 때 발생할 수 있다. 459 | 460 | --- 461 | 462 | ### 정규화의 단점은? 463 | 464 | 정규화를 진행하는 과정에서 테이블이 여러 개로 분리된다. 테이블이 많아지면, 데이터를 추출하는 과정에서 `JOIN` 연산이 많이 사용되고, 이는 질의에 대한 응답 시간이 느려지는 요인이 된다. 465 | 466 | --- 467 | 468 | ### 반정규화(De-normalization)란? 469 | 470 | 정규화로 인해 발생하는 개발이나 운영 상 이슈를 방지/해결하기 위해 분리된 테이블을 다시 통합하는 것. 471 | 472 | 반정규화가 고려될 수 있는 상황 473 | 474 | - 테이블에 `JOIN`을 지나치게 많이 사용하게 되어 기술적으로 구현이 어렵거나 성능상의 이슈가 있을 때 475 | - 테이블에 대량의 데이터가 있고, 대량의 범위를 자주 처리하는 경우 476 | 477 | > - 일반적으로 데이터의 무결성보다 조회 속도가 더 중요하다고 판단될 때 수행한다. 478 | 479 | ## 키 480 | 481 | ### 키란? 482 | 483 | 무언가를 식별할 수 있는 고유한 식별자 484 | 485 | --- 486 | 487 | ### 슈퍼키란? 488 | 489 | 테이블에서 각 행을 유일하게 식별할 수 있는 하나 이상의 속성들의 집합 490 | 491 | > - 즉, 유일성을 만족하면 슈퍼키이다. 492 | > (유일성: 하나의 키로 특정 행을 찾아낼 수 있는 고유한 속성) 493 | 494 | --- 495 | 496 | ### 후보키란? 497 | 498 | 테이블에서 각 행을 유일하게 식별할 수 있는 최소한의 속성들의 집합 499 | 500 | > - 후보키는 기본키가 될 수 있는 후보들이다. 501 | > - 유일성과 최소성을 동시에 만족해야 한다. 502 | 503 | --- 504 | 505 | ### 기본키란? 506 | 507 | 후보키들 중에서 하나를 선택한 키 508 | 509 | --- 510 | 511 | ### 대체키란? 512 | 513 | 후보키가 두개 이상일 경우, 기본키 이외의 나머지 후보키 514 | 515 | --- 516 | 517 | ### 외래키란? 518 | 519 | 테이블의 속성 중 다른 테이블의 행을 식별할 수 있는 키 520 | 521 | ## SQL Query 522 | 523 | ### SQL이란? 524 | 525 | RDBMS를 조작할 때 사용하는 언어 526 | 527 | (예시) 528 | 529 | ```sql 530 | /* SELECT */ 531 | SELECT id, password FROM users; 532 | 533 | SELECT * FROM users WHERE id=2 OR id=3; -- 또는 AND 534 | SELECT * FROM users WHERE NOT(id=2); 535 | 536 | SELECT * FROM users WHERE nick LIKE '%hee%'; -- 전방일치('%hee'), 후방일치('hee%') 537 | 538 | /* INSERT */ 539 | INSERT INTO users VALUES(2, 'hee', 'gml3413@@', '2021-07-02'); 540 | INSERT INTO users (id, name, password, createdAt) VALUES(2, 'hee', 'gml3413@@', '2021-07-02'); 541 | 542 | /* UPDATE */ 543 | UPDATE users SET name=NULL; -- WHERE 절이 없으면 모든 행이 수정됨. 544 | UPDATE users SET name='lee', createdAt='2021-07-19' WHERE id=2; 545 | 546 | /* DELETE */ 547 | DELETE FROM users; -- 모든 행 삭제 548 | DELETE FROM users WHERE id=2; 549 | ``` 550 | 551 | --- 552 | 553 | ### JOIN이란? 554 | 555 | ![Database%2079d9527d1d534251afb6af40532b918b/Untitled%208.png](Database%2079d9527d1d534251afb6af40532b918b/Untitled%208.png) 556 | 557 | 두개 이상의 테이블을 연결해서 데이터를 검색하는 방법 558 | 559 | > - 테이블을 연결하려면 Primary key나 Foreign key 등 적어도 하나의 컬럼은 서로 공유되고 있어야 한다. 560 | 561 | --- 562 | 563 | ### INNER JOIN이란? 564 | 565 | 집합으로 치면 교집합에 해당하는 연산으로, 566 | 기준 테이블과 조인한 테이블 둘 다 가지고 있는 값만 검색된다. 567 | 568 | ```sql 569 | > SELECT girl_group.id, girl_group.name, song.title 570 | FROM girl_group 571 | JOIN song -- SQL에서 INNER JOIN은 간략히 JOIN으로 사용할 수 있다. 572 | WHERE girl_group.hit_song_id = song.id; 573 | 574 | -- 만일 girl_group 중 hit_song_id가 NULL인 행이 있을 경우, 결과에 포함되지 않는다. 575 | ``` 576 | 577 | --- 578 | 579 | ### OUTER JOIN이란? 580 | 581 | 조인하는 여러 테이블이 있을 때, 한쪽에는 데이터가 있고 한쪽에는 없을 때, 데이터가 있는 쪽 테이블의 내용을 모두 출력하는 것. 582 | 583 | 즉, 조건에 맞지 않아도 (한쪽 테이블의) 해당하는 행을 출력하는 것. 584 | 585 | --- 586 | 587 | ### LEFT (OUTER) JOIN / RIGHT (OUTER) JOIN이란? 588 | 589 | 왼쪽(혹은 오른쪽) 테이블의 행 중 조건절에 일치하지 않는 값을 가지고 있는 행도 가져온다. 590 | 591 | ```sql 592 | > SELECT girl_group.id, girl_group.name, song.title 593 | FROM girl_group 594 | LEFT JOIN song 595 | WHERE girl_group.hit_song_id = song.id; 596 | 597 | -- girl_group 중 hit_song_id가 NULL인 행도 결과에 포함된다. 598 | ``` 599 | 600 | > - LEFT JOIN과 LEFT OUTER JOIN는 같은 용어이다. 601 | 602 | --- 603 | 604 | ### CROSS JOIN(카티전 조인)이란? 605 | 606 | 집합으로 치면 곱의 개념이다. 607 | 608 | (A = { a, b, c, d }, B = { 1, 2, 3 } 일 때, 609 | A CROSS JOIN B 는 (a,1), (a, 2), (a,3), (b,1), (b,2), (b,3), (c, 1), (c,2), (c,3), (d, 1), (d, 2), (d,3) 이다) 610 | 611 | ```sql 612 | > SELECT girl_group.id, girl_group.name, song.title 613 | FROM girl_group 614 | CROSS JOIN song; 615 | 616 | -- 위 CROSS JOIN은 다음과 같이 나타낼 수도 있다. 617 | > SELECT girl_group.id, girl_group.name, song.title 618 | FROM girl_group, song; 619 | ``` 620 | 621 | --- 622 | 623 | ### JOIN에서 ON과 WHERE의 차이점은? 624 | 625 | JOIN하는 범위가 다르다. 626 | 627 | ```sql 628 | -- 1번 쿼리 629 | > SELECT * 630 | FROM A LEFT JOIN B 631 | ON (A.id = B.id) 632 | WHERE B.foo = 3; 633 | 634 | -- 2번 쿼리 635 | > SELECT * 636 | FROM A LEFT JOIN B 637 | ON (A.id = B.id AND B.foo = 3); 638 | ``` 639 | 640 | 1번 쿼리는 641 | 642 | - A와 B 테이블을 LEFT JOIN한 후, WHERE절 조건에 해당하는 행만 추출한다. 643 | - 즉, 결과값에는 `B.foo = 3`인 데이터만 존재한다. 644 | 645 | 2번 쿼리는 646 | 647 | - ON 절로 LEFT JOIN한 행이 추출된다. 648 | - 즉, 결과값에는 `B.foo = 3`이 아닌 데이터도 존재한다. 649 | 650 | > - JOIN에서의 ON과 WHERE의 차이점을 이용해서 차집합을 구할 수 있다. 651 | 652 | --- 653 | 654 | ### (OUTER) JOIN에서 (ON과 WHERE를 이용해서) 차집합을 구하는 방법은? 655 | 656 | ```sql 657 | > SELECT * 658 | FROM A LEFT JOIN B 659 | ON (A.id = B.id) 660 | WHERE B.id IS NULL; 661 | ``` 662 | 663 | ## DBMS 664 | 665 | ### DBMS란? 666 | 667 | 사용자와 데이터베이스 사이에서, 668 | 669 | - 사용자의 요구에 따라 정보를 생성해주고 670 | - 데이터베이스를 관리해주는 671 | 672 | 소프트웨어 673 | 674 | --- 675 | 676 | ### DBMS를 사용했을 때의 장점은? 677 | 678 | - 저장된 데이터를 여러 애플리케이션에서 공동으로 이용할 수 있다. 679 | - 보안을 유지할 수 있다. 680 | 681 | --- 682 | 683 | ### RDBMS란? 684 | 685 | 행과 열을 가지는 표 형식의 2차원 데이터를 저장하는 DB 686 | -------------------------------------------------------------------------------- /etc/README.md: -------------------------------------------------------------------------------- 1 | # Etc 2 | 3 | ## Table of Contents 4 | 5 | 객체 지향 프로그래밍(OOP) 6 | 7 | - 객체 지향 프로그래밍이란? 8 | - 객체 지향 프로그래밍의 장단점은? 9 | - 절차 지향 프로그래밍이란? 10 | - 클래스와 인스턴스(객체)란? 11 | - 오버로딩(Overloading)과 오버라이딩(Overriding)의 차이점은? 12 | - 객체 지향 5대 원칙에 대해 설명해본다면? 13 | 14 | ## 객체 지향 프로그래밍(OOP) 15 | 16 | ### 객체 지향 프로그래밍이란? 17 | 18 | 프로그램을 (명령어의 목록으로 보는 시각에서 벗어나) 여러 개의 독립된 단위인 객체의 모임으로 파악하고자 하는 것. 각각의 객체는 메시지를 주고받고, 데이터를 처리할 수 있다. 19 | 20 | 특징 21 | 22 | 1. 추상화 23 | 24 | - 객체들의 공통적인 특징을 도출하는 것. 25 | > - 객체 지향 프로그래밍에서 추상화는 클래스를 정의하는 것을 말한다. 즉, 공통의 속성이나 기능을 묶고 이름을 붙여 변수와 메서드로 정의하는 것이다. 26 | 27 | 1. 캡슐화 28 | 29 | - 데이터와 기능을 묶어 외부에 드러나지 않도록 정보를 은닉하는 것. 30 | > 캡슐화의 목적 31 | > 32 | > - 코드의 재활용: 관련된 특성과 기능이 한 곳에 모여 객체의 재활용이 원활해진다. 33 | > - 정보 은닉: 외부에 노출되어서는 안되는 정보를 접근 제어자를 통해 은닉함으로써 책임이 있는 객체만 수정할 수 있고, 예측이 원활해진다. 34 | 35 | 1. 상속 36 | 37 | - 하나의 클래스가 가진 데이터와 함수를 다른 클래스가 그대로 물려받는 것. 38 | 39 | 1. 다형성 40 | 41 | - 동일한 이름의 함수가, 연결된 객체에 따라 다르게 해석되는 것. 42 | - 오버라이딩(Overriding)과 오버로딩(Overloading)이 다형성을 보장한다. 43 | 44 | --- 45 | 46 | ### 객체 지향 프로그래밍의 장단점은? 47 | 48 | 장점 49 | 50 | - 생산성: 상속, 다형성 등을 통해 코드를 재사용하기 쉽다. (이미 만들어진 클래스를 상속받거나, 객체를 가져다 재사용하거나, 부분만 수정함으로써 소프트웨어 작성 부담을 대폭 줄일 수 있다.) 51 | 52 | - 모델링 용이: 실세계를 모델링할 때, 하나의 절차로 모델링하는 것보다 객체 간 상호작용으로 모델링하는 것이 훨씬 쉽다. 53 | 54 | - 보안성: 캡슐화를 통해 구현되는 부분이 외부에 드러나지 않도록 은닉할 수 있다. 55 | 56 | 단점 57 | 58 | - 느린 실행 속도와 추가 메모리 공간: 캡슐화와 격리 구조로 인해 추가적인 포인터 크기와 메모리 연산 비용으로 인해 속도가 느리다. 59 | 60 | --- 61 | 62 | ### 절차 지향 프로그래밍이란? 63 | 64 | 어떤 기능을 어떤 순서로 처리하는가에 초점을 맞춰 개체를 순차적으로 처리하는 것. 65 | 66 | 장점 67 | 68 | - 실행 속도가 빠르다: 컴퓨터의 처리 구조와 비슷하며, 추가적인 메모리가 필요하지 않아 연산이 빠르다. 69 | 70 | 단점 71 | 72 | - 유지보수가 어렵다: 모든 구성 요소가 유기적으로 연결되어 있기 때문에, 하나가 고장났을 때 시스템 전체가 고장난다. 또한, 문제를 해결하기 위해 일부분이 아닌 시스템 전체를 수리해야 한다. 73 | 74 | > 객체 지향과 절차 지향, 각각 어느 상황에서 사용하는 것이 좋을까? 75 | > 76 | > - 대형 프로그램의 경우, 많은 기능을 가지고 있기 때문에 객체 지향이 유리하다. 많은 역할을 객체로 묶을 수 있고, 재사용이 용이하기 때문이다. 77 | > - 소형 프로그램의 경우, 절차 지향이 유리하다. 작은 기능을 객체로 나눌 경우 오히려 복잡해질 수 있기 때문이다. 78 | 79 | --- 80 | 81 | ### 클래스와 인스턴스(객체)란? 82 | 83 | 클래스 84 | 85 | - 집단의 속성과 행위를 추상화를 거쳐 변수와 메서드로 정의한 것. 86 | - 객체를 만들기 위한 메타 정보 87 | 88 | 인스턴스(객체) 89 | 90 | - 클래스에서 정의한 것을 토대로 실제 메모리에 할당된 것. 91 | 92 | --- 93 | 94 | ### 오버로딩(Overloading)과 오버라이딩(Overriding)의 차이점은? 95 | 96 | 오버로딩: 같은 이름의 메서드를 여러 개 정의하고, 매개변수의 타입과 개수를 다르게 해 다양한 유형의 호출에 응답할 수 있도록 하는 것. 97 | 98 | 오버라이딩: 메서드의 이름, 매개변수, 반환형이 모두 같은 경우 상속받은 메서드를 덮어쓰는 것. 99 | 100 | --- 101 | 102 | ### 객체 지향 5대 원칙에 대해 설명해본다면? 103 | 104 | 1. 단일 책임 원칙(SRP, Single Responsibility Principle) 105 | 106 | - 클래스는 단 한 개의 책임을 가져야 한다. 107 | > 단 한 개의 '기능'을 가져야 한다는 의미로 해석할 수 있다. 이 원칙을 따르면 응집도는 높고, 결합도는 낮은 프로그램을 설계할 수 있다. 책임이 많아지면 클래스 내부 함수끼리의 결합도가 높아질 가능성이 많아진다. 이는 유지보수 비용을 높인다. 108 | > 109 | > - 결합도(coupling): 어떤 기능이 다른 클래스나 모듈에 얼마나 의존적인지를 나타낸다. 110 | > - 응집도: 객체 안의 모듈 간 요소가 얼마나 밀접한 관련이 있는 것들로 구성되어 있는지를 나타낸다. 111 | 112 | 2. 개방-폐쇄 원칙(OCP, Open-Closed Principle) 113 | 114 | - 확장에는 열려 있어야 하고, 변경에는 닫혀 있어야 한다. 115 | 116 | > 기존의 코드를 변경하지 않고(Closed) 기능을 수정하거나 추가할 수 있어야 한다(Open)는 말이다. 이 원칙을 따르면 변경에 유연하므로 유지보수 비용을 줄여주며, 코드의 가독성이 좋아진다. 117 | 118 | ```java 119 | // OCP를 위배하는 코드 120 | class SoundPlayer { 121 | void play() { 122 | System.out.println("play Wav"); // wav 재생 123 | } 124 | } 125 | 126 | public class Client { 127 | public static void main(String[] args) { 128 | SoundPlayer sp = new SoundPlayer(); 129 | sp.play(); 130 | } 131 | } 132 | // - SoundPlayer가 wav 이외의 다른 포맷을 재생할 수 있도록 요구사항이 변경되면 SoundPlayer의 play() 메소드를 수정해야만 한다. 133 | 134 | // OCP를 만족시키는 코드 135 | // 여러가지 방법이 있지만, 그 중 interface를 활용하는 예시이다. 136 | interface playAlgorithm { 137 | public void play(); 138 | } 139 | // play()를 interface로 분리한다. 140 | 141 | class Wav implements playAlgorithm { 142 | @Override 143 | public void play() { 144 | System.out.println("Play Wav"); 145 | } 146 | } 147 | 148 | class Mp3 implements playAlgorithm { 149 | @Override 150 | public void play() { 151 | System.out.println("Play Mp3"); 152 | } 153 | } 154 | 155 | class SoundPlayer { 156 | private playAlgorithm file; 157 | 158 | public void setFile(playAlgorithm file) { 159 | this.file = file; 160 | } 161 | 162 | public void play() { 163 | file.play(); 164 | } 165 | } 166 | 167 | public class Client { 168 | public static void main(String[] args) { 169 | SoundPlayer sp = new SoundPlayer(); 170 | // (둘 중 원하는 파일 선택) 171 | sp.setFile(new Wav()); 172 | sp.setFile(new Mp3()); 173 | sp.play(); 174 | } 175 | } 176 | // - 이와 같은 설계를 Strategy Pattern(전략 패턴)이라고 한다. 177 | // - SoundPlayer 클래스의 변경 없이 재생되는 파일을 변경할 수 있다. 178 | 179 | ``` 180 | 181 | 3. 리스코프 치환 법칙(LSP, Liskov Substitution Principle) 182 | 183 | - 부모 클래스의 인스턴스 대신 자식 클래스의 인스턴스를 사용해도 문제가 없어야 한다. 184 | - 자식 클래스는 부모 클래스에서 가능한 행위를 수행할 수 있어야 한다. 185 | 186 | > 리스코프 치환 법칙은 일반화 관계에 대한 원칙이다. 상속 관계에서는 일반화 관계(IS-A)가 성립해야 한다. 187 | 188 | ```text 189 | 예시) 도형 클래스와 사각형 클래스, 원 클래스가 있다. 사각형 클래스는 도형 클래스의 상속을 받는다. 190 | 191 | (1) 도형은 둘레를 가지고 있다. 192 | (2) 도형은 넓이를 가지고 있다. 193 | (3) 도형은 각을 가지고 있다. 194 | 195 | 위 문장의 '도형' 단어를 '사각형'으로 바꾸면 이상한 부분이 없지만, '원'으로 바꾸면 (3)번 문장이 어색해진다. 이때 도형 클래스는 LSP를 만족하지 않는 설계라고 할 수 있다. 196 | 197 | ``` 198 | 199 | 4. 인터페이스 분리 원칙(ISP, Interface Segregation Principle) 200 | 201 | - 한 클래스는 자신이 사용하지 않는 인터페이스를 구현하지 말아야 한다. 202 | > 즉 자신이 사용하지 않는 기능(인터페이스)에 영향을 받지 않아야 한다. 예를 들어 스마트폰으로 전화, 웹 서핑, 카메라 등의 기능을 사용할 수 있는데, 그 중 특정 기능을 사용할 때는 다른 기능을 사용하지 않을 것이다. 따라서 각각의 기능을 독립된 인터페이스로 구현해 서로에게 영향을 주고받지 않도록 설계해야 한다. 이 원칙은 시스템 내부 의존성을 약화시켜 리팩토링을 용이하게 한다. 203 | 204 | 5. 의존 역전 원칙(DIP, Dependency Inversion Principle) 205 | 206 | - 의존 관계를 맺을 때, 변화하기 쉬운 것보다 변화하기 어려운 것에 의존해야 한다는 원칙이다. 207 | > 변화하기 쉬운 것이란 구체적인 것을 말하고, 변화하기 어려운 것이란 추상적인 것을 말한다. 객체 지향의 관점에서 변화하기 쉬운 것은 구체화된 클래스를 말하고, 변화하기 어려운 것이란 추상 클래스나 인터페이스를 말한다. 따라서 DIP를 만족하기 위해서는 의존 관계를 맺을 때 구체화된 클래스보다는 인터페이스나 추상 클래스와 관계를 맺어야 한다. 208 | -------------------------------------------------------------------------------- /javascript/JavaScript f07b25d7438e4d0ca94bbc0c3231bc62/Untitled 1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heech1013/study-note/9c5d4ee9887aed616e24701a9a43b1cd53dcf6a4/javascript/JavaScript f07b25d7438e4d0ca94bbc0c3231bc62/Untitled 1.png -------------------------------------------------------------------------------- /javascript/JavaScript f07b25d7438e4d0ca94bbc0c3231bc62/Untitled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heech1013/study-note/9c5d4ee9887aed616e24701a9a43b1cd53dcf6a4/javascript/JavaScript f07b25d7438e4d0ca94bbc0c3231bc62/Untitled.png -------------------------------------------------------------------------------- /javascript/README.md: -------------------------------------------------------------------------------- 1 | # JavaScript 2 | 3 | ## Table of Contents 4 | 5 | 언어의 특징 6 | 7 | - JS의 언어적인 특징? 8 | - 인터프리터 언어와 컴파일 언어의 차이점? 9 | - 인터프리터 언어와 컴파일 언어의 장단점? 10 | - 프로토타입 기반 언어란? 11 | 12 | 엔진 & 런타임 13 | 14 | - JavaScript 엔진의 구성은? 15 | - JavaScript 런타임이란? 16 | 17 | 객체(Object) 18 | 19 | - Object(객체)란? 20 | - 객체를 생성하는 방법은? 21 | 22 | 프로토타입(Prototype) 23 | 24 | - 클래스 기반의 객체지향 프로그래밍 언어와, 프로토타입 기반의 객체지향 프로그래밍 언어(JavaScript)의 차이점은? 25 | - prototype이란? 26 | - 프로토타입을 사용하는 이유는? (활용되는 예시는?) 27 | - (참고) `[[Prototype]]` & `__proto__` & `prototype` 28 | - 프로토타입이 결정되는 시기는? 29 | - prototype chain이란? 30 | - 프로토타입 객체를 확장하는 방법은? 31 | - 값을 할당할 때와, 참조할 때 프로토타입 체인이 동작하는 여부? 32 | - 프로토타입 객체를 동적으로 변경하는 방법은? 33 | - 프로토타입 객체를 동적으로 변경하기 이전에 생성된 객체와, 이후 생성된 객체의 차이점은? 34 | 35 | Class `보충` 36 | 37 | - (참고) Class의 constructor 38 | 39 | Closure 40 | 41 | - Closure란? 42 | - Closure의 동작 원리를 (실행 컨텍스트와 관련하여) 설명? 43 | - Closure의 활용법? 44 | - Closure의 상태 유지가 전역 변수에 비해 갖는 이점? 45 | - 렉시컬 스코핑(lexical scoping)이란? 46 | - Closure의 단점? 47 | - Closure가 참고하고 있는 메모리를 해제해주려면 어떻게 할까? 48 | - 클로저로 인해 자주 발생하는 실수에는 어떤 것들이 있을까? `보충` 49 | 50 | this 51 | 52 | - this란? 53 | - this의 값이 결정되는 방식을 설명? 54 | - 함수가 '일반 함수로서' 호출될 때 this가 바인딩되는 객체는? 55 | - 전역객체란? 56 | - Browser-side와 server-side에서의 전역객체가 어떻게 다른가? 57 | - 그러면 함수의 내부 함수나 메소드의 내부 함수, 콜백 함수가 '일반 함수로서' 호출될 때의 this는 어떻게 될까? 58 | - 함수가 '일반 함수로서' 호출되었을 때 this가 전역 객체를 참조하는 것을 회피하는 방법이 있을까? 59 | - 함수가 '메소드로서' 호출될 때 this가 바인딩되는 객체는? 60 | - 그러면 함수가 '프로토타입 객체의 메소드로서' 호출될 때는? 61 | - 함수가 '생성자 함수로서' 호출될 때 this가 바인딩되는 객체는? 62 | - 객체 리터럴 방식과 생성자 함수 방식의 차이는? 63 | - 명시적으로 this를 바인딩하는 방법? 64 | - this를 사용할 때 자주 발생하는 실수에는 어떤 것들이 있을까? 65 | - apply, call, bind 메소드의 사용법에 대해 설명? 66 | - 유사 배열(arguments)이 배열의 메소드를 사용할 수 있도록(조작할 때) apply와 call을 사용하는 방법에 대해 아는지? 67 | - 암시적 바인딩과 명시적 바인딩의 우선 순위는? 68 | - arrow function에서의 this는 어떻게 동작하나? 69 | - arrow function을 사용하면 안되는 경우는? 70 | 71 | 비동기 처리 72 | 73 | - JavaScript에서의 비동기 프로그래밍이란? 74 | - JavaScript가 코드를 비동기적으로 실행하는 이유는 뭘까? 75 | - JavaScript에서 (시간이 오래 걸리는) 동기적인 코드가 blocking을 일으키는 이유는 뭘까? 76 | - 프론트엔드에서 비동기 처리가 중요한 이유는? 77 | 78 | 콜백 패턴 & Promise 79 | 80 | - Promise란? 81 | - 동기식 작업과 비동기식 작업이란? 차이점은? 82 | - Promise는 어떤 문제점을 해결하고자 등장했나? 83 | - 비동기 처리에 콜백 패턴을 사용해야 하는 이유는? 84 | - 콜백 방식의 비동기 처리가 에러 처리에 곤란한 이유는? 85 | - Promise를 생성하는 방법은? 86 | - Promise의 상태(state)는 어떤 것들이 있나? 87 | - Promise의 후속 처리 메소드에 대해 설명? 88 | - Promise의 에러 처리는 then과 catch 중 어떤 것으로 하는 것이 더 좋을까? 89 | - Promise의 정적 메소드에 대해 설명? 90 | - Promise.resolve와 Promise.reject에 대해 설명? 91 | - Promise.all과 Promise.race에 대해 설명? 92 | 93 | 이벤트 루프 94 | 95 | - 이벤트 루프란? 96 | - 이벤트 루프가 필요한 이유는? 97 | - Run-to-Completion이란? 98 | - 자바스크립트가 Run-to-Completion으로 동작하는 이유(원리)는? 99 | - 태스크 큐가 동작하는 과정은? 100 | - 태스크 큐와 마이크로 태스크 큐가 동작하는 과정은? 101 | - 이벤트 루프(혹은 태스크 큐의 우선 순위)로 인해 사용자 경험에 해가 되는 경우가 있을까? 102 | - 고비용 연산으로 인한 블로킹에 대응하는 방법은? 103 | - (참고) 활용 예시: progress bar 104 | 105 | 실행 컨텍스트 106 | 107 | - 실행 컨텍스트란? 108 | - 실행 가능한 코드란? 109 | - 실행에 필요한 환경이란? 110 | - 코드가 실행되고, 함수가 실행되고 끝나는 과정을 실행 컨텍스트 스택으로 설명해본다면? 111 | - 실행 컨텍스트의 (물리적인) 구조는? 112 | - Variable Object란? 113 | - 전역 컨텍스트와 함수 컨텍스트에서 VO가 가리키는 객체(내용)의 차이는? 114 | - 스코프 체인이란? 115 | - 특정 EC의 스코프 체인에는 어떤 스코프가 담겨있나? 116 | - 변수를 검색하는 과정을 스코프 체인과 연관하여 설명해본다면? 117 | - 실행 컨텍스트에 값이 채워지는 순서는? (실행 컨텍스트가 생성되는 순서는?) 118 | - 변수 객체화가 진행되는 과정은? 119 | - 클로저를 실행 컨택스트에 기반해 설명해본다면? 120 | - 함수 호이스팅이란? 121 | - 변수 호이스팅이란? 122 | 123 | 호이스팅 124 | 125 | - 호이스팅이란? 126 | - 호이스팅의 대상은? 127 | - 함수 선언문과 함수 표현식의 차이는? 128 | - 함수 선언문에 비해 함수 표현식이 가지는 장점은? 129 | - 호이스팅에서의 우선순위에 대해 설명해본다면? 130 | - 호이스팅은 지향해야 할까, 지양해야 할까? 131 | - 호이스팅을 방지하기 위한 방법은? 132 | - 호이스팅을 지양해야 함에도 불구하고, var와 호이스팅을 이해해야 하는 이유는? 133 | 134 | EcmaScript 135 | 136 | - EcmaScript란? 137 | - ECMAScript와 JavaScript의 관계는? 차이점은? 138 | - ES6에서 추가된 문법에 대해 아는 것이 있는지? 139 | 140 | 기타 141 | 142 | - 자바스크립트 배열도 객체일까? (배열의 내부 구조는?) 143 | - use strict란? 144 | 145 | --- 146 | 147 |
148 | 149 | ## 언어의 특징 150 | 151 | ### JS의 언어적인 특징? 152 | 153 | - 인터프리터 언어 154 | - 프로토타입 기반 언어 155 | 156 | --- 157 | 158 | ### 인터프리터 언어와 컴파일 언어의 차이점? 159 | 160 | 인터프리터 언어: 인터프리터에 의해 소스코드를 한 줄 씩 읽어 바로 실행됨 161 | 162 | 컴파일 언어: 컴파일러에 의해 기계어로 모두 번역 후 실행 163 | 164 | > - 인터프리터 언어는 번역과 실행이 동시에 이루어져 별도의 실행 파일이 존재하지 않는다. 165 | > 컴파일 언어는 컴파일러에 의해 실행 가능한 파일(: 오브젝트 파일, 바이너리 파일)이 생성된다. 166 | 167 | --- 168 | 169 | ### 인터프리터 언어와 컴파일 언어의 장단점? 170 | 171 | 인터프리터 언어 172 | 173 | - 별도의 컴파일 시간 x → 크기가 큰 소스코드를 바로 실행 가능 174 | - 런타임 환경에서 컴파일 언어에 비해 속도가 느림 175 | 176 | 컴파일 언어 177 | 178 | - 일단 컴파일 되면 인터프리터를 통해 실행하는 것보다 빠르게 실행됨 179 | 180 | --- 181 | 182 | ### 프로토타입 기반 언어란? 183 | 184 | 객체를 원형, 즉 프로토타입으로 복제의 과정을 통해 객체의 동작 방식을 다시 사용할 수 있는 언어 185 | 186 | > - 클래스 기반 언어는 객체 생성 이전에 클래스를 정의하고, 해당 클래스로 인스턴스를 생성해 상속을 구현한다. 187 | 188 | ## 엔진 & 런타임 189 | 190 | ### JavaScript 엔진의 구성은? 191 | 192 | - call stack : 코드 실행에 따라 콜 스택이 쌓이는 곳 193 | - memory heap : 메모리 할당이 일어나는 곳 194 | 195 | > 대표적인 JavaScript 엔진으로 Chrome의 V8 엔진이 있다. 196 | 197 | --- 198 | 199 | ### JavaScript 런타임이란? 200 | 201 | JavaScript가 구동되는 환경. 202 | 203 | > - 자바스크립트 런타임에는 브라우저, Node.js 등이 있다. 204 | > - 자바스크립트는 싱글 스레드인 반면, 자바스크립트 런타임인 브라우저, Node.js 등은 멀티 스레드를 지원한다. 205 | 206 | ## 객체(Object) 207 | 208 | ### Object(객체)란? 209 | 210 | 키와 값으로 구성된 프로퍼티들의 집합 211 | 212 | > - JavaScript에서 원시 타입을 제외한 모든 것이 객체(함수, 배열 등)이다. 213 | > - 프로퍼티의 값으로 JavaScript에서 사용할 수 있는 모든 값을 사용할 수 있다. 214 | > - 프로퍼티의 값으로 함수(: 일급 객체)를 사용할 수 있으며, 프로퍼티 값이 함수일 경우, 일반 함수와 구분 짓기 위해 메소드라고 부른다. 215 | 216 | --- 217 | 218 | ### 객체를 생성하는 방법은? 219 | 220 | > - 객체는 언제나 함수(Function)로 생성된다. 221 | 222 | 1. 객체 리터럴 223 | 224 | - 중괄호(`{ }`)로 객체를 생성하는 방법 225 | 226 | ```jsx 227 | const person = { 228 | name: "Lee", 229 | gender: "female", 230 | }; 231 | ``` 232 | 233 | > - 객체 리터럴은 내부적으로 Object 생성자 함수를 통해 객체를 생성하는 축약 표현이다. 234 | 235 | 2. Object 생성자 함수 236 | 237 | - new 연산자와 Object 생성자 함수를 호출해 빈 객체를 생성하는 방법 238 | 239 | > - '생성자 함수(constructor)': `new` 키워드와 함께 객체를 생성하고 초기화하는 함수 240 | > - Object 생성자 함수는 같은 용도에 비해 객체 리터럴에 코드가 길어 잘 쓰이지 않는다. 241 | > - 게다가, 프로퍼티 값만 다른 여러 객체를 생성할 때마다 같은 프로퍼티를 일일이 추가해줘야 하므로 불편하다. 242 | 243 | ```jsx 244 | const person = new Object(); 245 | person.name = "Lee"; 246 | person.gender = "female"; 247 | ``` 248 | 249 | 3. 생성자 함수 250 | 251 | ```jsx 252 | function Person(name, gender) { 253 | this.name = name; // this는 생성자 함수가 생성할 인스턴스(instance)를 가리킨다. 254 | this.gender = gender; 255 | } 256 | const person1 = new Person("Lee", "female"); 257 | const person2 = new Person("Shin", "male"); 258 | ``` 259 | 260 | > - 생성자 함수 내에서 this에 바인딩되어 있는 프로퍼티와 메소드는 외부에서 참조 가능하다. 261 | > - 생성자 함수 내에서 선언된 일반 변수는 외부에서 참조 불가능하다. 262 | 263 | ## 프로토타입(Prototype) 264 | 265 | ### prototype이란? 266 | 267 | 다른 객체의 원형 객체, 또는 상위 객체 268 | 269 | > - prototype은 prototype object(객체)의 줄임말이다. 270 | 271 | --- 272 | 273 | ### 프로토타입을 사용하는 이유는? (활용되는 예시는?) 274 | 275 | 일부 프로퍼티 값만 다른 객체를 여러 개 생성할 때, 메모리를 절약하는 용도로 활용할 수 있다. 276 | 277 | 예를 들어 `foo`라는 프로퍼티 또는 메소드를 가지는 100개의 객체를 생성한다고 하자. 278 | 내부에 `this.foo`를 통해 프로퍼티를 생성하는 생성자 함수로 100개의 객체를 생성하면, 279 | 100개의 `foo`가 메모리에 할당돼서 저장된다. 280 | 281 | 그러나 만약 생성자 함수의 프로토타입에 `foo` 프로퍼티를 설정한다면, 282 | 1개의 `foo`를 위한 메모리만 사용하면서 100개의 객체가 모두 `foo`를 참조할 수 있게 된다. 283 | 284 | --- 285 | 286 | ### (참고) `[[Prototype]]` & `__proto__` & `prototype` 287 | 288 | JavaScript의 모든 객체는 상속을 구현하기 위해 `[[Prototype]]`이라는 internal slot을 가진다. 289 | 290 | - `[[Prototype]]` 객체의 프로퍼티는 상속되어, 자식 객체에서 사용할 수 있다. 291 | - `[[Prototype]]`의 값은 프로토타입 객체이며, `__proto__`로 접근할 수 있다. 292 | 293 | > - internal slot: 명세에서 요구되는 행동을 정의(구현)하기 위해 사용되는 pseudo-property/method 294 | 295 | 함수 객체(함수도 객체이므로)는 일반 객체와 다르게 `[[Prototype]]` 이외에 `prototype`이라는 프로퍼티도 가진다. 296 | 297 | - `prototype` 프로퍼티는, 함수 객체가 생성자 함수로 사용될 때, 이 함수를 통해 생성될 객체의 프로토타입 객체를 가리킨다. 298 | 299 | --- 300 | 301 | ### 프로토타입이 결정되는 시기는? 302 | 303 | 객체가 생성될 때 프로토타입이 결정된다. 304 | 305 | > - 결정된 프로토타입 객체는 다른 임의의 객체로 동적으로 변경할 수 있다. 306 | 307 | --- 308 | 309 | ### prototype chain이란? 310 | 311 | 특정 객체의 프로퍼티나 메소드에 접근하려고 할 때, 312 | 해당 객체에 접근하려는 프로퍼티 또는 메소드가 없다면, 313 | `[[Prototype]]`이 가리키는 링크를 따라 프로토타입 객체의 프로퍼티나 메소드를 차례대로 검색한다. 314 | 315 | 이를 프로토타입 체인이라고 한다. 316 | 317 | --- 318 | 319 | ### 프로토타입 객체를 확장하는 방법은? 320 | 321 | 프로토타입 객체도 (일반 객체와 마찬가지로) 프로퍼티를 추가/삭제할 수 있다. 322 | 323 | > - 추가/삭제된 프로퍼티는 즉시 프로토타입 체인에 반영된다. 324 | 325 | ```jsx 326 | function Person(name) { 327 | this.name = name; 328 | } 329 | const lee = new Person("Lee"); 330 | 331 | Person.prototype.sayHello = function () { 332 | console.log(`Hi! I'm ${this.name}`); 333 | }; 334 | lee.sayHello(); // Hi! I'm Lee 335 | ``` 336 | 337 | --- 338 | 339 | ### 값을 할당할 때와, 참조할 때 프로토타입 체인이 동작하는 여부? 340 | 341 | 객체의 프로퍼티를 참조하는 경우, 그리고 해당 객체에 해당 프로퍼티가 없는 경우, 프로토타입 체인이 작동한다. 342 | 343 | 객체의 프로퍼티에 값을 할당하는 경우, 프로토타입 체인이 동작하지 않는다. 344 | 왜냐햐면, 객체에 해당 프로퍼티가 있는 경우는 값을 재할당하고, 프로퍼티가 없는 경우에는 해당 객체에 프로퍼티를 동적으로 추가하기 때문이다. 345 | 346 | --- 347 | 348 | ### 프로토타입 객체를 동적으로 변경하는 방법은? 349 | 350 | 생성자 함수의 `prototype`이라는 프로퍼티의 값을 변경하면 된다. 351 | 352 | --- 353 | 354 | ### 프로토타입 객체를 동적으로 변경하기 이전에 생성된 객체와, 이후 생성된 객체의 차이점은? 355 | 356 | - 변경 이전 생성된 객체는, 프로토타입으로 기존의 프로토타입 객체를 가진다. 357 | - 변경 이후 생성된 객체는, 프로토타입으로 변경 이후의 프로토타입 객체를 가진다. 358 | 359 | ```jsx 360 | function Person(name) { 361 | this.name = name; 362 | } 363 | 364 | const lee = new Person("Lee"); 365 | 366 | // 프로토타입 객체를 동적으로 변경 367 | Person.prototype = { gender: "male" }; 368 | 369 | const shin = new Person(); 370 | 371 | console.log(lee.name); // Lee 372 | console.log(lee.gender); // undefined 373 | console.log(shin.gender); // male 374 | ``` 375 | 376 | ## Class `보충` 377 | 378 | ### (참고) Class의 constructor 379 | 380 | - `constructor` 내부에 선언되는 프로퍼티와 메소드는 객체 인스턴스의 것이 된다. 381 | - `constructor` 외부에 선언되는 메서드는, 생성자 함수의 프로토타입 객체의 것이 된다. 382 | 즉 객체 인스턴스의 것이 아니라, 단일 원본을 여러 인스턴스들이 프로토타입 체인에 의해 참조하게 된다. 383 | 384 | ```jsx 385 | class Person { 386 | // 생성되는 객체 인스턴스의 것이 됨. 387 | constructor(name, gender) { 388 | this.name = name; 389 | this.gender = gender; 390 | } 391 | 392 | // Person.prototype에 추가됨 393 | greet() { 394 | return `HI, I'm ${this.name}`; 395 | } 396 | } 397 | ``` 398 | 399 | > class는 ES6에 추가된 'syntactic suger'이다. 400 | 401 | ```jsx 402 | class Person { 403 | constructor(name, gender) { 404 | this.name = name; 405 | this.gender = gender; 406 | } 407 | sayHello() { 408 | return `Hi! I'm ${this.name}`; 409 | } 410 | } 411 | 412 | // class로 구현된 위의 Person은 아래와 같이 정확히 똑같이 구현될 수 있다. 413 | function Person(name, gender) { 414 | this.name = name; 415 | this.gender = gender; 416 | } 417 | 418 | Person.prototype.sayHello = function () { 419 | return `Hi! I'm ${this.name}`; 420 | }; 421 | ``` 422 | 423 | ## Closure 424 | 425 | ### Closure란? 426 | 427 | - 함수와, 그 함수가 선언됐을 때의 (lexical) 환경과의 조합 428 | - (특정 함수로부터) 반환된 내부 함수가, 자신이 선언됐을 때의 환경을 기억해서, 자신이 선언됐을 때의 환경 밖에서 호출되어도 그 환경에 접근할 수 있는 함수 429 | 430 | --- 431 | 432 | ### Closure의 동작 원리를 (실행 컨텍스트와 관련하여) 설명? 433 | 434 | 내부 함수가 유효한 상태에서 외부 함수가 종료하여 외부 함수의 실행 컨텍스트가 반환되어도, 외부 함수의 실행 컨텍스트 내 활성 객체(AO)는 유효. 내부 함수가 스코프 체인을 통해 참조할 수 있게 되는 것. 435 | 436 | ![JavaScript%20f07b25d7438e4d0ca94bbc0c3231bc62/Untitled.png](JavaScript%20f07b25d7438e4d0ca94bbc0c3231bc62/Untitled.png) 437 | 438 | --- 439 | 440 | ### Closure의 활용법? 441 | 442 | 1. 상태 유지: 현재 상태를 기억하고 변경된 최신 상태를 유지하는 것. 443 | 444 | - 즉시실행함수로 내부 함수를 리턴한다. 내부 함수는 즉시실행함수의 변수를 기억하는 클로저이다. 445 | - 내부 함수가 존재하는 한 '자유 변수'는 유지되고, 446 | 내부 함수가 실행되면 내부 함수의 로직에 따라 자유 변수는 변경되어 최신 상태를 유지한다. 447 | 448 | ```jsx 449 | const toggle = (() => { 450 | let isVisible = false; 451 | 452 | return () => { 453 | isVisible = !isVisible; 454 | box.style.display = isVisible ? "block" : "none"; 455 | }; 456 | })(); 457 | 458 | toggleBtn.onclick = toggle; 459 | ``` 460 | 461 | >- 자유 변수(free variable) : 클로저에 의해 참조되는 외부 함수의 변수 462 | >- 내부 함수의 지역 변수로 상태를 관리한다면, 내부 함수를 호출할 때마다 지역 변수가 초기화되므로 변경된 최신 상태를 기억하지 못하지! 반면 IIFE는 한번만 실행되므로 변수가 초기화 될 일은 없다. 463 | 464 | 2. 정보의 은닉 465 | 466 | - 생성자 함수를 선언. 생성자 함수 내 변수는 this로 바인딩하지 않는 한 자유변수가 됨. 생성자 내부 메소드만 접근 가능. 467 | - this 바인딩된 프로퍼티는 외부 접근 가능한 `public` 프로퍼티가 되지만, 자유변수는 `private` 프로퍼티가 된다. 468 | 469 | ```jsx 470 | function Counter() { 471 | let counter = 0; // free variable 472 | 473 | this.increase = () => ++counter; 474 | this.decrease = () => --counter; 475 | } 476 | ``` 477 | 478 | --- 479 | 480 | ### Closure의 상태 유지가 전역 변수에 비해 갖는 이점? 481 | 482 | 전역 변수는 누구나 접근할 수 있기 때문에 많은 부작용을 유발. 오류 원인. 483 | 484 | --- 485 | 486 | ### 렉시컬 스코핑(lexical scoping)이란? 487 | 488 | 스코프가 함수를 호출할 때가 아니라 함수가 선언될 때 결정되는 것 489 | 490 | --- 491 | 492 | ### Closure의 단점? 493 | 494 | - 메모리: 내부 함수가 참조하고 있는 한 메모리는 해제되지 않고 남아있다. 495 | (→ 지속적으로 반복문을 돌면서 클로저를 생성하는 등, 과도하게 사용할 시 문제) 496 | - 퍼포먼스: 변수 조회 시 클로저로 생성한 스코프를 탐색. 497 | (→ 과도하게 사용할 시 문제) 498 | 499 | --- 500 | 501 | ### Closure가 참고하고 있는 메모리를 해제해주려면 어떻게 할까? 502 | 503 | 클로저가 해당 스코프의 변수를 더 이상 참조하지 않도록 해주면 된다. 504 | 505 | > - 종료된 외부 함수의 실행 컨텍스트의 활성 객체는 이를 필요로 하는 내부 함수가 하나 이상 존재할 경우 계속 유지된다. 506 | 507 | --- 508 | 509 | ### 클로저로 인해 자주 발생하는 실수에는 어떤 것들이 있을까? `보충` 510 | 511 | ## this 512 | 513 | ### this란? 514 | 515 | 그것이 속해있는 객체를 표현하는 값 516 | 517 | --- 518 | 519 | ### this의 값이 결정되는 방식을 설명? 520 | 521 | **함수 호출 방식**에 의해 this에 바인딩되는 객체가 동적으로 결정. 522 | 523 | > '동적'으로 결정된다는 말은, 함수가 선언될 때 this에 바인딩되는 객체가 '정적'으로 결정되는 것이 아니라, 함수가 호출될 때 어떻게 호출되었는지에 따라 결정된다는 말이다. 524 | 525 | 함수를 526 | 527 | - 함수로서 호출 하는지 528 | - 메소드로서 호출 하는지 529 | - 생성자 함수로서 호출 하는지 530 | 531 | 에 따라 달라진다. 532 | 533 | --- 534 | 535 | ### 함수가 '일반 함수로서' 호출될 때 this가 바인딩되는 객체는? 536 | 537 | 전역객체(global object). 538 | 539 | > - 이를 '기본 바인딩'이라 한다. 540 | 541 | --- 542 | 543 | ### 전역객체란? 544 | 545 | - 모든 객체의 유일한 최상위 객체를 의미. 546 | - 전역 변수(global variable)를 프로퍼티로 소유한다. 547 | 548 | --- 549 | 550 | ### Browser-side와 server-side에서의 전역객체가 어떻게 다른가? 551 | 552 | 전역객체는 Browser-side에서는 `window`. Node.js 등 server-side에서는 `global` 객체를 의미한다. 553 | 554 | --- 555 | 556 | ### 그러면 함수의 내부 함수나 메소드의 내부 함수, 콜백 함수가 '일반 함수로서' 호출될 때의 this는 어떻게 될까? 557 | 558 | 함수로서 호출된다면 일반 함수, 함수의 내부 함수, 메소드의 내부 함수, 콜백 함수 어디에서 선언되든 관계 없이 this는 전역 객체를 바인딩한다. 559 | 560 | --- 561 | 562 | ### 함수가 '일반 함수로서' 호출되었을 때 this가 전역 객체를 참조하는 것을 회피하는 방법이 있을까? 563 | 564 | apply, call, bind를 사용해서 명시적으로 this를 바인딩할 수 있다. 565 | 566 | --- 567 | 568 | ### 함수가 '메소드로서' 호출될 때 this가 바인딩되는 객체는? 569 | 570 | 해당 메소드를 소유한 객체. 571 | 572 | > - 함수가 객체의 프로퍼티 값이면 메소드로서 호출된다. 573 | > - 이를 '암시적 바인딩'이라 한다. 574 | 575 | --- 576 | 577 | ### 그러면 함수가 '프로토타입 객체의 메소드로서' 호출될 때는? 578 | 579 | 일반 메소드 방식과 마찬가지로 해당 메소드를 호출한 객체에 바인딩. 580 | 581 | --- 582 | 583 | ### 함수가 '생성자 함수로서' 호출될 때 this가 바인딩되는 객체는? 584 | 585 | - 생성자 함수의 코드가 실행되기 전 생성되는 빈 객체를 가리킨다. 586 | - this를 통해 빈 객체에 동적으로 프로퍼티나 메소드가 추가될 수 있다. 587 | 588 | > - 'new 바인딩'이라고도 한다. 589 | 590 | --- 591 | 592 | ### 객체 리터럴 방식과 생성자 함수 방식의 차이는? 593 | 594 | 프로토타입 객체( `[[Prototype]]` )에 차이가 있다. 595 | 596 | - 객체 리터럴 방식의 경우, 생성된 객체의 프로토타입 객체는 `Object.prototype`이다. 597 | - 생성자 함수 방식의 경우, 예를 들어 `Person`이라는 함수명을 가진 생성자 함수라고 했을 때, 생성된 객체의 프로토타입 객체는 `Person.prototype`이다. 598 | 599 | --- 600 | 601 | ### 명시적으로 this를 바인딩하는 방법? 602 | 603 | `Function.prototype` 객체의 메소드인 apply와 call, bind 메소드를 사용할 수 있다. 604 | 605 | > - `Function.prototype`은 모든 함수 객체의 프로토타입 객체이다. 606 | > - apply와 call을 통한 바인딩을 '명시적 바인딩', bind를 통한 바인딩을 '하드 바인딩'이라 한다. 607 | 608 | --- 609 | 610 | ### this를 사용할 때 자주 발생하는 실수에는 어떤 것들이 있을까? 611 | 612 | this를 사용하는 함수를 콜백 함수로 넘겨줄 때 의도와 다르게 동작하는 경우가 있다. 613 | 614 | - 예를 들어, setTimeout의 콜백 함수로 어떤 객체의 메소드를 전달하면, 해당 콜백 함수는 메소드로서 실행되는 것이 아니라 일반 함수로 실행된다. 따라서 this는 전역 객체를 가리키게 된다. 615 | 616 | ```jsx 617 | name = "global context!"; 618 | 619 | function hello() { 620 | console.log(this.name); 621 | } 622 | 623 | var obj = { 624 | name: "chris", 625 | hello: hello, 626 | }; 627 | 628 | setTimeout(obj.hello, 1000); // "global context" 629 | ``` 630 | 631 | --- 632 | 633 | ### apply, call, bind 메소드의 사용법에 대해 설명? 634 | 635 | `call` 636 | 637 | - this를 바인딩할 함수의 프로퍼티로 `call()`을 호출한다. 638 | - `call()`의 첫 번째 인자로, 바인딩할 객체를 전달한다. 639 | - `call()`의 두 번째 인자부터는 (optional) 함수로 전달할 인자를 전달한다. 640 | 641 | > - `call()`은 this를 바인딩할 뿐 아니라 `call()`을 호출한 함수를 실행한다. 642 | > - 첫 번째 인자로 `null`을 전달하면 this는 전역 객체를 바라본다. 643 | 644 | `apply` 645 | 646 | - `call()`과 모든 것이 동일하나, `call()`은 함수에 전달할 인자로 인자 여러 개를, `apply()`는 인자 여러 개를 하나로 묶은 배열 하나를 인자로 전달한다. 647 | 648 | ```jsx 649 | const say = function (city) { 650 | console.log(`Hello, ${this.name} in ${city}`); 651 | }; 652 | 653 | name = "Jin"; 654 | const obj = { name: "Tom" }; 655 | 656 | say("seoul"); // Hello, Jin in seoul 657 | say.call(obj, "paris"); // Hello, Tom in paris 658 | say.apply(obj, ["new york"]); // Hello, Tom in new york 659 | ``` 660 | 661 | `bind` 662 | 663 | - this를 바인딩할 함수의 메소드로 `bind()`를 호출하고, 인자로 바인딩할 객체를 전달한다. 664 | - apply, call과 다르게 바인딩만 하고 해당 함수를 호출하지는 않고 반환한다. 665 | 666 | ```jsx 667 | const obj1 = { 668 | name: "shin", 669 | yell: function () { 670 | console.log(this.name); 671 | }, 672 | }; 673 | const obj2 = { 674 | name: "Lee", 675 | }; 676 | 677 | const yell2 = obj1.yell.bind(obj2); 678 | yell2(); // 'Lee' 679 | ``` 680 | 681 | --- 682 | 683 | ### 유사 배열(arguments)이 배열의 메소드를 사용할 수 있도록(조작할 때) apply와 call을 사용하는 방법에 대해 아는지? 684 | 685 | > - 유사 배열(`arguments`)은 함수에 전달된 인수로, 배열의 형태를 띄지만 실제 배열은 아니기에 유사 배열이라 불린다. 686 | > 687 | > - 유사 배열은 실제 배열이 아니기 때문에 배열의 메소드를 사용할 수 없다. 688 | 689 | apply나 call을 사용해 이를테면 다음과 같이 사용할 수 있다. 690 | 691 | ```jsx 692 | function example() { 693 | console.log(Array.prototype.join.call(arguments)); 694 | } 695 | 696 | example(1, "string", true); // '1,string,true' 697 | ``` 698 | 699 | --- 700 | 701 | ### 암시적 바인딩과 명시적 바인딩의 우선 순위는? 702 | 703 | 명시적 바인딩이 암시적 바인딩보다 우선된다. 704 | 705 | ```jsx 706 | function hello() { 707 | console.log(this.name); 708 | } 709 | 710 | var obj = { 711 | name: "shin", 712 | hello: hello, 713 | }; 714 | 715 | obj.hello(); // 'shin' 716 | obj.hello.call({ name: "lee" }); // 'lee' 717 | ``` 718 | 719 | > new 바인딩 > 명시적 바인딩 > 암시적 바인딩 > 기본 바인딩 720 | 721 | --- 722 | 723 | ### arrow function에서의 this는 어떻게 동작하나? 724 | 725 | - 기존 함수 호출을 통한 this 바인딩은 '동적 바인딩'인 것에 반해, arrow function에서는 '정적 바인딩'이 적용된다. 726 | - array function은 코드상 상위 블록의 컨텍스트를 this로 바인딩한다. 727 | 728 | ```jsx 729 | function hello() { 730 | setTimeout(function callback() { 731 | console.log(this.name); 732 | }); 733 | } 734 | 735 | function helloArrow() { 736 | setTimeout(() => { 737 | console.log(this.name); 738 | }); 739 | } 740 | 741 | var obj1 = { 742 | name: "Lee", 743 | hello: hello, 744 | }; 745 | 746 | var obj2 = { 747 | name: "Shin", 748 | helloArrow: helloArrow, 749 | }; 750 | 751 | var name = "global context"; 752 | 753 | hello(); // 'global contenxt' 754 | helloArrow(); // 'global contenxt' 755 | obj1.hello(); // 'Lee' 756 | obj2.helloArrow(); // 'global contenxt' 757 | hello.call({ name: "chris" }); // 'chris' 758 | helloArrow.call({ name: "alice" }); // ''global contenxt' 759 | ``` 760 | 761 | --- 762 | 763 | ### arrow function을 사용하면 안되는 경우는? 764 | 765 | 1. 메소드: 화살표 함수로 메소드를 정의하는 것은 피해야 한다. 766 | 767 | - 메소드로 정의한 화살표 함수 내부의 `this`는 메소드를 소유한 객체가 아닌, 상위 컨텍스트인 전역 객체를 가리킨다. 768 | - 이와 같은 경우는 메소드 단축 표기법인 `ES6 축약 메소드 표현`을 사용하는 것이 좋다. 769 | 770 | ```jsx 771 | const person = { 772 | name: "Lee", 773 | // 화살표 함수 774 | sayHi: () => console.log(`Hi, ${this.name}`), 775 | // ES6 축약 메소드 표현 776 | sayBye() { 777 | console.log(`Bye, ${this.name}`); 778 | }, 779 | }; 780 | 781 | person.sayHi(); // Hi, undefined 782 | person.sayBye(); // Bye, Lee 783 | ``` 784 | 785 | 2. 생성자 함수 786 | 787 | - 화살표 함수는 생성자 함수로 사용할 수 없다. 화살표 함수는 `prototype` 프로퍼티를 가지고 있지 않다. 788 | 789 | ```jsx 790 | const Foo = () => {}; 791 | const foo = new Foo(); // TypeError: Foo is not a constructor 792 | ``` 793 | 794 | 3. `addEventListener` 함수의 콜백 함수 795 | 796 | - `addEventListener` 함수의 콜백 함수를 화살표 함수로 등록하면, `this`가 상위 컨텍스트인 전역 객체(`window`)를 가리킨다. 797 | - 따라서, `addEventListener` 함수의 콜백 함수 내에서 `this`를 사용한다면 `function` 키워드로 정의한 일반 함수를 사용해야 한다. 일반 함수로 정의된 `addEventListener` 함수의 콜백 함수 내부 `this`는 이벤트 리스너에 바인딩된 요소(`currentTarget`)를 가리킨다. 798 | 799 | ```jsx 800 | var button = document.getElementById("myButton"); 801 | 802 | button.addEventListener("click", () => { 803 | console.log(this === window); // true 804 | this.innerHTML = "Clicked button"; 805 | }); 806 | 807 | button.addEventListener("click", function () { 808 | console.log(this === button); // true 809 | this.innerHTML = "Clicked button"; 810 | }); 811 | ``` 812 | 813 | --- 814 | 815 | ## 비동기 처리 816 | 817 | ### JavaScript에서의 비동기 프로그래밍이란? 818 | 819 | JavaScript가 웹 API 등을 비동기적으로 실행함에 따라, 820 | 821 | - 작업이 언제 끝날지 모르는 상황을 대응하고 822 | - 처리 순서를 보장하기 위한 823 | 824 | 프로그래밍 방식이다. 825 | 826 | --- 827 | 828 | ### JavaScript가 코드를 비동기적으로 실행하는 이유는 뭘까? 829 | 830 | 비동기 기법은 웹 프로그래밍에 유용하다. 831 | 832 | JavaScript에서 시간이 오래 걸리는 작업을 동기적으로 처리할 경우, 해당 작업을 실행하느라 브라우저에게 제어권을 돌려주지 않게 되고 이를 blocking이라고 한다. blocking으로 인해 사용자는 브라우저가 마치 정지된 것처럼 느끼게 될 것이다. 833 | 834 | 비동기 기법을 사용할 경우 시간이 오래 걸리는 작업을 요청해놓고, 그동안 사용자에게 적절한 UI를 렌더링해주는 등 다른 작업들을 수행할 수 있다. 835 | 836 | --- 837 | 838 | ### JavaScript에서 (시간이 오래 걸리는) 동기적인 코드가 blocking을 일으키는 이유는 뭘까? 839 | 840 | JavaScript는 single thread 기반의 언어이기 때문이다. 841 | 하나의 main thread에서, 한 번에 하나의 작업만 처리될 수 있다. 그 다음 작업은 앞선 작업이 끝난 다음에야 수행될 수 있다. 842 | 843 | --- 844 | 845 | ### 프론트엔드에서 비동기 처리가 중요한 이유는? 846 | 847 | - 웹은 현대에 들어서며 정적인 웹에서 동적인 웹으로 진화했다. 848 | - 그에 따라 웹은 사용자와 상호작용하며 연속적으로 변경되는 정보를 실시간으로 보여주어야 하는 일이 늘어났다. 849 | - 이때, 사용자로부터 들어오는 요청을 들어온 순서대로 처리할 경우 사용자의 대기 시간이 크게 늘어날 것이다. 850 | 타이머를 사용한 이벤트, 서버와의 통신, 애니메이션 등 예측할 수 없는 다양한 이벤트가 존재하기 때문이다. 851 | - 비동기 처리를 통해 이벤트를 기다리는 일을 사용자가 아닌 브라우저가 하도록 위임할 수 있다. 852 | 이를 통해 사용자 경험이 크게 향상될 것이다. 853 | 854 | --- 855 | 856 | ## 콜백 패턴 & Promise 857 | 858 | ### Promise란? 859 | 860 | 비동기 작업이 미래에 맞게되는 완료 또는 실패와 그 결과값을 나타내는 객체 861 | 862 | > - Promise는 ES6에 정식 채택되어 IE를 제외한 대부분의 최신 브라우저에서 정상 작동한다. 863 | 864 | --- 865 | 866 | ### 동기식 작업과 비동기식 작업이란? 차이점은? 867 | 868 | 동기식(Synchronous) 처리 모델 869 | 870 | - 태스크가 순차적으로 실행된다. 871 | - 어떤 작업이 수행 중이면 다음 작업은 대기하게 된다. 872 | 873 | 비동기식(Asynchronous/Non-Blocking) 처리 모델 874 | 875 | - 태스크가 병렬적으로 실행된다. 876 | - 어떤 작업이 수행 중일 경우(종료되지 않은 상태이더라도), 대기하지 않고 바로 다음 태스크를 실행한다. 877 | 878 | --- 879 | 880 | ### Promise는 어떤 문제점을 해결하고자 등장했나? 881 | 882 | - js는 비동기 처리를 위해 전통적인 콜백 패턴을 사용했었다. 883 | - 콜백 패턴은 콜백 헬로 인해 가독성이 나쁘다. 884 | - 비동기 처리 중 발생한 에러 처리가 곤란하다. 여러 개의 비동기 처리를 한 번에 처리하는 데 한계가 있다. 885 | 886 | --- 887 | 888 | ### 비동기 처리에 콜백 패턴을 사용해야 하는 이유는? 889 | 890 | ('프론트엔드에서 비동기 프로그래밍이 필요한 이유'와 같은 결로 이해하면 된다.) 891 | 892 | - 처리 순서를 보장하기 위함 893 | - js의 비동기식 처리는 실행 완료를 기다리지 않고 다음 태스크를 진행한다. 비동기 함수 내에서 처리 결과를 반환하는 로직이 기대한 대로 동작하지 않는다. 894 | - 때문에 비동기 함수의 처리 결과에 대한 처리는 콜백 함수 내에서 진행해야 한다. 895 | 896 | > 자바스크립트의 대부분의 DOM 이벤트와 Timer 함수, Ajax 요청은 비동기식 처리 모델로 동작한다. 897 | 898 | --- 899 | 900 | ### 콜백 방식의 비동기 처리가 에러 처리에 곤란한 이유는? 901 | 902 | 예외(exception)은 호출자(caller) 방향으로 전파되기 때문에, 콜백 함수 내에서 발생된 에러를 잡을 수 없기 때문이다. 903 | 904 | 예를 들어 try 블록 내에 비동기 처리 함수(예를 들어 setTimeout)가 있고, setTimeout의 콜백 함수는 예외를 발생시킨다고 하자. 905 | 906 | ```jsx 907 | try { 908 | setTimeout(() => { 909 | throw new Error("Here is error!"); 910 | }); 911 | } catch (e) { 912 | // Thrown error can't be catched in here. 913 | } 914 | ``` 915 | 916 | > `throw` 문은 사용자 정의 예외를 던질 수 있다. 호출자 함수 사이에 catch 블록이 없으면 프로그램이 중지된다. 917 | > (https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/throw) 918 | 919 | - 비동기 처리 함수 setTimeout은 실행 후 콜 스택에서 즉시 제거된다. 920 | - 콜백 함수는 이벤트 발생 시 태스크 큐로 이동한 후 콜 스택이 비워졌을 때 콜 스택으로 이동해 실행된다. 921 | - 콜 스택에 setTimeout이 존재하지 않기 때문에, setTimeout은 콜백 함수의 호출자가 아니게 된다. 호출자라면 콜 스택에 존재해야 한다. 922 | - 예외는 호출자 방향으로 전파되지만, setTimeout이 존재하지 않아 에러는 catch 블록에 잡히지 않는다. 프로세스는 종료된다. 923 | 924 | > - `try ... catch` 문은 실행할 코드 블록을 표시하고, 예외(exception)가 발생(throw)했을 경우 응답을 지정한다. 925 | 926 | --- 927 | 928 | ### Promise를 생성하는 방법은? 929 | 930 | - Promise 생성자 함수를 통해 생성한다: `Promise()` 931 | - 인자로 비동기 작업을 수행할 콜백 함수를 전달한다. 932 | 933 | > - 콜백 함수는 resolve와 reject 함수를 인자로 전달 받는다. 934 | > - 콜백 함수는 프로미스 내부 구현에 의해 즉시 실행된다. Promise 생성자 함수가 생성한 객체를 반환하기도 이전에 호출된다. 935 | 936 | --- 937 | 938 | ### Promise의 상태(state)는 어떤 것들이 있나? 939 | 940 | `pending`, `fulfilled`, `rejected`, `settled` 941 | 942 | - `pending` : 비동기 처리가 아직 수행되지 않은 상태. 즉 `resolve나` `reject` 함수가 아직 호출되지 않은 상태 943 | - `fulfilled` : 비동기 처리가 수행되었고 성공한 상태. 즉 `resolve가` 호출된 상태 944 | - `rejected` : 비동기 처리가 수행되었고 실패한 상태. 즉 `reject가` 호출된 상태 945 | - `settled` : 비동기 처리가 수행되었고 성공 또는 실패한 상태. 즉 `resolve` 또는 `reject가` 호출된 상태 946 | 947 | --- 948 | 949 | ### Promise의 후속 처리 메소드에 대해 설명? 950 | 951 | - `then`과 `catch`, `finally`가 있다. 952 | - Promise 객체의 결과 상태에 따라 후속 처리 메소드를 체이닝 방식으로 호출한다. 953 | 954 | `then`은 955 | 956 | - 두 개의 콜백 함수를 인자로 받는다. 첫 번째는 성공 시(`fulfilled`) 호출되고, 두 번째는 실패 시(`rejected`) 호출된다. 957 | 958 | `catch`는 959 | 960 | - 예외가 발생하면 호출된다. 961 | 962 | `finally`는 963 | 964 | - 성공, 혹은 실패 시 호출된다. 965 | 966 | > - finally 메소드에는 인수가 없다. 즉 Promise가 이행되었는지, 거부되었는지 알 수 없다. 967 | > 968 | > - `then`과 `catch`, `finally` 메소드는 Promise를 반환한다. 969 | 970 | --- 971 | 972 | ### Promise의 에러 처리는 then과 catch 중 어떤 것으로 하는 것이 더 좋을까? 973 | 974 | `catch`로 하는 것이 좋다. 975 | 976 | `then`은 977 | 978 | - 두 번째 콜백 함수로 비동기 작업 간에 발생하는 에러를 처리할 수 있다. 979 | - 단, 첫 번째 콜백 함수에서 발생한 에러를 캐치하지 못한다. 980 | - 코드가 복잡해져서 가독성이 좋지 않다. 981 | 982 | `catch`는 983 | 984 | - 모든 `then` 메소드를 호출한 이후 호출하면, 비동기 작업 간 발생한 에러 뿐만 아니라 `then` 메소드 내부에서 발생한 에러까지 모두 캐치할 수 있다. 985 | - `then`에 비해 가독성이 좋고 명확하다. 986 | 987 | > catch 메소드는 내부적으로 `then(undefined, onRejected)`를 호출한다. 988 | 989 | --- 990 | 991 | ### Promise의 정적 메소드에 대해 설명? 992 | 993 | - `Promise.resolve`, 994 | - `Promise.reject`, 995 | - `Promise.all`, 996 | - `Promise.race` 997 | 998 | 가 있다. 999 | 1000 | > Promise는 생성자 함수이지만, 함수도 객체이므로 메소드를 가질 수 있다. 1001 | 1002 | --- 1003 | 1004 | ### Promise.resolve와 Promise.reject에 대해 설명? 1005 | 1006 | 존재하는 값을 Promise로 매핑하기 위해 사용된다. 1007 | 1008 | - `Promise.resolve`는 인자로 전달된 값을 `resolve`하는 Promise를 생성한다. 1009 | - `Promise.reject`는 인자로 전달된 값을 `reject`하는 Promise를 생성한다. 1010 | 1011 | --- 1012 | 1013 | ### Promise.all과 Promise.race에 대해 설명? 1014 | 1015 | `Promise.all` 1016 | 1017 | - Promise가 담겨 있는 배열 등을 인자로 받아, 내부 Promise를 병렬로 처리하고 그 처리 결과를 `resolve`하는 Promise를 반환한다. 1018 | 1019 | > - 처리 순서가 보장된다. 즉, 배열의 첫 번째 Promise가 resolve한 처리 결과부터 차례대로 배열에 담아 그 배열을 resolve하는 Promise를 반환한다. 1020 | > - 프로미스의 처리가 하나라도 실패하면 가장 먼저 실패한 Promise가 reject한 에러를 reject하는 새로운 Promise를 즉시 반환한다. 1021 | > - 전달 받은 배열의 요소가 Promise가 아닐 경우, Promise.resolve 메소드를 통해 Promise로 매핑된다. 1022 | 1023 | `Promise.race` 1024 | 1025 | - `Promise.all`과 동일하게 Promise가 담겨 있는 배열 등을 인자로 받는다. 1026 | - 다만 배열의 모든 Promise를 병렬 처리하는 것이 아니라, 가장 먼저 처리된 Promise가 `resolve`한 처리 결과를 `resolve`하는 새로운 Promise를 반환한다. 1027 | 1028 | ## 이벤트 루프 1029 | 1030 | ### 이벤트 루프란? 1031 | 1032 | 자바스크립트의 싱글 스레드 엔진과 멀티 스레드 환경을 연동시켜주는 장치. 1033 | 1034 | --- 1035 | 1036 | ### 이벤트 루프가 필요한 이유는? 1037 | 1038 | - 자바스크립트는 싱글 스레드 기반의 언어이다. → 한번에 하나의 작업만 처리할 수 있다. 1039 | - (브라우저 환경을 예시로 들면) 마우스 이벤트 발생, HTTP 요청, 애니메이션 등의 작업이 동시에 이뤄진다. 1040 | - 자바스크립트가 이러한 동시성을 지원할 수 있도록 이벤트 루프가 도와준다. 1041 | 1042 | (즉, 싱글 스레드 기반 언어인 자바스크립트가 동시성을 지원할 수 있도록 도와주는 것은 브라우저, Node.js 등 외부의 환경이다.) 1043 | 1044 | --- 1045 | 1046 | ### Run-to-Completion이란? 1047 | 1048 | 자바스크립트에서 하나의 함수가 실행되면, 그 함수의 실행이 끝날 때까지 다른 어떤 작업도 중간에 끼어들지 못하는 특성. 1049 | 1050 | --- 1051 | 1052 | ### 자바스크립트가 Run-to-Completion으로 동작하는 원리는? 1053 | 1054 | - 자바스크립트 엔진은 단일 콜 스택 구조로 이루어져 있다. 1055 | - 함수가 호출되면 스택에 해당 함수의 코드 블록이 쌓이고, 실행이 완료되면 코드 블록이 스택에서 제거된다. 1056 | - 하나의 함수가 콜 스택에 쌓이면, 콜 스택이 비워질 때까지 다른 함수의 코드 블록이 스택에 추가되지 않는다. 1057 | 1058 | --- 1059 | 1060 | ### 태스크 큐가 동작하는 과정은? 1061 | 1062 | 예를 들어 다음과 같은 상황이라고 하자. 1063 | 1064 | ```jsx 1065 | const A = () => { 1066 | console.log("A"); 1067 | }; 1068 | 1069 | const B = () => { 1070 | for (let i = 0; i < 100000; i++); 1071 | console.log("B"); 1072 | }; 1073 | 1074 | setTimeout(A, 1000); 1075 | B(); 1076 | // 'B' 1077 | // 'A' 1078 | ``` 1079 | 1080 | - `setTimeout()` 함수가 콜 스택에 진입한다. 1081 | - `setTimeout()`은 즉시 콜 스택에서 제거되고, 백그라운드에서 1초를 센다. 1082 | - `B()`가 콜 스택에 진입한다. 반복문을 실행한다. 1083 | - 1초가 지나고, 백그라운드에서 콜백 함수 `A()`를 태스크 큐로 보낸다. 1084 | - `A()`가 실행할 준비를 마쳤어도, `B()`의 반복문이 끝나 콜 스택에서 제거되지 않으면 run-to-completion 특성으로 인해 `A()`는 실행되지 않는다. 1085 | - `B()`의 반복문이 끝나 콜 스택에서 제거되고 나서야, 이벤트 루프는 태스크 큐의 `A()`를 콜 스택에 추가한다. 1086 | 1087 | > - 대부분의 비동기 코드들(ex: Ajax, setTimeout, Promise 등)은 모두 Web API에서 처리된다. 1088 | > - Web API에 요청했던 작업이 끝나면 콜백으로 전달한 함수가 큐에 등록된다. 1089 | > - 이벤트 루프는 콜 스택이 비워져 있을 경우, 큐의 작업들을 콜 스택에 추가한다. 1090 | 1091 | > - Web API는 브라우저에서 제공하는 API이다. 1092 | 1093 | --- 1094 | 1095 | ### 태스크 큐와 마이크로 태스크 큐가 동작하는 과정은? 1096 | 1097 | 예를 들어 다음과 같은 상황이라고 하자. 1098 | 1099 | ```jsx 1100 | setTimeout(() => { 1101 | console.log("A"); 1102 | }, 1000); 1103 | 1104 | Promise.resolve() 1105 | .then(() => { 1106 | console.log("B"); 1107 | }) 1108 | .then(() => { 1109 | console.log("C"); 1110 | }); 1111 | // B 1112 | // C 1113 | // A 1114 | ``` 1115 | 1116 | - Promise는 마이크로 태스크(micro task)이다. 1117 | - 마이크로 태스크는 일반 태스크보다 높은 우선 순위를 가진다. 따라서 이벤트 루프는 콜 스택이 비어 큐의 작업을 추가할 때, 마이크로 태스크 큐를 먼저 확인한 후 태스크 큐를 확인한다. 1118 | 1119 | > - Animation Frames라는 큐도 있다. 브라우저 렌더링과 관련된 API가 해당된다. 1120 | > - 우선 순위: 마이크로 태스크 > Animation Frame > 태스크 1121 | 1122 | --- 1123 | 1124 | ### 이벤트 루프(혹은 태스크 큐의 우선 순위)로 인해 사용자 경험에 해가 되는 경우가 있을까? 1125 | 1126 | 태스크는 이벤트 루프를 통해 순차적으로 실행되기 때문에, 고비용 연산을 포함한 태스크나 마이크로 태스크가 있다면 이로 인해 다른 작업들 - 그 중에서도 사용자 경험과 직결된 이벤트(클릭, 텍스트 입력, 렌더링 등)가 가로막힐 수 있다. 1127 | 1128 | --- 1129 | 1130 | ### 고비용 연산으로 인한 블로킹에 대응하는 방법은? 1131 | 1132 | 1. 고비용 연산을 수행하는 태스크를 적절히 쪼개 실행할 수 있다. 1133 | 1134 | ```jsx 1135 | let i = 0; 1136 | 1137 | const count = () => { 1138 | while (i % 100 !== 0) i++; 1139 | 1140 | if (i === 10000) console.log("work completed"); 1141 | else setTimeout(count); 1142 | }; 1143 | 1144 | count(); 1145 | ``` 1146 | 1147 | - 쪼개진 고비용 연산이 콜 스택에서 수행되는 동안 이벤트가 발생하면, 태스크 큐에서 대기한다. 1148 | - 쪼개진 연산이 끝나 콜 스택에서 제거되면, 다음 연산이 수행되기 전에 태스크 큐의 작업이 먼저 콜 스택에 추가되어 작업이 진행된다. 1149 | 1150 | 2. 자바스크립트의 웹 워커(Web Worker)를 사용해 멀티 스레딩을 할 수 있다. 1151 | 1152 | - 웹 워커: 스크립트 연산을 별도의 백그라운드 스레드에서 실행할 수 있는 Web API. 1153 | 1154 | 사용 방법 1155 | 1156 | - 메인 스레드에서 워커 객체를 생성한다. (파라미터로는 워커가 수행할 스크립트 파일 명을 전달한다.) 1157 | `const myWorker = new Worker("work.js");` 1158 | - 메인 스레드에서 메시지에 기반해 워커와 통신한다. 1159 | 1160 | `postMessage()`로 작업의 실행을 요청한다. 워커는 결과를 반환한다. 1161 | 1162 | 한계 1163 | 1164 | - 메시지 기반으로만 통신이 가능하므로, 메인 스레드의 context에 접근할 수 없다. 특히, DOM 객체를 직접 조작할 수 없다. 1165 | 1166 | --- 1167 | 1168 | ### (참고) 활용 예시: progress bar 1169 | 1170 | ```html 1171 |
1172 | 1182 | ``` 1183 | 1184 | - `i`가 `9999`가 되고 나서야 브라우저는 `
`에 `9999`를 출력한다. 이전의 `i`는 출력되지 않는다. 1185 | - 브라우저가 스크립트를 실행할 때는 렌더링 작업을 멈추기 때문이다. 1186 | - 이 역시 `setTimeout()`으로 스케줄링을 하면 `i`가 변하는 모습을 실시간으로 볼 수 있다. 1187 | 1188 | ## 실행 컨텍스트 1189 | 1190 | ### 실행 컨텍스트란? 1191 | 1192 | 실행 가능한 코드가 실행되기 위해 필요한 환경. 1193 | 1194 | > - "실행 가능한 코드를 형상화하고 구분하는 추상적인 개념" (by ECMAScript spec) 1195 | 1196 | --- 1197 | 1198 | ### 실행 가능한 코드란? 1199 | 1200 | - 전역 코드: 전역 영역에 존재하는 코드 1201 | - 함수 코드: 함수 내에 존재하는 코드 1202 | - eval 코드: `eval` 함수로 실행되는 코드 1203 | 1204 | --- 1205 | 1206 | ### 실행에 필요한 환경이란? 1207 | 1208 | 변수, 함수 선언, 스코프, this 등 1209 | 1210 | > 이와 같이 실행에 필요한 정보들을 형상화하고 구분하기 위해 자바스크립트 엔진은 실행 컨텍스트를 물리적 객체의 형태로 관리한다. 1211 | 1212 | --- 1213 | 1214 | ### 코드가 실행되고, 함수가 실행되고 끝나는 과정을 실행 컨텍스트 스택으로 설명해본다면? 1215 | 1216 | - 실행 컨텍스트 스택은 Last-In-First-Out의 스택 구조를 띈다. 1217 | - 전역 코드(global code)에 진입하면, 전역 EC가 생성되고, EC 스택에 쌓인다. 1218 | 1219 | > EC 스택은 어플리케이션이 종료될 때까지 유지된다. 1220 | 1221 | - 함수를 호출하면, 해당 함수의 EC가 생성되며, 직전에 실행된 코드 블록의 EC 위에 쌓인다. 컨트롤이 새로 생성된 EC에게 이동한다. 1222 | - 함수 실행이 끝나면,해당 EC를 파기하고 직전의 EC에 컨트롤을 반환한다. 1223 | 1224 | --- 1225 | 1226 | ### 실행 컨텍스트의 (물리적인) 구조는? 1227 | 1228 | 1. Variable Object(변수 객체) 1229 | 1230 | 2. Scope Chain 1231 | 1232 | 3. this 1233 | 1234 | --- 1235 | 1236 | ### Variable Object란? 1237 | 1238 | 실행에 필요한 여러 정보들을 담은 객체. 1239 | 1240 | - 변수 1241 | - 함수 선언 1242 | - parameter(매개변수)와 arguments(인수) 정보 (: 함수 컨텍스트인 경우에만) 1243 | 1244 | > - VO는 코드가 실행될 때 엔진에 의해 참조되며, 코드에서는 접근할 수 없다. 1245 | 1246 | > - 매개변수(parameters): 함수의 입력 변수 명 1247 | > - 인수(arguments): 함수의 입력 값 1248 | 1249 | --- 1250 | 1251 | ### 전역 컨텍스트와 함수 컨텍스트에서 VO가 가리키는 객체(내용)의 차이는? 1252 | 1253 | 전역 컨텍스트 (← 전역 코드 실행 시 생성됨) 1254 | 1255 | - 전역 객체(Global Object / GO)를 가리킨다. 1256 | 1257 | 전역 변수는 다음을 프로퍼티로 가진다. 1258 | 1259 | - 전역에 선언된 전역 변수 1260 | - 전역에 선언된 전역 함수 1261 | 1262 | 함수 컨텍스트 (← 함수를 실행할 때 생성됨) 1263 | 1264 | - 활성 객체(Activation Object / AO)를 가리킨다. 1265 | 1266 | 활성 객체는 다음 프로퍼티를 가진다. 1267 | 1268 | - 함수 코드에 선언된 지역 변수 1269 | - 함수 코드에 선언된 내부 함수 1270 | - parameter, arguments 정보를 담고 있는 arguments object 1271 | 1272 | --- 1273 | 1274 | ### 스코프 체인이란? 1275 | 1276 | 자신(EC)의 VO와, 자신의 상위 컨텍스트의 스코프의 VO를 차례대로 담고 있는 리스트 1277 | 1278 | --- 1279 | 1280 | ### 특정 EC의 스코프 체인에는 어떤 스코프가 담겨있나? 1281 | 1282 | ![JavaScript%20f07b25d7438e4d0ca94bbc0c3231bc62/Untitled%201.png](JavaScript%20f07b25d7438e4d0ca94bbc0c3231bc62/Untitled%201.png) 1283 | 1284 | - 가장 먼저 현재 EC의 AO(활성 객체) 1285 | - 순차적으로 자신의 상위 EC의 AO를 가리키며 1286 | - 마지막은 전역 객체(GO)를 가리킨다. 1287 | 1288 | > - 스코프 체인의 값은 (함수의 실행이 아닌) 함수의 선언 시점에 결정된다. 1289 | > - 상위 EC라 함은, 현재 실행되고 있는 함수가 선언된 EC를 말한다. 1290 | > - 즉, 스코프 체인은 현재 EC의 AO, 그리고 상위 EC의 AO, ..., 마지막으로 GO를 가리키게 된다. 1291 | 1292 | --- 1293 | 1294 | ### 변수를 검색하는 과정을 스코프 체인과 연관하여 설명해본다면? 1295 | 1296 | - 코드에서 변수를 참조하면, 엔진은 현재 EC의 스코프 체인의 첫번째 요소가 가리키는 AO에 접근해 변수를 검색한다. 1297 | - 검색에 실패하면, 리스트의 다음 요소가 가리키는 AO를 검색해 GO까지 내려간다. 1298 | - 만약 검색에 실패하면, 정의되지 않은 변수에 접근하는 것으로 판단하여 Reference 에러를 발생시킨다. 1299 | 1300 | > - 스코프 체인은 함수의 감춰진 프로퍼티 `[[Scope]]`로 참조된다. 1301 | > - `console.dir()`로 함수를 찍어보면 볼 수 있다. 1302 | 1303 | > - `console.log()`는 HTML 구조로 파라미터를 출력한다. (→ 인수의 내부 HTML 구조 등을 확인할 수 있다.) 1304 | > `console.dir()`는 JSON 구조로 파라미터를 출력한다. (→ 인수의 내부 메소드 등을 확인할 수 있다.) 1305 | 1306 | --- 1307 | 1308 | ### 실행 컨텍스트에 값이 채워지는 순서는? (실행 컨텍스트가 생성되는 순서는?) 1309 | 1310 | 1. 스코프 체인이 생성되고, 초기화 1311 | 1312 | 2. 변수 객체화(variable instantiation) 실행 1313 | 1314 | 3. this value 결정 1315 | 1316 | --- 1317 | 1318 | ### 변수 객체화가 진행되는 과정은? 1319 | 1320 | 1. (함수 컨텍스트인 경우) 매개변수가 (VO의) 프로퍼티로, 인수가 값으로 설정된다. 1321 | 1322 | 2. 대상 컨텍스트(코드) 내의 함수 선언을 대상으로, 함수명이 (VO의) 프로퍼티로, 생성된 함수 객체가 값으로 설정된다. 1323 | (→ 함수 호이스팅) 1324 | 1325 | 3. 대상 컨텍스트(코드) 내의 변수 선언을 대상으로, 변수명이 (VO의) 프로퍼티로, `undefined`가 값으로 설정된다. 1326 | (→ 변수 호이스팅) 1327 | 1328 | --- 1329 | 1330 | ### 클로저를 실행 컨택스트에 기반해 설명해본다면? 1331 | 1332 | - EC는 [스코프 체인 생성 및 초기화] → [변수 객체화] → [this 값 할당]의 순서로 진행된다. 1333 | - [변수 객체화] 단계에서, 가장 먼저 코드 내의 함수 선언을 대상으로, 함수명이 프로퍼티로, 생성된 함수 객체가 값으로 설정된다. 1334 | - 이때, 생성된 함수 객체는 `[[Scopes]]`라는 프로퍼티를 가진다. 1335 | - `[[Scopes]]`는 함수 객체가 실행되는 환경을 가리킨다. 1336 | - 즉, 현재 EC의 스코프 체인이 참조하고 있는 객체를 값으로 설정한다. 1337 | - ⇒ 내부 함수의 `[[Scopes]]`는 자신의 실행 환경과, 자신을 포함하는 외부 함수의 실행 환경, 그리고 전역 객체를 가리킨다. 1338 | - 이때, 자신을 포함하는 외부 함수의 EC가 소멸해도 `[[Scopes]]`의 프로퍼티가 가리키는 외부 함수의 실행 환경은 소멸하지 않고 참조할 수 있다. 이것이 클로저이다. 1339 | 1340 | --- 1341 | 1342 | ### 함수 호이스팅이란? 1343 | 1344 | 코드가 실행되기 이전에, 현재 EC의 스코프 체인이 가리키는 VO에 함수가 이미 등록되어 있기 때문에, 함수 선언식 코드에 닿기 이전에 함수를 호출할 수 있는 현상. 1345 | 1346 | > - 함수 선언식은 VO에 함수명을 프로퍼티로, 함수 객체를 (즉시) 값으로 할당한다. 1347 | > 반면, 함수 표현식은 일반 변수의 방식을 따른다. 따라서 함수 표현식 코드에 닿기 이전에 함수를 호출할 수 없다. 1348 | 1349 | --- 1350 | 1351 | ### 변수 호이스팅이란? 1352 | 1353 | - 변수 선언은 변수 객체화 단계에서 변수명이 프로퍼티로, `undefined`가 값으로 설정된다.(`var`로 선언된 변수의 경우에 그렇다.) 1354 | - 때문에 변수 선언 코드에 닿기 전에, 해당 변수를 참조할 수 있다. (`undefined`로) 이를 변수 호이스팅이라고 한다. 1355 | 1356 | > - 실제 값이 설정되는 것은 변수 선언 코드가 실행되는 시점이다. 1357 | > - `let`과 `const`는 변수 객체화 단계에서 변수명이 프로퍼티로 설정되나, 값은 초기화되지 않는다. 때문에 변수 선언 이전에 변수를 참조하면 `uninitialized` 에러가 발생한다. 1358 | 1359 | --- 1360 | 1361 | ## 호이스팅 1362 | 1363 | ### 호이스팅이란? 1364 | 1365 | 함수 내의 선언을 끌어올려서, 해당 함수 블록(`{}`)의 최상단에 선언하는 것. 1366 | 1367 | > - 실제로 코드가 끌어올려지는 것은 아니고, 자바스크립트 파서(parser)가 내부적으로 끌어올려 처리하는 것이다. 1368 | 1369 | --- 1370 | 1371 | ### 호이스팅의 대상은? 1372 | 1373 | `var` 변수 선언과 함수 선언. 1374 | 1375 | > - `var` 변수의 **할당**, `let` / `const` 변수 **선언**, 함수**표현식**은 호이스팅이 발생하지 않는다. 1376 | 1377 | --- 1378 | 1379 | ### 함수 선언문과 함수 표현식의 차이는? 1380 | 1381 | 함수 선언문 1382 | 1383 | ```jsx 1384 | function foo() { 1385 | // 함수 로직 1386 | } 1387 | ``` 1388 | 1389 | 함수 표현식 1390 | 1391 | ```jsx 1392 | const foo = function () { 1393 | // 함수 로직 1394 | }; 1395 | ``` 1396 | 1397 | --- 1398 | 1399 | ### 함수 선언문에 비해 함수 표현식이 가지는 장점은? 1400 | 1401 | 다른 함수의 인자로 넘길 수 있다. 1402 | 1403 | --- 1404 | 1405 | ### 호이스팅에서의 우선순위에 대해 설명해본다면? 1406 | 1407 | 1. 변수 선언이 함수 선언보다 위로 호이스팅된다. 1408 | 1409 | ```jsx 1410 | var myName = "shin"; 1411 | 1412 | function myName() {} 1413 | function yourName() {} 1414 | 1415 | var yourName = "lee"; 1416 | 1417 | console.log(typeof myName); // "string" 1418 | console.log(typeof yourName); // "string" 1419 | ``` 1420 | 1421 | 2. 값이 할당되어 있는 변수의 경우, 변수가 함수 선언을 덮어쓴다. 1422 | 3. 값이 할당되어 있지 않은 변수의 경우, 함수 선언이 변수를 덮어쓴다. 1423 | 1424 | ```jsx 1425 | var myName = "shin"; 1426 | var yourName; 1427 | 1428 | function myName() {} 1429 | function yourName() {} 1430 | 1431 | console.log(typeof myName); // "string" 1432 | console.log(typeof yourName); // "function" 1433 | ``` 1434 | 1435 | --- 1436 | 1437 | ### 호이스팅은 지향해야 할까, 지양해야 할까? 1438 | 1439 | 지양해야 한다. 1440 | 호이스팅은 코드의 가독성과 유지보수에 좋지 않다. 1441 | 1442 | --- 1443 | 1444 | ### 호이스팅을 방지하기 위한 방법은? 1445 | 1446 | - 함수와 변수를 코드의 상단부에 선언한다. 1447 | - `let` / `const`를 사용한다. 1448 | 1449 | --- 1450 | 1451 | ### 호이스팅을 지양해야 함에도 불구하고, var와 호이스팅을 이해해야 하는 이유는? 1452 | 1453 | 아직은 모든 환경에 ES6를 사용할 수 없어서 ES5로 트랜스파일링 해야 하기 때문에 var와 호이스팅에 대해 이해하고 있어야 한다. 1454 | 1455 | --- 1456 | 1457 | ## EcmaScript 1458 | 1459 | ### EcmaScript란? 1460 | 1461 | Ecma 인터내셔널이 스크립트 언어에 대해 규정해놓은 표준 중에 하나의 사양이다. 1462 | (ECMA → ECMA-262 → ECMAScript) 1463 | 1464 | - ECMA 인터내셔널은 정보 통신에 대한 표준을 제정하는 기구이다. 1465 | - ES6는 ECMA-262 표준의 제 6판을 지칭하는 말이다. 1466 | 1467 | --- 1468 | 1469 | ### ECMAScript와 JavaScript의 관계는? 차이점은? 1470 | 1471 | JavaScript는 ECMAScript 사양을 준수하는 스크립트 언어이다. 1472 | 1473 | --- 1474 | 1475 | ### ES6에서 추가된 문법에 대해 아는 것이 있는지? 1476 | 1477 | - let & const 1478 | - Class 1479 | - arrow function 1480 | - Promise 1481 | - 비구조화 할당 1482 | - template literal 1483 | 1484 | > - ES2015와 ES6는 같은 말이다. 1485 | 1486 | ## 기타 1487 | 1488 | ### 자바스크립트 배열도 객체일까? (배열의 내부 구조는?) 1489 | 1490 | 자바스크립트 배열은 특수한 종류의 `객체`이다. (배열의 본질은 객체이다) 1491 | 1492 | > - 대괄호로 접근(ex: `arr[0]`)은 객체로부터 기인했다. 다만 배열은 키가 숫자라는 점만 다르다. 1493 | > - 배열은 객체 기본 기능 이외에도, 순서가 있는 컬렉션을 제어할 수 있도록 해주는 특별한 메소드를 제공한다. (ex. 배열의 프로퍼티 `length`) 1494 | > - 배열은 내부의 특수한 표현 방식으로 인해 배열답게 기능한다. 자바스크립트 엔진은 배열의 요소를 인접한 메모리 공간에 차례대로 저장해 연산 속도를 높인다(ex. `push`, `pop`). 1495 | 1496 | --- 1497 | 1498 | ### use strict란? 1499 | 1500 | 파일 전체 또는 함수를 엄격한 운용 컨텍스트 안에서 실행할 수 있도록 한다. 1501 | 1502 | - 오류는 아니지만 의도치 않은 함정이 될 수 있는 코드에 대해 오류를 발생시킨다. 1503 | - JavaScript 엔진의 최적화를 방해하는 코드에 오류를 발생시킨다. 1504 | 1505 | 예를 들어, 1506 | 1507 | - 우발적인 전역 변수 선언을 방지한다. 1508 | `x = 3.14;` 1509 | (엄격 모드가 아니라면, 선언되지 않은 변수에 값을 할당하면 해당 이름의 전역 변수가 생성된다.) 1510 | -------------------------------------------------------------------------------- /network/Network 0208784d439545d2a6f93e6c5c4355bc/Untitled 1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heech1013/study-note/9c5d4ee9887aed616e24701a9a43b1cd53dcf6a4/network/Network 0208784d439545d2a6f93e6c5c4355bc/Untitled 1.png -------------------------------------------------------------------------------- /network/Network 0208784d439545d2a6f93e6c5c4355bc/Untitled 2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heech1013/study-note/9c5d4ee9887aed616e24701a9a43b1cd53dcf6a4/network/Network 0208784d439545d2a6f93e6c5c4355bc/Untitled 2.png -------------------------------------------------------------------------------- /network/Network 0208784d439545d2a6f93e6c5c4355bc/Untitled 3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heech1013/study-note/9c5d4ee9887aed616e24701a9a43b1cd53dcf6a4/network/Network 0208784d439545d2a6f93e6c5c4355bc/Untitled 3.png -------------------------------------------------------------------------------- /network/Network 0208784d439545d2a6f93e6c5c4355bc/Untitled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heech1013/study-note/9c5d4ee9887aed616e24701a9a43b1cd53dcf6a4/network/Network 0208784d439545d2a6f93e6c5c4355bc/Untitled.png -------------------------------------------------------------------------------- /network/Network 0208784d439545d2a6f93e6c5c4355bc/connection-termination.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heech1013/study-note/9c5d4ee9887aed616e24701a9a43b1cd53dcf6a4/network/Network 0208784d439545d2a6f93e6c5c4355bc/connection-termination.png -------------------------------------------------------------------------------- /network/Network 0208784d439545d2a6f93e6c5c4355bc/osi-vs-tcp-ip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heech1013/study-note/9c5d4ee9887aed616e24701a9a43b1cd53dcf6a4/network/Network 0208784d439545d2a6f93e6c5c4355bc/osi-vs-tcp-ip.png -------------------------------------------------------------------------------- /network/README.md: -------------------------------------------------------------------------------- 1 | # Network 2 | 3 | ## Table of Contents 4 | 5 | 일반 6 | 7 | - 주소창에 www.naver.com을 입력 후 접속했을 때의 무슨 일이 일어날까? 8 | 9 | OSI 7계층 10 | 11 | - OSI 7계층이란? 12 | - OSI 7계층이 필요한 이유는? 13 | - OSI 7계층과 TCP/IP 4계층을 비교해본다면? 14 | 15 | OSI Physical Layer(물리 계층, 1계층) 16 | 17 | - OSI Physical Layer란? 18 | 19 | OSI Data-link Layer(2계층) 20 | 21 | - OSI Data-link Layer란? 22 | - TCP/IP Network (Interface) layer(1계층)란? 23 | - 데이터 링크 계층의 주요 역할은? 24 | - 2계층에서 데이터가 hop-by-hop으로 전달된다는 것의 의미는 무엇일까? 25 | - 프레이밍이란? 26 | - 프레임의 구조(필드)는? 27 | - MAC 주소란? 28 | - MAC 주소와 IP 주소의 차이점은? 29 | - MAC 주소의 종류에는 어떤 것들이 있을까? 30 | - 스위치란? 31 | - 스위치의 포워딩 방식에 대해 설명해본다면? 32 | - MAC 주소 테이블이란? 33 | - MAC 주소 테이블이 동작하는 과정은? 34 | - LAN과 WAN의 차이점? 35 | - 접근 제어란? 36 | - 흐름 제어(Flow control)란? 37 | - 오류 제어란? 38 | - 이더넷이란? 39 | - 이더넷의 특징? 40 | - 이더넷의 장단점? 41 | 42 | OSI Network Layer(3계층) & TCP/IP Internet Layer(2계층) 43 | 44 | - OSI Network layer(TCP/IP Internet layer)란? 45 | - 라우터란? 46 | - 라우팅이란? 47 | - 정적 라우팅과 동적 라우팅이란? 48 | - 포워딩이란? 49 | - 포워딩 테이블이란? 50 | - 스위치와 라우터의 차이점은? 51 | - 스위치와 라우터의 공통점은? 52 | - AS(Autonomous System, 자치 시스템)란? 53 | - IP(Internet Protocol)란? 54 | - 네트워크에서 '신뢰성'이 의미하는 것은? 55 | - ICMP(Internet Control Message Protocol)란? 56 | - IP의 데이터그램 단편화(fragmentation)란? 57 | - IP 데이터그램 단편화/재조립에 사용되는 IP 헤더의 종류에는 어떤 것들이 있을까? 58 | - IPv6란? 59 | - ARP(Address Resolution Protocol)란? 60 | - ARP 테이블이란? 61 | - 같은 LAN 상에서의 전송에서 ARP가 진행되는 과정은? 62 | - DHCP(Dynamic Host Configuration Protocol, 동적 호스트 구성 프로토콜)란? 63 | - DHCP의 장단점? 64 | - DHCP에서 IP 주소를 할당 받으면 영원히 사용할 수 있을까? 65 | - DHCP가 ip주소를 임대해주는 절차? `보충` 66 | 67 | OSI Transport Layer(4계층) & TCP/IP Transport Layer(3계층) 68 | 69 | - Transport Layer란? 70 | - network layer(3계층)와 Transport Layer(4계층)와의 차이점은? 71 | - Transport Layer가 흐름 제어를 제공하는 방법? 72 | - 혼잡 제어(Congestion control란? 73 | - Transport Layer가 혼잡 제어를 제공하는 방법? 74 | - AIMD(합 증가/곱 감소)란? 75 | - Slow start(느린 시작)란? 76 | - Fast retransmit(빠른 재전송)이란? 77 | - Transport Layer가 오류 제어를 제공하는 방법은? 78 | 79 | TCP & UDP 80 | 81 | - TCP(Transmission Control Protocol)란? 82 | - UDP(User Datagram Protocol)란? 83 | - 연결형 서비스와 비연결형 서비스의 차이점은? 84 | - 데이터그램 방식과 가상 회선 방식이란? 85 | - 가상 회선 방식에서 논리적 연결이 설정되는 과정은? 86 | - 회선 구성 방식에는 어떤 것들이 있을까? 87 | - 전이중, 반이중, 단방향 방식에 대해 설명해본다면? 88 | - TCP와 UDP는 각각 어떤 특성의 서비스에 적합할까? 89 | - 3-way handshake의 과정에 대해 설명해본다면? 90 | - 4-way handshake의 과정에 대해 설명해본다면? 91 | - 왜 2-way handshake는 성립될 수 없을까? 92 | 93 | OSI Application Layer(응용 계층, 7계층) & TCP/IP Application Layer(4계층) 94 | 95 | - Application Layer란? 96 | 97 | DNS 98 | 99 | - DNS(Domain Name Server)란? 100 | - 도메인 네임(domain name)이란? 101 | - 도메인 네임의 구조? 102 | - DNS에서 도메인을 얻어오는 과정은? 103 | - PC는 local DNS의 ip 주소를 어떻게 알고 있을까? 104 | - DNS의 구성 요소는? 105 | - 도메인 네임 스페이스란? 106 | - 네임 서버란? 107 | - 네임 서버의 종류는? 108 | - resolver란? 109 | - DNS가 사용하는 전송 계층(Transport Layer)의 프로토콜은? 110 | - DNS에 UDP를 사용하는 이유? 111 | 112 | 로드 밸런싱(Load Balancing) 113 | 114 | - 트래픽이 증가해 기존의 컴퓨팅 자원으로 서비스할 수 없을 때, 대처할 수 있는 2가지 방법은? 115 | - 로드 밸런싱이란? 116 | - 로드 밸런싱 알고리즘에 대해 설명해본다면? 117 | - 각 계층의 로드 밸런서에 대해 설명해본다면? 118 | 119 | --- 120 | 121 | ## 일반 122 | 123 | ### 주소창에 www.naver.com을 입력 후 접속했을 때의 무슨 일이 일어날까? 124 | 125 | 브라우저는 주소의 도메인 네임에 대응되는 IP 주소를 탐색한다. 126 | 127 | > - 도메인 네임: 인터넷 상에서 컴퓨터를 식별하는 호스트명. 1, 2, 3단계 도메인으로 구성되어 있으며 왼쪽으로 갈수록 범위가 좁아진다. (www.naver.com의 경우 `www`는 3단계 도메인, `naver`가 2단계 도메인, `com`이 1단계 도메인에 해당한다.) 128 | 129 | - 브라우저는 먼저 여러 캐시로부터 DNS 기록이 있는지 확인을 한다. 130 | 131 | > 1. 브라우저 캐시: 브라우저는 일정 기간 동안 DNS 기록을 저장하고 있다. 132 | > 2. OS 캐시: OS가 저장하고 있는 DNS 기록 133 | > 3. router 캐시: DNS 기록을 캐싱하고 있는 라우터와 통신 134 | > 4. ISP 캐시: ISP(Internet Service Provider)는 인터넷 접속 서비스를 제공하는 회사를 말한다. ISP는 각자의 local DNS 서버를 구축하고 있으며, DNS 기록을 캐싱하고 있다. 135 | 136 | > - 캐시는 네트워크 트래픽을 조절하고, 데이터 통신 시간을 줄이기 위해 매우 중요하다. 137 | > - OS는 DHCP(Dynamic Host Configuration Protocol)를 통해 자신의 ip 주소, 가장 가까운 라우터의 ip 주소, 가장 가까운 DNS 서버의 ip 주소를 알고 있다. PC가 최초 인터넷 접속을 시도할 때 DHCP가 수행된다. 138 | 139 | - 캐싱된 DNS가 없을 경우, DNS query를 날려 DNS를 얻어낸다. 140 | > - 캐싱된 DNS 기록이 없을 경우 ISP의 local DNS 서버가 DNS query를 날리게 된다. 141 | > - DNS query의 목적은 여러 다른 DNS 서버를 검색해서 DNS에 대응하는 IP 주소를 찾는 것이다. DNS query는 recursive search 방식으로 진행되는데, IP 주소를 찾거나 오류가 발생할 때까지 반복적으로 DNS 서버를 이동해가며 검색을 진행한다는 의미이다. recursive search를 보내는 출발점인 ISP의 local DNS 서버는 DNS recursor라 불리우고, 다른 DNS들은 name server라고 불린다. 142 | > - name server인 다른 DNS들은 도메인 네임 구조에 기반해 검색을 진행한다. 143 | > -DNS recursor는 최초에 root name server에 쿼리를 보낸다. 144 | > -root name server는 `.com` name server에 쿼리를 redirect한다. 145 | > -`.com` name server는 `naver.com` name server로, 146 | > -`name.com` name server는 `www.naver.com` name server로 쿼리를 redirect한다. 147 | > -`www.naver.com` name server는 매칭되는 IP 주소를 찾아 DNS recursor로 전송한다. 148 | 149 | 브라우저와 서버가 TCP connection을 맺는다. 150 | 151 | > - HTTP 요청의 경우 일반적으로 TCP를 사용한다. 152 | 153 | - TCP의 3-way handshake 프로세스를 통해 연결을 맺는다. 154 | > - 클라이언트가 서버에게 SYN 패킷을 보내, TCP 연결 요청을 보낸다. 155 | > - 서버는 클라이언트에게 SYN/ACK 패킷을 보내, 요청을 수락함과 동시에 클라이언트도 연결 포트를 열어줄 것을 요청한다. 156 | > - 클라이언트는 서버에게 ACK 패킷을 보내, 최종적으로 연결을 수립한다. 157 | 158 | 브라우저가 서버에 HTTP 요청을 보낸다. 159 | 160 | - HTTP 프로토콜에 따라 요청 메시지가 생성된다. 161 | - TCP/IP 프로토콜에 따라 Applcation Layer, Transport Layer, Internet Later, Network Layer를 거쳐 최종 메시지가 생성된다. 162 | 163 | 서버는 HTTP 요청을 받고, 응답을 보낸다. 164 | 165 | - 서버는 TCP/IP 프로토콜과 HTTP 프로토콜에 기반해 메시지를 해석한다. 166 | - 클라이언트와 같은 방식으로 HTTP 응답 메시지를 생성해 전송한다. 167 | 168 | 브라우저는 서버로부터 응답 메시지를 받고, 해당 내용을 렌더링한다. 169 | 170 | > - 브라우저는 데이터를 렌더링하기 위해 parsing -> style -> layout -> paint -> composite의 과정을 거친다. 171 | 172 | ## OSI 7계층 173 | 174 | ### OSI 7계층이란? 175 | 176 | - 네트워크 프로토콜 디자인을 계층으로 나누어 설명한 것. 177 | - Physical Layer, Data-link Layer, Network Layer, Transport Layer, Session Layer, Presentation Layer, Application Layer로 구성되어 있다. 178 | 179 | --- 180 | 181 | ### OSI 7계층이 필요한 이유는? 182 | 183 | - 통신이 일어나는 과정을 단계별로 파악할 수 있다. 184 | - 이상이 생겼을 때, 다른 단계의 장비나 소프트웨어를 건드리지 않고 이상이 생긴 단계의 모듈만 고치면 된다. 185 | 186 | --- 187 | 188 | ### OSI 7계층과 TCP/IP 4계층을 비교해본다면? 189 | 190 | ![Network%200208784d439545d2a6f93e6c5c4355bc/osi-vs-tcp-ip.png](Network%200208784d439545d2a6f93e6c5c4355bc/osi-vs-tcp-ip.png) 191 | 192 | > tcp/ip는 osi보다 먼저 개발되었고, osi는 실제 개발된 사례가 많이 없어서 신뢰도가 떨어지는 반면, tcp/ip는 계속적으로 실제 개발되고, 발전되면서 실질적인 표준이 되었다. 193 | 194 | --- 195 | 196 | ## OSI Physical Layer(물리 계층, 1계층) 197 | 198 | ### OSI Physical Layer란? 199 | 200 | 물리적으로 연결된 두 대의 컴퓨터가 디지털 신호를 주고 받도록 해주는 모듈. 201 | 202 | > - 물리 계층은 미디어 타입, 신호 표현 방법, 속도 등을 몀시한다. 203 | > - 물리 계층의 PDU(Protocol Data Unit)는 비트(bit)이다. 204 | > - 물리 계층은 두 대의 컴퓨터가 통신할 수 있도록 해주지만, 여러 대의 컴퓨터가 통신할 수는 없다. 205 | > - 물리 계층은 하드웨어의 PHY칩에 구현되어 있다. 206 | 207 | > 아날로그 신호와 디지털 신호의 차이점 208 | > 209 | > - 아날로그 신호: 연속된 값을 가진다. 210 | > - 디지털 신호: 비연속적 값(= 0과 1)을 가진다. 211 | 212 | --- 213 | 214 | ## OSI Data-link Layer(2계층) 215 | 216 | ### OSI Data-link Layer란? 217 | 218 | - "직접 연결된(인접한)" 서로 다른 2개의 네트워킹 장치 간의 데이터 전송을 담당하는 모듈. 219 | - 물리 계층으로부터 받은 데이터가 네트워크 장치에 올바르게 안착될 수 있도록 하는 역할을 한다. 220 | 221 | > - data-link layer의 PDU은 프레임(Frame)이다. 222 | > - 어느 방향으로 가야 하는지는 상위 프로토콜(네트워크 계층)이 책임진다. 데이터링크 계층은 상위 프로토콜이 가리키는 곳으로 데이터를 전송할 뿐이다. 223 | > - LAN에서 데이터를 주고 받기 위해 필요하다. 224 | 225 | --- 226 | 227 | ### TCP/IP Network (Interface) layer(1계층)란? 228 | 229 | - 물리적 연결을 포함해, "직접 연결된(인접한)" 서로 다른 2개의 네트워킹 장치 간의 데이터 전송을 담당하는 모듈. 230 | 231 | > - TCP/IP의 network layer는 OSI physical layer와 data-link layer에 해당한다. 232 | > - network layer의 PDU은 프레임(Frame)이다. 233 | 234 | --- 235 | 236 | ### 데이터 링크 계층의 주요 역할은? 237 | 238 | - 프레이밍(Framing) 239 | - 물리 주소(MAC) 지정 240 | - 접근 제어 / 흐름 제어 / 오류 제어 제공 241 | 242 | --- 243 | 244 | ### 2계층에서 데이터가 hop-by-hop으로 전달된다는 것의 의미는 무엇일까? 245 | 246 | (종단에서 종단으로 데이터가 한번에 직접 전달되는 것이 아니라) 두 종단 사이에 존재하는 라우터들을 거치며 점진적으로 전달이 된다는 의미이다. 247 | 248 | > IP 주소간의 통신은 각 라우터 hop에서 일어나는 MAC 주소와 MAC 주소 통신의 연속적인 과정이다. 249 | 250 | --- 251 | 252 | ### 프레이밍이란? 253 | 254 | 네트워크 계층으로부터 전달 받은 데이터그램을 캡슐화하는 작업. 255 | 256 | --- 257 | 258 | ### 프레임의 구조(필드)는? 259 | 260 | - 출발지 MAC 주소/ 목적지 MAC 주소 261 | - data: 실제 전송되는 데이터. 262 | - length / type: 데이터 필드 길이나 프로토콜 종류를 나타냄 263 | - SOF(Start of Frame): 10101011의 값을 가짐. 프레임의 시작을 알린다. 264 | - Frame Check Sequence: 에러 발생 여부를 확인하기 위한 필드. 265 | - Preemble: 10101010이 반복되는 필드. 수신측에서 프레임이 전송된다는 것을 알리고, 곧 도착할 프레임에서 0과 1을 제대로 구분할 수 있도록 동기 신호를 제공하는 것. 266 | 267 | --- 268 | 269 | ### MAC 주소란? 270 | 271 | 랜 카드(또는 네트워크 인터페이스 카드(NIC))에 할당되는 고유한 식별자 주소. 272 | 273 | > - 데이터 링크 계층에서 통신을 위해 사용된다. 274 | > - 모든 네트워크 장비(라우터, 스위치 등)가 지니고 있다. 275 | > - 48비트(00:00:00:00:00:00 꼴) 276 | > - '물리 주소', '하드웨어 주소'라고도 불린다. 277 | 278 | --- 279 | 280 | ### MAC 주소와 IP 주소의 차이점은? 281 | 282 | - IP 주소: 최종 목적지의 '논리적' 주소. 283 | - MAC 주소: 최종 목적지까지 가기 위해 거쳐가야 하는 경로 상, 바로 다음 라우터의 '물리적' 주소. 284 | 285 | > - 앨리스가 밥에게 데이터를 전송할 때, IP는 밥의 컴퓨터의 IP 주소를 나타낼 것이고 MAC 주소는 바로 다음 라우터의 MAC 주소를 나타낼 것이다. 286 | 287 | --- 288 | 289 | ### MAC 주소의 종류에는 어떤 것들이 있을까? 290 | 291 | 수신자가 몇 개인지에 따라 3종류로 나뉜다. 292 | 293 | 1. Unicast 294 | 295 | - `1 : 1` 통신을 의미. 296 | - (L2 계층에서) Framing을 할 때 unicast address를 넣으면 해당 MAC 주소를 가진 곳으로만 간다. 297 | 298 | 2. multicast 299 | 300 | - `1 : 다` 통신을 의미. 301 | - 특정 관할 구역에서 제한적으로 사용됨. 302 | 303 | 3. broadcast 304 | 305 | - `1 : 전체` 통신을 의미. 306 | - broadcast address를 담은 frame은 (네트워크에 연결된) 모든 기기에 전달된다. 307 | 308 | > 일반적으로 broadcast address는` FF:FF:FF:FF:FF:FF`이다. 309 | 310 | --- 311 | 312 | ### 스위치란? 313 | 314 | 같은 네트워크 내에서 데이터를 전달하는 역할을 하는 네트워크 장치. 315 | 316 | - 프레임을 수신하면, MAC 테이블을 참조해 어떤 포트로 프레임을 보낼지 결정한다. 317 | 318 | > - 스위치는 데이터링크 계층에서 사용되는 대표적인 장비이다. 319 | 320 | --- 321 | 322 | ### 스위치의 포워딩 방식에 대해 설명해본다면? 323 | 324 | 1. cut-through 325 | 326 | - 프레임 전체를 확인하지 않고, 수신되는 프레임의 목적지 MAC 주소만 확인해서 목적지 포트로 프레임을 전송하는 방식 327 | - 장점: 전송 대기 시간을 최소화하는 방식이다. 328 | - 단점: 프레임의 에러를 제거할 수 있는 기능을 지원하지 않는다. 329 | 330 | > - cut-through 방식은 에러가 발생한 프레임이 수신되었을 경우, 이를 폐기시킨 후 재전송될 프레임을 기다린다. 331 | 332 | 2. store-and-forward 333 | 334 | - 하나의 프레임을 수신할 때 프레임 전체를 확인해 에러를 체크한 후에 목적지 포트로 전송하는 방식. 335 | - 장점: 에러를 체크하기 때문에 신뢰도가 높다. 336 | - 단점: 비교적 속도가 느리고 오버헤드가 든다. 337 | 338 | > 데이터 링크 계층에서의 오류는 통신 회선의 순간적인 절단, 통신 회선의 잡음과 혼선, 지연, 장치의 기계적 원인, 전원 중단 등의 원인으로 발생할 수 있다. 339 | 340 | --- 341 | 342 | ### MAC 주소 테이블이란? 343 | 344 | 목적지 MAC 주소와, 해당 MAC 주소로 가기 위한 포트 번호가 기록된 테이블. 345 | 346 | > - 프레임의 목적지 MAC 주소와 포트 번호를 캐싱하기 위해 사용된다. 347 | 348 | --- 349 | 350 | ### MAC 주소 테이블이 동작하는 과정은? 351 | 352 | - 스위치가 프레임을 수신하면, 프레임의 목적지 MAC 주소를 확인한다. 353 | - MAC 주소 테이블에 해당 MAC 주소가 존재하면, 매칭되는 포트로 프레임을 전송한다. 354 | - 만일 MAC 주소가 존재하지 않는다면, ARP 프로토콜을 통해 MAC 주소를 알아낸 후 해당하는 포트로 전송한다. 355 | - 알아낸 MAC 주소와 포트 정보를 MAC 주소 테이블에 추가한다. 356 | 357 | > - 스위치의 MAC 주소 테이블은 자동으로 동작한다. 프레임이 스위치를 거치면 해당 MAC 주소와 포트가 맥 주소 테이블에 등록이 된다. 358 | > - 맥 주소 테이블의 entry는 시간이 지나면 삭제가 된다. (default 300초) 359 | 360 | --- 361 | 362 | ### LAN과 WAN의 차이점? 363 | 364 | LAN(Local Area Network, 근거리 통신망) 365 | 366 | - 지역 네트워크 367 | 368 | > - LAN은 ARP Request 패킷이 도달하는 범위의 기준이기도 하다. 369 | 370 | WAN(Wide Area Network, 원거리 통신망) 371 | 372 | - 광범위한 지역 단위로 LAN과 LAN을 연결하는 네트워크. 373 | 374 | --- 375 | 376 | ### 접근 제어란? 377 | 378 | 여러 장비가 하나의 링크(매체)를 공유해 다중 접속되어 있는 경우, 여러 장비에서 발생한 신호로 인해 충돌이 발생한다. 이러한 충돌을 최소화하고, 충돌이 발생했을 경우 대응하는 것을 말한다. 379 | 380 | > 접근 제어를 제공하는 기능으로는 대표적으로 CSMA/CD가 있다. 381 | > 382 | > CSMA/CD란? 383 | > 384 | > - CS(Carrier Sense), MA(Multiple Access) 385 | > 386 | > - 다른 장비가 통신 중인지를 미리 확인해서 충돌을 최소화하는 기능. 387 | > - 공유 매체에 아무런 전기 신호가 발생하지 않으면 데이터 전송을 시도한다. 다른 장비가 사용 중이면 잠시 기다렸다가 전송을 시도한다. 388 | > 389 | > - CD(Collision Detect) 390 | > 391 | > - 충돌이 일어났을 때 대처하는 기능. 392 | > - 충돌이 감지되면 연결된 모든 장비에게 Signal을 전달하여 충돌이 발생했음을 알린다. 신호를 받은 장비들은 랜덤한 시간을 기다렸다가 재전송을 한다. 393 | 394 | --- 395 | 396 | ### 흐름 제어(Flow control)란? 397 | 398 | 송신측이 수신측의 처리 속도보다 더 빨리 데이터를 보내지 않도록 제어해주는 것. 399 | 400 | - 데이터 링크 계층에서는 송신측의 최고 전송 속도와 수신측의 최고 처리 속도를 서로 공유하여, 더 낮은 속도에 두 노드가 속도를 맞춤으로써 흐름 제어를 제공한다. 401 | 402 | > 데이터 링크 계층의 흐름 제어는 노드 대 노드 간의 흐름 제어를, 403 | > 전송 계층의 흐름 제어는 종단 간의 흐름을 제어한다. 404 | 405 | --- 406 | 407 | ### 오류 제어란? 408 | 409 | 데이터 전송 시 발생한 오류를 복원하거나 재전송하는 것. 410 | 411 | - 데이터 링크 계층에서의 오류 제어는 '오류 검출'과 '재전송' 과정으로 구성된다. 412 | - 수신측에서 오류를 검출하고, 오류가 발생하면 송신측에서 해당 패킷을 재전송한다. 413 | - 송신측은 타이머와 ACK 패킷 등으로 오류 발생 여부를 알 수 있다. 414 | 415 | --- 416 | 417 | ### 이더넷이란? 418 | 419 | LAN에서 사용하기 위해 개발된 유선 통신망 기술. 420 | 421 | > 이더넷(Ethernet)은 데이터 링크 계층의 대표적인 프로토콜이다. 422 | 423 | --- 424 | 425 | ### 이더넷의 특징? 426 | 427 | - 비연결형 서비스: 송신 - 수신 노드 사이에 handshake가 없다. 428 | - 비신뢰적 서비스: 수신 노드는 송신 노드에게 ACK을 보내지 않는다. 429 | - CSMA/CD 지원 430 | 431 | --- 432 | 433 | ### 이더넷의 장단점? 434 | 435 | 장점 436 | 437 | - 적은 용량의 데이터를 전송할 경우 성능이 우수하다. (하나의 링크를 여러 노드가 공유하고 있기 때문이다.) 438 | - 설치 비용이 저렴하고 관리가 쉽다. 439 | 440 | 단점 441 | 442 | - 네트워크 사용시 충돌이 발생하며, 충돌로 인해 지연이 발생한다. 443 | 444 | --- 445 | 446 | ## OSI Network Layer(3계층) & TCP/IP Internet Layer(2계층) 447 | 448 | ### OSI Network layer(TCP/IP Internet layer)란? 449 | 450 | - 데이터 전송 과정에서 라우팅(routing)과 포워딩(forwarding)을 통해 전송 경로를 결정해주는 모듈. 451 | - 데이터를 종단 목적지까지 가장 안전하고 빠르게 전달하는 기능을 한다. 452 | 453 | > 3계층의 PDU는 '패킷'이다. 454 | 455 | --- 456 | 457 | ### 라우터란? 458 | 459 | - LAN과 LAN을 연결해주는 장치. 460 | - 수신된 패킷을 라우팅하는 역할을 한다. 461 | 462 | > 라우터는 네트워크 계층에서 사용되는 대표적인 장비이다. 463 | 464 | --- 465 | 466 | ### 라우팅이란? 467 | 468 | 라우팅 알고리즘을 통해 최적의 경로를 얻어내어, 데이터를 목적지까지 전송하는 것. 469 | 470 | --- 471 | 472 | ### 정적 라우팅과 동적 라우팅이란? 473 | 474 | 정적 라우팅(static routing): 관리자가 수동으로 router에 필요한 정보를 입력해주는 라우팅 방식. 475 | 476 | - 장점: 라우터의 직접적인 처리 부하가 감소한다. 477 | - 단점: 네트워크 변화에 대응할 수 없음 → 관리자가 지속적으로 업데이트해주어야 한다. 478 | 479 | 동적 라우팅(dynamic routing): 라우팅 알고리즘을 통해 경로 설정이 자동으로 진행되는 라우팅 방식. 480 | 481 | - 장점: 네트워크 환경이 변화해도 능동적인 대처가 가능하다. 482 | - 단점: 네트워크 환경 변화 시 경로 재설정 → 처리부하 증가 → 지연 발생 483 | 484 | --- 485 | 486 | ### 포워딩이란? 487 | 488 | 라우터에서 입력 포트로 수신한 패킷을 목적지에 맞게 적절한 출력 포트로 패킷을 이동시키는 것. 489 | 490 | --- 491 | 492 | ### 포워딩 테이블이란? 493 | 494 | - 수신된 패킷의 정보와, 패킷이 최적의 경로로 전송될 수 있는 출력 포트가 기록된 테이블. 495 | - 라우팅을 통해 entry가 채워진다. 496 | 497 | --- 498 | 499 | ### 스위치와 라우터의 차이점은? 500 | 501 | 스위치 502 | 503 | - 같은 네트워크 내에서 데이터의 목적지를 확인해 전달하는 역할 504 | 505 | 라우터 506 | 507 | - 스위치와 스위치를 연결해서, 서로 다른 네트워크에 속한 컴퓨터끼리 통신이 가능하게 해주는 역할 508 | 509 | --- 510 | 511 | ### 스위치와 라우터의 공통점은? 512 | 513 | 1. 저장 후 전달(store-and-forward) 514 | 515 | - 스위치: 데이터 링크 계층 헤더(frame header) 조사 516 | - 라우터: 네트워크 계층 헤더(ip header) 조사 517 | 518 | 2. 테이블 관리 519 | 520 | - 스위치: MAC 주소 테이블과 ARP 테이블 관리 521 | - 라우터: 포워딩 테이블과 ARP 테이블 관리 522 | 523 | --- 524 | 525 | ### AS(Autonomous System, 자치 시스템)란? 526 | 527 | 하나의 네트워크 관리자에 의해 관리되는 라우터 집단. 528 | 529 | - 같은 AS 내의 라우터들은 infra-AS routing protocol로서 같은 라우팅 알고리즘을 가진다. 530 | - 다른 AS의 라우터들은 서로 다른 infra-AS routing protocol을 가질 수 있다. 531 | 532 | 필요한 이유: 전세계 수많은 호스트를 독립적인 영역으로 나눔으로써 관리와 확장이 용이하도록 하기 위함. 533 | 534 | > gateway router란? 535 | > 536 | > - 다른 AS의 라우터에 직접 연결된 라우터. 537 | > - 내부 AS에서 외부 목적지 AS로 패킷을 전달하는 역할. 538 | 539 | --- 540 | 541 | ### IP(Internet Protocol)란? 542 | 543 | 패킷의 IP 주소 부분을 처리해서 목적지까지 도달할 수 있도록 도와주는 프로토콜. 544 | 545 | - best effort service: 데이터그램의 전송을 위해 최선의 노력을 하지만, 신뢰성을 보장하지 않음. (즉, 패킷을 송신하기는 하지만 그 패킷이 도착할 것이라는 보장은 없다.) 546 | - 비연결형 서비스 547 | 548 | > - IP는 network layer의 대표적인 프로토콜 중 하나이다. 549 | > - _연결형 서비스와 비연결형 서비스의 차이점은?_ 참고 550 | 551 | --- 552 | 553 | ### 네트워크에서 '신뢰성'이 의미하는 것은? 554 | 555 | - 네트워크에서 데이터 전송 간 문제가 발생해도 사용자가 이를 느끼지 못하도록 조치해 서비스를 계속할 수 있는 능력. 556 | - 즉, 오류 제어와 흐름 제어를 제공하면 신뢰성을 제공하는 것이다. 557 | 558 | --- 559 | 560 | ### ICMP(Internet Control Message Protocol)란? 561 | 562 | - IP 패킷을 처리할 때 발생되는 문제를 알려주는 프로토콜 563 | - IP의 비신뢰성을 보완하기 위한 방법이다. 564 | 565 | > (배경) 566 | > 567 | > - IP는 best effort service로, 패킷을 목적지에 전송하기 위해 최선의 노력을 하지만 어떤 문제로 인해 도착하지 않았을 때 출발지 호스트에서 알 수 있는 방법이 없다. 568 | > - 이렇게 패킷이 제대로 도착하지 않았을 경우를 보완할 수 있는 것이 ICMP이다. 569 | 570 | > ICMP는 에러 상황(목적지에 해당하는 호스트가 없을 때, 해당 포트에 대기 중인 서버가 없을 때 등)이 발생한 경우 IP 헤더에 기록된 출발지 호스트로 에러에 대한 상황을 보내주는 역할을 한다. 571 | 572 | > ICMP에서 사용하는 에러 메시지의 종류 573 | > 574 | > - Destination Unreachable: 목적지에 도달하지 못함 575 | > - Time Exceeded: 시간이 오래 걸려 목적지에 도달하지 못함 576 | 577 | --- 578 | 579 | ### IP의 데이터그램 단편화(fragmentation)란? 580 | 581 | 단편화 582 | 583 | - MTU보다 큰 데이터그램을 더 작은 크기로 분할하는 과정 584 | 585 | > MTU(Maximum Transmission Unit) 586 | > 587 | > - 최대 전달 크기 588 | > - MTU보다 큰 데이터그램은 전송 불가. 589 | > 590 | > - MTU는 정확히는 링크 계층(Link layer / Physical + Data-link layer)의 프레임이 최대로 전달할 수 있는 데이터의 양이다. 링크 계층은 IP 데이터그램을 링크 계층의 프레임 안으로 캡슐화하므로, IP 데이터그램의 길이에 엄격한 제한을 두는 것이다. 591 | > - 단편화를 거쳐 데이터그램이 수신지에 도착하면, 수신자가 데이터그램을 재조립(reassembly)하는 과정을 거친다. 592 | 593 | --- 594 | 595 | ### IP 데이터그램 단편화/재조립에 사용되는 IP 헤더의 종류에는 어떤 것들이 있을까? 596 | 597 | `Frag` 598 | 599 | - 데이터그램이 단편화된 상태를 나타냄. 600 | 601 | `Fragment Offset` 602 | 603 | - 단편화 되기 전 데이터의 시작점으로부터의 거리(차이) 604 | 605 | `Total Length` 606 | 607 | - 헤더와 데이터 길이를 합한 길이 608 | 609 | `Identification` 610 | 611 | - 데이터그램이 단편화되어 전송된 후, 재조립 시 사용됨. 612 | 613 | --- 614 | 615 | ### IPv6란? 616 | 617 | IPv4의 주소 부족 문제를 해결하기 위해 등장한 주소체계. 618 | 619 | > IPv4는 32비트로 표현되는 주소체계로, 약 43억개의 주소 밖에 표현할 수 없다. 620 | 621 | 특징 622 | 623 | - 확장된 주소 공간: 128비트 주소 체계 사용 624 | - 주소 설정이 자동화: 기존 IPv4에서 DHCP 등으로 이뤄졌던 host configuration이 자동화됨. (기존 네트워크 관리자로부터 IP 할당 → IPv6 네트워크 접속 시 자동으로 주소 할당) 625 | - 보안 기능이 기본 제공: IP 수준에서의 보안에 대한 지원이 별도의 프로그램 없이 IPv6의 확장 헤더를 통해 수행됨. 626 | 627 | > 기타 628 | > 629 | > - QoS를 지원한다: IPv6의 Flow Label이라는 필드를 사용 630 | > - IPv6는 고정된 헤더 크기를 가진다. (↔ IPv4: 가변 헤더 크기) 631 | > - IPv6는 단편화를 허용하지 않는다. 점보그램 옵션을 사용하면 임의의 큰 패킷을 주고 받을 수 있게 된다. 632 | > - IPv4의 필요 없는 체크섬을 제거했다. 633 | 634 | > QoS(Quality of Service): 데이터 전송에 있어서 응용 프로그램, 사용자, 데이터 흐름 등에 우선 순위를 정해 특정 수준의 성능을 보장하는 서비스. 635 | 636 | --- 637 | 638 | ### ARP(Address Resolution Protocol)란? 639 | 640 | (네트워크 상에서) IP 주소를 MAC 주소에 대응시키기 위한 프로토콜. 641 | 642 | > - network layer에 속하는 프로토콜이다. 643 | 644 | > 데이터 통신에 ARP가 필요한 이유는? 645 | > 646 | > 일반적으로 통신을 위해 필요한 값들은 사용자가 결정해 입력해준다. 예를 들어, 647 | > 648 | > - transport layer에 필요한 포트 번호는 어플리케이션을 동작시키면서 입력된다. 649 | > - network layer에 필요한 ip 주소는 사용자가 주소를 입력하면서 encapsulation된다. 650 | > 651 | > 그러나, data-link layer에서 필요한 물리 주소는 따로 입력이 되지 않아 디바이스 스스로 주소를 결정해주어야 한다. 이때 사용되는 프로토콜이 ARP 프로토콜이다. 652 | 653 | --- 654 | 655 | ### ARP 테이블이란? 656 | 657 | IP 주소와 MAC 주소가 일대일로 매칭되어 있는 테이블. 658 | 659 | > - ARP 테이블은 LAN 상의 모든 노드(호스트, 라우터, 즉 네트워크 통신이 가능한 모든 장비)가 가지고 있다. 660 | > - ARP 테이블의 plug-and-play: 시스템 관리자의 개입 없이도 자동으로 구축됨. 661 | 662 | --- 663 | 664 | ### 같은 LAN 상에서의 전송에서 ARP가 진행되는 과정은? 665 | 666 | 1. 노드 A에서 노드 B로 데이터그램을 전송한다. 667 | 668 | - (A의 ARP 테이블에 B의 MAC 주소 엔트리가 아직 없다.) 669 | 670 | 2. A는 ARP 질의 패킷을 broadcast로 전송한다. 671 | 672 | - 질의 패킷의 MAC 주소는 모든 byte가 F로 설정된 broadcast 주소이며, B의 IP 주소를 포함하고 있다. 673 | - LAN 상의 모든 노드가 질의 패킷을 수신한다. 674 | 675 | 3. 그 중 질의 패킷을 수신한 B는 응답 패킷을 A에게 unicast한다. 676 | 677 | - 응답 패킷에는 B의 MAC 주소가 포함. 678 | 679 | 4. A는 ARP 테이블에 B의 IP와 MAC 주소를 저장한다. 680 | 681 | --- 682 | 683 | ### DHCP(Dynamic Host Configuration Protocol, 동적 호스트 구성 프로토콜)란? 684 | 685 | 호스트의 IP 주소와 각종 TCP/iP 통신에 필요한 기본 설정을 클라이언트에게 자동으로 제공해주는 프로토콜. 686 | 687 | - DHCP 서버는 네트워크 통신에 사용되는 IP 주소를 중앙에서 관리하고, 688 | - DHCP 지원을 받는 클라이언트는 네트워크 통신 설정 과정에서 DHCP 서버에 IP 주소를 요청하고 이를 얻을 수 있다. 689 | 690 | --- 691 | 692 | ### DHCP의 장단점? 693 | 694 | 장점 695 | 696 | - 알아서 네트워크 통신에 필요한 설정을 해주기 때문에 효율적이고 편리하다. 697 | - 중앙에서 IP를 관리하기 때문에 IP 충돌을 막을 수 있다. 698 | 699 | 단점 700 | 701 | - DHCP 서버에 의존 → 다운되면 IP 할당이 이뤄지지 않는다. 702 | 703 | --- 704 | 705 | ### DHCP에서 IP 주소를 할당 받으면 영원히 사용할 수 있을까? 706 | 707 | 아니다. DHCP는 IP 주소를 '임대'해준다. 708 | 709 | - DHCP 서버가 클라이언트에 IP 주소를 할당할 때 임대 기간을 명시한다. 클라이언트는 해당 기간동안만 IP 주소를 사용할 수 있다. 710 | - 만약 해당 IP 주소를 더 사용하고자 한다면 'IP 주소 임대기간 연장'을 DHCP 서버에 요청한다. 711 | - IP 주소가 더 이상 필요하지 않다면 'IP 주소 반납 절차'를 수행한다. 712 | 713 | --- 714 | 715 | ### DHCP가 ip주소를 임대해주는 절차? `보충` 716 | 717 | [https://velog.io/@hidaehyunlee/더-편리한-인터넷을-위해-DHCP-DNS-프로토콜](https://velog.io/@hidaehyunlee/%EB%8D%94-%ED%8E%B8%EB%A6%AC%ED%95%9C-%EC%9D%B8%ED%84%B0%EB%84%B7%EC%9D%84-%EC%9C%84%ED%95%B4-DHCP-DNS-%ED%94%84%EB%A1%9C%ED%86%A0%EC%BD%9C) 718 | 719 | --- 720 | 721 | ## OSI Transport Layer(4계층) & TCP/IP Transport Layer(3계층) 722 | 723 | ### Transport Layer란? 724 | 725 | 프로세스 간 논리적 통신을 제공하는 모듈. 726 | 727 | - 흐름 제어와 오류 제어를 통해 신뢰성 있는 전송을 지원한다. 728 | 729 | > - Transport layer는 흐름 제어, 혼잡 제어, 오류 제어를 제공한다. 730 | > - Trasport layer에서 논리적 연결이 성립되는 과정: "_가상회선 방식에서 논리적 연결이 성립되는 과정_" 참고 731 | 732 | > Data-link Layer와 Transport Layer 모두 오류 제어와 흐름 제어를 제공하는데, 둘의 차이점은 733 | > 734 | > - data-link layer는 물리적 연결에 대한 오류/흐름 제어를 수행하고, 735 | > - transport layer는 (더 상위 계층의) 논리적 연결에 대한 오류/흐름 제어를 수행한다는 것이다. 736 | 737 | --- 738 | 739 | ### network layer(3계층)와 Transport Layer(4계층)와의 차이점은? 740 | 741 | Network layer는 호스트 간 서비스, Transport layer는 프로세스 간 서비스이다. 742 | 743 | > 호스트: 네트워크에 연결된 컴퓨터. (또는, IP를 가지고 있고 양방향 통신이 가능한 컴퓨터) 744 | 745 | --- 746 | 747 | ### Transport Layer가 흐름 제어를 제공하는 방법? 748 | 749 | 1. Stop and wait 기법: 매번 전송한 패킷에 대해 확인 응답을 받아야만 그 다음 패킷을 전송하는 방법. 750 | 751 | 2. 슬라이딩 윈도우 기법: 윈도우를 통해 '동적으로' 흐름 제어를 지원하는 방식. 752 | 753 | - 수신 측에서 설정한 윈도우 크기만큼, 송신 측에서 확인 응답(ACK)없이 전송할 수 있게 한다. 754 | - 송신 측이 윈도우에 포함되는 모든 패킷을 전송한 후, 수신이 확인되는 대로 윈도우를 옆으로 옮겨 다음 패킷들을 전송한다. 755 | 756 | > - 동적으로 흐름을 제어한다는 말은, 상황에 따라 윈도우 크기를 조절할 수 있음을 의미한다. 757 | > - TCP/IP를 사용하는 모든 호스트들은 송신을 위한 윈도우와 수신을 위한 윈도우를 각 1개씩 가지고 있다. 758 | > - 송신측은 TCP 3 way handshaking을 통해 수신측의 윈도우 사이즈를 알 수 있게 된다. 759 | 760 | --- 761 | 762 | ### 혼잡 제어(Congestion control란? 763 | 764 | 송신측 데이터 전송 속도와 네트워크의 데이터 처리 속도 차이를 해결하는 기법. 765 | 766 | > 네트워크의 데이터 처리 속도라는 것은 곧, 네트워크 전송 경로 상에 존재하는 호스트와 라우터들의 데이터 처리 속도를 말한다. 767 | 768 | --- 769 | 770 | ### Transport Layer가 혼잡 제어를 제공하는 방법? 771 | 772 | AIMD, Slow start, Fast retransmit, Fast recovery등의 혼잡 제어 알고리즘을 사용한다. 773 | 774 | --- 775 | 776 | ### AIMD(합 증가/곱 감소)란? 777 | 778 | - 처음에 패킷을 하나씩 보내고, 문제 없이 도착하면 윈도우 사이즈를 1씩 증가시켜 전송. 779 | - 패킷 전송에 실패하거나 일정 시간을 넘으면 윈도우 사이즈를 절반으로 줄인다. 780 | 781 | > - "Additive Increase / Multicative Decrease" 782 | > - 공평한 방식: 여러 네트워크가 하나의 호스트를 공유하는 상황에서, 나중에 진입한 네트워크가 처음에는 불리하지만 시간이 지날 수록 평형의 상태에 가까워진다. 783 | > - 문제 1: 처음에는 네트워크의 높은 대역폭을 다 활용하지 못함. 784 | > - 문제 2: 네트워크 혼잡을 미리 감지하지 못함. 혼잡해지고 나서야 줄이는 방법. 785 | 786 | --- 787 | 788 | ### Slow start(느린 시작)란? 789 | 790 | - 최초에 전송하는 패킷에 대해 각각의 ACK 값이 도착할 때마다 윈도우 사이즈를 1씩 증가시킨다. 791 | - 혼잡 현상이 발생하면 윈도우 사이즈를 1로 떨어트린다. 792 | - 이후에는 혼잡 현상이 발생하는 사이즈의 절반까지는 똑같이 2배씩 증가시키고, 이후부터는 완만하게 1씩 증가시킨다. 793 | 794 | - AIMD와는 다르게 윈도우 사이즈가 지수 함수꼴로 증가한다. (대역폭 활용까지 오래 걸린다는 단점 극복) 795 | 796 | --- 797 | 798 | ### Fast retransmit(빠른 재전송)이란? 799 | 800 | ![Network%200208784d439545d2a6f93e6c5c4355bc/Untitled%201.png](Network%200208784d439545d2a6f93e6c5c4355bc/Untitled%201.png) 801 | 802 | - 수신측에서, 먼저 도착해야 할 패킷이 도착하지 않고 다음 패킷이 도착하면 이전에 잘 도착한 마지막 패킷의 순번을 ACK 값에 실어 보낸다. 803 | - 송신측에서는 중복된 ACK 값을 받게 된다. 중복된 ACK 값을 3번 받게 되면 패킷 손실로 판단하고, 문제가 되는 순번의 패킷을 재전송한다. 804 | - 이러한 현상은 혼잡한 네트워크 상황으로 인해 발생하므로, 혼잡을 감지하고 윈도우 사이즈를 줄인다. 805 | 806 | --- 807 | 808 | ### Transport Layer가 오류 제어를 제공하는 방법은? 809 | 810 | 수신 확인(데이터가 잘 도착했는지)와 오류 검출, 오류 처리로 구성된다. 811 | 812 | 수신 확인 813 | 814 | - 송신 측에서 Sequence Number를 전송 815 | - 수신 측에서 Sequence Number + 1 값을 ACK으로 전송해서 수신 확인 816 | 817 | 오류 검출/처리 818 | 819 | - CRC 사용해 무결성 검사. 820 | - 오류 발생 시 수신측에서 송신측에 재발송 요청 821 | 822 | --- 823 | 824 | ## TCP & UDP 825 | 826 | ### TCP(Transmission Control Protocol)란? 827 | 828 | Transport Layer의 프로토콜 중 하나로, 가상 회선 방식을 사용하는 연결형 서비스. 829 | 830 | 특징 831 | 832 | - 가상 회선 방식을 사용하는 연결형 서비스. 833 | - 흐름 제어, 혼잡 제어, 오류 제어를 통해 신뢰성을 보장. 834 | - 서버와 클라이언트가 1:1로 연결된다. 835 | - UDP에 비해 속도가 느리다. 836 | 837 | > - TCP는 3-way handshake로 논리적 연결을 성립하고, 4-way handshake로 논리적 연결을 해제한다. 838 | > - TCP는 전이중, 점대점 방식을 사용한다. 839 | 840 | > UDP에 비해 속도가 느린 이유 841 | > 842 | > - 흐름 제어, 혼잡 제어, 오류 제어 등이 CPU 자원을 사용하기 때문. 843 | > - 패킷에 대한 응답을 해야 하기 때문. (→ 시간 지연) 844 | 845 | > TCP가 전송할 수 있는 데이터의 크기 제한 846 | > : TCP는 스트림 전송으로, 전송 데이터의 크기가 무제한이다. 847 | > 848 | > - 스트림: 데이터, 패킷, 비트 등이 일련의 연속성을 갖는 흐름. 849 | > - TCP는 데이터를 무제한으로 전송할 수 있지만, Network layer에서 MTU에 따라 데이터를 분할, Data-link layer에서 프레이밍을 통해 분할됨. 850 | 851 | > (1:1 연결의 한계 극복 대안) MPTCP(: Multipath TCP) 852 | > 853 | > - MPTCP는 다수의 TCP 경로를 구성하고, 구성한 다수 경로로 동시에 데이터를 송수신하는 방법이다. (예를 들어, 100Mbps(Mege bit per second) 속도의 대역폭과 500Mbps 속도의 대역폭이 있다면, MPTCP는 이를 하나의 망인 것처럼 구성해 최대 600Mbps의 대역폭으로 사용할 수 있다.) 854 | 855 | --- 856 | 857 | ### UDP(User Datagram Protocol)란? 858 | 859 | Transport layer의 프로토콜 중 하나로, 데이터그램 방식을 사용하는 비연결형 서비스. 860 | 861 | 특징 862 | 863 | - 데이터그램 방식을 사용하는 비연결형 프로토콜. 864 | - (흐름 제어, 혼잡 제어 등을 제공하지 않아) 신뢰성이 낮다. 865 | - 서버와 클라이언트가 N:M(1:1, 1:N, N:M 등)으로 연결될 수 있다. 866 | - TCP에 비해 속도가 빠르다. 867 | 868 | > - UDP는 메시지에 대한 확인 응답(ACK)이 없다. 869 | 870 | > UDP는 헤더의 체크섬 필드를 통해 최소한의 오류만 검출한다. 871 | > 872 | > - 송신측은 데이터를 전송하기 전에 데이터 값을 사용해 체크섬(데이터가 변형되지 않았는지 확인하는 값) 값을 계산하고, 데이터에 담아 전송한다. 873 | > - 수신측은 데이터 값을 사용해 다시 체크섬 값을 계산하고, 함께 전송된 체크섬 값과 비교한다. 874 | 875 | > UDP가 전송할 수 있는 데이터의 크기 제한 876 | > : (UDP는 데이터그램 방식으로 통신하므로) 데이터가 데이터그램 단위로 전송되며, 그 크기는 '이론상' 65,535($2^{16}-1$) 바이트로, 크기가 초과하면 잘라서 보낸다. 877 | > 878 | > (UDP 패킷의 최대 크기는 '이론상' 65,535 byte이지만, 실제 구현에서는 해당 패킷을 실어나르는 호스트에 따라 그 최대 길이가 결정된다.) 879 | > 880 | > - UDP도 근본적으로는 network layer의 IP 프로토콜에서 운용된다는 점을 고려할 수 있다. 881 | > - TCP/IP 표준이 게시된 RFC를 참고하면, 모든 장비는 약 500byte까지의 데이터그램을 처리할 수 있어야 함을 명시하고 있다. 882 | > - 바꾸어 말하면, IPv4에서는 500byte 이상의 데이터그램에 대해서는 보장되지 않음을 의미한다. 883 | > - 따라서, IPv4 위에서 운용된다는 점을 고려할 때 실질적인 UDP의 패킷 크기는 약 500byte라고 볼 수 있다. 884 | > (https://scrapsquare.com/notes/udp-length) 885 | 886 | > (참고) RFC란? 887 | > 888 | > - Requests For Comments. 즉, 컴퓨터 공학 분야에 적용될 수 있는 여러 연구, 기법 등에 대한 메모. 889 | > - TCP/IP의 표준이 RFC에 게시되어 있다. 890 | > (단, 정의에서 알 수 있듯이 모든 RFC가 표준은 아니다.) 891 | 892 | --- 893 | 894 | ### 연결형 서비스와 비연결형 서비스의 차이점은? 895 | 896 | 연결형 서비스 897 | 898 | - 송신자와 수신자 사이에 논리적 연결을 확립하고 데이터를 전송하는 방법. 899 | - 오류 발생 시 재전송을 해, 신뢰성 있는 전송. 900 | - (전송되는 데이터가 모두 동일한 경로를 이용하기 때문에) 전송된 데이터의 순서와 목적지에 도착하는 데이터 순서가 동일하다. 901 | > - 대표적으로 가상 회선 방식이 있다. 902 | 903 | 비연결형 서비스 904 | 905 | - 송신자와 수신자 사이에 논리적 연결을 확립하지 않고 데이터를 전송하는 방법. 906 | - 오류 발생 시 재전송하지 않아 신뢰성 없는 전송. 907 | - 연결 확립에 걸리는 시간이 없어 전송 속도가 빠르다. 908 | > - 대표적으로 데이터그램 방식이 있다. 909 | 910 | --- 911 | 912 | ### 데이터그램 방식과 가상 회선 방식이란? 913 | 914 | 데이터그램 방식 915 | 916 | - 데이터를 전송하기 전에 논리적 연결이 설정되지 않고 전송되는 방식. 917 | - 패킷은 독립적으로, 서로 다른 경로를 통해 전송된다. 918 | - 송신한 순서와 수신한 순서가 다를 수 있다. 919 | - 속도가 빠르다. 여러 노드에 트래픽이 분산되기 때문이다. 920 | 921 | 가상 회선 방식 922 | 923 | - 데이터를 전송하기 전에 논리적 연결을 설정하고 전송하는 방식. 924 | - 최초 경로 설정할 때 한 번 경로가 선택되고 그 경로가 가상 회선. 925 | - 패킷은 송신한 순서대로 도착한다. 926 | - 상대적으로 속도가 느리다. 특정 교환기(노드)에 트래픽이 몰려 지연 현상이 발생하기 때문이다. 927 | 928 | > 가상회선 방식과 데이터그램 방식의 공통점은? 929 | > 930 | > - 둘 다 '패킷 교환 방식'의 일종이다. 931 | > - 데이터를 패킷으로 분할해 전송한다. 932 | 933 | > 사용하기 적합한 데이터 특성 934 | > 935 | > - 가상회선 방식: 다량의 데이터를 정해진 시간 안에 연속으로 전송할 때(신뢰성이 보장되기 때문이다.) 936 | > - 데이터그램 방식: 짧은 메시지를 일시적으로 전송할 때(속도가 빠르기 때문이다.) 937 | 938 | > 네트워크 내 특정 노드가 다운되었을 때의 차이점 939 | > 940 | > - 데이터그램 방식: 다른 경로를 새로 설정. 941 | > - 가상회선 방식: 해당 노드를 지나는 가상회선의 전체 경로를 잃게 된다. 942 | 943 | --- 944 | 945 | ### 가상 회선 방식에서 논리적 연결이 설정되는 과정은? 946 | 947 | ![Network%200208784d439545d2a6f93e6c5c4355bc/Untitled.png](Network%200208784d439545d2a6f93e6c5c4355bc/Untitled.png) 948 | 949 | 1. 송신지 노드가 논리적 연결을 요구하는 제어 패킷을 전송. 950 | 951 | 2. 제어 패킷을 수신한 라우터들은 각자의 virtual circuit table을 완성시키면서 다음 라우터로 제어 패킷을 전달. 952 | 953 | - virtual circuit table은 수신된 패킷의 VCI, 즉 virtual circuit identifier와 수신된 port 번호를 incoming section에 기록하고, 내보낼 port 번호를 outgoing section에 기록 954 | 955 | 3. 제어 패킷을 받은 수신지 노드는 논리적 연결에 대한 응답을 송신지에 전송. 이 과정에서 virtual circuit table이 완성된다. 956 | 957 | 4. 이후 해당 논리적 연결을 통해 전송되는 패킷은 주소 정보 대신 VCI 값에 의해 데이터 전송이 이루어짐. 958 | 959 | --- 960 | 961 | ### 회선 구성 방식에는 어떤 것들이 있을까? 962 | 963 | 1. 점대점(point-to-point) 방식 964 | 965 | : 두 장치 간 1:1 회선을 이용해 연결되는 방식. 966 | 967 | 장점 968 | 969 | - 회선 구성이 간단하다. 970 | - 대용량 전송에 유리하다. 971 | (회선이 전송할 수 있는 데이터량은 한정되어 있으므로, 데이터를 주고 받는 주체가 적을 수록 더 많은 양의 데이터를 주고 받을 수 있을 것이다.) 972 | 973 | 단점 974 | 975 | - 1:1 통신을 위해 별도의 회선 설치 → 높은 설치 비용 976 | 977 | > 점대점 방식은 Data-link layer의 프로토콜 중 하나이며, network layer(osi 3) 등 다양한 타 계층에서도 사용할 수 있도록 발전되었다. 978 | 979 | 2. 다중점(multi-point) 방식 980 | 981 | : 하나의 회선에 여러 개의 장치가 연결되어 통신하는 방식. 982 | 983 | 장점 984 | 985 | - 송수신하는 데이터의 양이 적을 때 효율적이다. 986 | 987 | 단점 988 | 989 | - 구성 비용은 줄일 수 있으나 설계가 복잡하다. 990 | 991 | > - '회선 구성': 둘 이상의 장치가 하나의 회선(링크)에 연결되는 방식. 992 | > - '회선' : 하나의 장치에서 다른 장치로 데이터를 보내는 통신 경로. 993 | 994 | --- 995 | 996 | ### 전이중, 반이중, 단방향 방식에 대해 설명해본다면? 997 | 998 | - 전이중 방식(full-duplex) : 두 개의 통신 장치가 동시에 송, 수신이 가능한 통신 방식 999 | - 반이중 방식(half-duplex) : 두 개의 통신 장치가 송, 수신을 할 수 있지만, 한 번에 한 쪽 방향으로만 통신할 수 있는(데이터를 수신하는 동안에는 송신할 수 없는) 통신 방식 1000 | - 단방향 방식(simplex) : 송신, 혹은 수신만 할 수 있는 통신 방식 1001 | 1002 | --- 1003 | 1004 | ### TCP와 UDP는 각각 어떤 특성의 서비스에 적합할까? 1005 | 1006 | TCP 1007 | 1008 | - 연속성보다 신뢰성 있는 전송이 중요한 서비스 1009 | - 예) 파일 전송 1010 | 1011 | UDP 1012 | 1013 | - 신뢰성보다는 real time을 보장하거나 빠른 연결이 필요한 서비스 1014 | - 예) 실시간 (스트리밍) 서비스 1015 | 1016 | > UDP는 TCP에 비해 다음과 같은 이점이 있다. 1017 | > 1018 | > 1. 신속성 1019 | > 1020 | > - TCP는 흐름, 혼잡, 오류 제어로 데이터를 재전송하거나 속도를 제어. 반면 UDP는 UDP 세그먼트로. 만들고 바로 네트워크 계층으로 전송. → 조금의 데이터 손실을 감수하면 지나친 latency를 방지할 수 있다. 1021 | > - 연결 설정이 없다. 1022 | > 1023 | > 2. 수용성 1024 | > 1025 | > - TCP는 종단 호스트에서 연결 상태(수신 버퍼, 송신 버퍼, sequence, ack number 등)를 유지. 이에 반해 UDP는 연결 상태를 유지하기 위한 어떤 파라미터도 기록하지 않음 → 더 많은 클라이언트를 수용할 수 있다. 1026 | 1027 | > UDP에 적절한 서비스들 1028 | > 1029 | > - 비디오 스트리밍: 신속성 1030 | > - DNS: 신속성, 수용성 1031 | > - IPTV: IP 사용하는 디지털 텔레비전 서비스. 신속성(실시간 비디오 스트리밍과 같은 결) 1032 | > - 음성 인터넷 프로토콜(VoIP): ip를 사용하는 음성 통신 기술. 신속성. 1033 | > - TFTP: (↔ FTP with TCP) 간단한 버전의 FTP(File Transfer Protocol). 단순하고 빠르게 파일을 전송하는 목적. 1034 | > - IP 터널: 두 ip 네트워크를 연결하는 대화 채널. 1035 | > - 온라인 게임: 신속성. 실시간. 1036 | 1037 | --- 1038 | 1039 | ### 3-way handshake의 과정에 대해 설명해본다면? 1040 | 1041 | 최초의 클라이언트와 서버에 대해 1042 | 1043 | - (상태) 클라이언트: `CLOSED`, 서버: `LISTEN` 1044 | 1045 | > - 클라이언트가 서버로 연결 요청을 하기 이전에, 서버는 (연결 요청에 대한 준비로) port를 listen하고 있어야 한다. 이를 passive open이라고 한다. 1046 | > - 클라이언트가 서버에게 연결 요청을 보냄으로써 3-way handshake를 시작하는 것을 active open이라고 한다. 1047 | 1048 | 클라이언트 → 서버 1049 | 1050 | - 클라이언트가 서버에게 연결 요청 메시지 `SYN`을 전송. 1051 | 1052 | - `SYN` 메시지는 `SYN` flag 비트를 1로 설정한 세그먼트이다. 1053 | - `SYN`의 sequence number에는 클라이언트가 랜덤으로 선택한 값(ex: `A`)이 담겨진다. 1054 | 1055 | - (상태) 클라이언트: `CLOSED`, 서버: `SYN_RSV` 1056 | 1057 | 클라이언트 <- 서버 1058 | 1059 | - 서버는 클라이언트에게 `SYN` + `ACK`을 전송해서, 요청 수락과 동시에 클라이언트도 포트를 열어달라는 메시지를 보낸다. 1060 | 1061 | - `SYN-ACK` 메시지는 `SYN`과 `ACK` 비트가 1인 세그먼트이다. 1062 | - acknowledgement number는 이전에 클라이언트가 `SYN`에 담아 보낸 sequence number에 1을 더한 값(ex: `A+1`)으로 설정된다. 1063 | - sequence number에는 서버가 랜덤으로 선택한 값(ex: `B`)이 담겨진다. 1064 | 1065 | - (상태) 클라이언트: `CLOSED`, 서버: `SYN_RSV` 1066 | 1067 | 클라이언트 → 서버 1068 | 1069 | - 클라이언트는 서버에게 수락 메시지 `ACK`을 보낸다. 1070 | - sequence number는 이전에 받은 acknowledgement number(ex: `A+1`)로 설정된다. 1071 | - acknowledgement number는 이전에 받은 sequence number에 1을 더한 값(ex: `B+1`)으로 설정된다. 1072 | - (상태) 클라이언트: `ESTABILISHED`, 서버: `ESTABILISHED` 1073 | 1074 | --- 1075 | 1076 | ### 4-way handshake의 과정에 대해 설명해본다면? 1077 | 1078 | ![Network%200208784d439545d2a6f93e6c5c4355bc/connection-termination.png](Network%200208784d439545d2a6f93e6c5c4355bc/connection-termination.png) 1079 | 1080 | 최초 1081 | 1082 | - (상태) 클라이언트: `ESTABILISHED`, 서버: `ESTABILISHED` 1083 | 1084 | 클라이언트 → 서버 1085 | 1086 | - 클라이언트가 연결 종료를 요청하는 `FIN` 메시지를 서버에게 전송 1087 | - (상태) 클라이언트: `FIN_WAIT_1`, 서버: `ESTABILISHED` 1088 | 1089 | 서버 → 클라이언트 1090 | 1091 | - 서버는 클라이언트에게 일단 확인 메시지 `ACK`을 보낸다. 1092 | > (상태) 클라이언트: `FIN_WAIT_2`(active close), 서버: `CLOSE_WAIT` (passive close) 1093 | - 그리고, 서버는 자신의 통신이 끝날 때까지 마저 전송하며 기다린다. 1094 | - 서버의 통신이 끝나면, 클라이언트에게 연결 종료 요청에 합의한다는 의미로 `FIN` 메시지를 보낸다. 1095 | > - (상태) 클라이언트: `TIME_WAIT`, 서버: `LAST_ACK` 1096 | > - 클라이언트는 `TIME_WAIT` 상태에서 최종적으로 연결을 닫기 전까지 일정 시간을 기다린다(연결을 닫혀있다는 것은, 해당 local port가 새로운 연결을 맺을 수 없는 상태를 말한다). 이는 전송이 지연된 패킷이 뒤늦게 도착해 혼동이 생기는 것을 방지하기 위함이다. 1097 | 1098 | 클라이언트 → 서버 1099 | 1100 | - 클라이언트는 서버에게 확인했다는 메시지 `ACK`를 보낸다. 1101 | 1102 | > 메시지(세그먼트)가 SYN인지, ACK, FIN 등인지 나타내는 방법 1103 | > 1104 | > - TCP 헤더의 control bit를 사용한다. 1105 | > - control bit는 총 6비트이며, 각각의 비트는 SYN, ACK, FIN 등을 나타낸다. 1106 | 1107 | --- 1108 | 1109 | ### 왜 2-way handshake는 성립될 수 없을까? 1110 | 1111 | - TCP/IP 통신은 양방향 통신이다. 1112 | - 통신간 상대방의 특정 메시지를 받았다는 것을 알리는 데 sequence number가 사용된다. (받은 메시지의 sequence number+1을 담아 보냄으로써) 1113 | - TCP/IP는 양방향 통신이므로, 양쪽에서 서로의 메시지를 받았음을 알려줄 수 있어야 한다. 1114 | - 이를 위해서는 sequence number가 각각 1개씩 필요하며, 각 sequence number는 호스트가 고른 random한 숫자로 초기화된다. (ISN: Initial Sequence Number) 1115 | - 2-way로는 한 쪽의 sequence number만 사용할 수 있다. 따라서 3-way로 양쪽의 호스트가 ISN을 공유하는 과정이 필요하다. 1116 | 1117 | > 2-way 1118 | > (1) 클라이언트가 서버에게 `SYN` 패킷 전송 1119 | > (2) 서버가 클라이언트에게 `ACK` 패킷 전송 1120 | 1121 | --- 1122 | 1123 | ## OSI Application Layer(응용 계층, 7계층) & TCP/IP Application Layer(4계층) 1124 | 1125 | > OSI Session Layer(5계층) 1126 | > 1127 | > - 응용 프로그램간 세션을 지원하는 계층. 1128 | > - 세션 설정, 통신 응답 대기시간 등 세션과 관련된 작업을 처리한다. 1129 | > 1130 | > OSI Presentation Layer(6계층) 1131 | > 1132 | > - 데이터가 표현되는 방식을 담당하는 계층. 1133 | > - 데이터의 암호화 및 복호화, 인코딩(ASCII 등) 및 디코딩, 데이터 표현 형식(JPG, JPEG 등)을 처리한다. 1134 | 1135 | ### Application Layer란? 1136 | 1137 | - 어플리케이션 간 데이터 교환을 담당하는 모듈 1138 | - 사용자가 어플리케이션과 상호작용할 수 있도록 인터페이스를 제공 1139 | 1140 | > - TCP/IP의 application layer는 OSI session layer, presentation layer, application layer에 해당한다. 1141 | > - 응용 계층의 프로토콜 1142 | > 1143 | > - TCP 기반: HTTP 등 1144 | > - UDP 기반: DNS, DHCP 등 1145 | 1146 | --- 1147 | 1148 | ## DNS 1149 | 1150 | ### DNS(Domain Name Server)란? 1151 | 1152 | 도메인을 ip주소로 변환해주는 서버, 혹은 시스템 1153 | 1154 | > DNS가 사용되기 이전에는, 각 컴퓨터마다 가지고 있는 hosts.txt 파일을 사용했다. 1155 | > 1156 | > - hosts.txt 파일은 호스트명과 ip주소 정보가 저장되어 있었다. 1157 | > - 각 클라이언트는 FTP를 사용해 hosts 파일을 다운로드했다. 1158 | > - Web 서비스 사용자가 폭발적으로 증가하면서, 많은 host에 대한 정보를 파일로 관리하기 힘들어졌다. 1159 | 1160 | --- 1161 | 1162 | ### 도메인 네임(domain name)이란? 1163 | 1164 | 네트워크 상에서 컴퓨터를 식별하는 호스트명 1165 | 1166 | --- 1167 | 1168 | ### 도메인 네임의 구조? 1169 | 1170 | 오른쪽부터 1, 2, 3단계 도메인으로 구성되어 있으며, 왼쪽으로 갈 수록 도메인의 범위가 작아진다. 1171 | (예: Whois.co.kr) 1172 | 1173 | - 1단계 도메인(top level domain): 국가 도메인 1174 | - 2단계 도메인(second level domain): 도메인의 성격 1175 | - 3단계 도메인(third level domain): 도메인 네임을 등록하는 사람이 원하는 이름 1176 | 1177 | 보통 앞에 붙는 `www.`은 도메인 네임에 포함되지 않는 '호스트명'이다. 1178 | 1179 | - 도메인을 가지고 있으면, 앞에 수많은 호스트명을 붙여 다양한 호스트 서버를 운영할 수 있다. 1180 | (ex: www.naver.com, shopping.naver.com, mail.naver.com, ...) 1181 | - 도메인 네임은 논리적 그룹(.com), 호스트명은 실제 서버에 주어진 컴퓨터의 이름(www, naver)이라 볼 수 있다. 1182 | 1183 | --- 1184 | 1185 | ### DNS에서 도메인을 얻어오는 과정은? 1186 | 1187 | ![Network%200208784d439545d2a6f93e6c5c4355bc/Untitled%202.png](Network%200208784d439545d2a6f93e6c5c4355bc/Untitled%202.png) 1188 | 1189 | 사용자가 브라우저에 www.naver.com를 입력 후 접속한다. 1190 | 1191 | → 브라우저는 해당 도메인과 ip주소 정보가 브라우저 캐시(Browser Cache)에 존재하는지 확인한다. 1192 | 1193 | > 크롬의 경우, chrome://net-internals/#dns 에서 확인할 수 있다. 1194 | 1195 | → 브라우저 캐시에 정보가 없다면, OS에 저장된 DNS Cache를 찾는다. 1196 | 1197 | > Mac OS X의 경우, `/etc/hosts`에 존재한다. 1198 | 1199 | → OS DNS Cache에 정보가 없다면, PC는 (단말의) 시스템에 설정되어 있는 local DNS에게 "www.naver.com"이라는 호스트명의 ip주소를 요청한다. 1200 | 1201 | > Mac OS X의 경우, local DNS의 ip 주소가 `/etc/resolv.conf`에 존재한다. 1202 | 1203 | → local DNS는 자신의 네임 서버에서 해당 호스트명과 매칭되는 ip주소가 있는지 확인한다. 없을 경우, 루트 DNS 서버에게 DNS 요청을 보낸다. 1204 | 1205 | > local DNS는 root DNS의 ip주소를 미리 알고 있다. 1206 | 1207 | → 루트 DNS는 ip주소를 찾고, 없으면 자신의 하위 레벨 DNS의 ip주소를 local DNS에게 응답한다. 1208 | 1209 | - local DNS는 해당 하위 레벨 DNS에게 DNS 요청을 보낸다. 1210 | - 하위 레벨 DNS는 ip주소가 없으면 그 하위 레벨의 DNS의 ip주소를 local DNS에게 응답한다. 이렇게 반복적인 형태로 local DNS는 ip주소를 얻을 때까지 recursive(iterative) query를 전송한다. 1211 | 1212 | → 응답(ip주소)을 받은 local DNS는 도메인에 대한 ip주소를 (DNS Cache에) 캐싱하고, 해당 ip주소를 브라우저에게 전달한다. 1213 | 1214 | --- 1215 | 1216 | ### PC는 local DNS의 ip 주소를 어떻게 알고 있을까? 1217 | 1218 | DHCP라는 프로토콜로 알게 된다. 1219 | 1220 | --- 1221 | 1222 | ### DNS의 구성 요소는? 1223 | 1224 | - 도메인 네임 스페이스(domain name space) 1225 | - 네임 서버(name server) 1226 | - 리졸버(resolver) 1227 | 1228 | --- 1229 | 1230 | ### 도메인 네임 스페이스란? 1231 | 1232 | ![Network%200208784d439545d2a6f93e6c5c4355bc/Untitled%203.png](Network%200208784d439545d2a6f93e6c5c4355bc/Untitled%203.png) 1233 | 1234 | DNS가 구성, 관리되는 계층적 구조 1235 | 1236 | > - 최상위에 루트 DNS 서버가 존재 1237 | > - 루트 DNS 하위에 계층 구조로 DNS 서버가 구성 1238 | 1239 | --- 1240 | 1241 | ### 네임 서버란? 1242 | 1243 | 도메인과 ip주소 정보를 가지고 있는 서버. 1244 | 1245 | > - resolver로부터 요청을 받고, 응답(ip주소)를 다시 resolver에게 전달하는 역할. 1246 | 1247 | --- 1248 | 1249 | ### 네임 서버의 종류는? 1250 | 1251 | Primary Name Server 1252 | 1253 | - 도메인을 관리하는 주 네임 서버 1254 | 1255 | Secondary Name Server 1256 | 1257 | - Primary Name Server가 고장났을 때 등의 상황에서 역할을 대신 수행할 수 있는 서버 1258 | 1259 | > Secondary Name Server는 주기적으로 네임 서버로부터 정보를 받아와 자신의 정보를 갱신한다. 1260 | 1261 | --- 1262 | 1263 | ### resolver란? 1264 | 1265 | DNS의 구성 요소로서, 1266 | 1267 | - DNS 클라이언트의 요청을 네임 서버로 전달하고, 1268 | - 네임 서버로부터 정보(도메인 네임과 ip주소)를 받아 클라이언트에게 전송하는 역할을 한다. 1269 | 1270 | > - 네임 서버의 구조(네임 서버 스페이스)를 파악하고 있다. 1271 | > - 네임 서버에 요청 받은 도메인의 ip 주소를 조회하는 기능을 가진다. 1272 | > - 조회한 네임 서버에 원하는 ip주소가 없을 경우, 다른 네임 서버에 요청을 보낸다. 1273 | 1274 | --- 1275 | 1276 | ### DNS가 사용하는 전송 계층(Transport Layer)의 프로토콜은? 1277 | 1278 | - 대부분의 경우 UDP를 사용 1279 | - 약 500bytes를 초과하는 DNS 패킷을 전송해야 할 경우 TCP 사용 1280 | 1281 | --- 1282 | 1283 | ### DNS에 UDP를 사용하는 이유? 1284 | 1285 | DNS는 작은 데이터를 교환하며, 굉장히 많은 클라이언트와 연결을 맺는다. 1286 | 1287 | - TCP는 아무리 적은 데이터라도 논리적 연결을 맺는 데 시간과 비용이 들며, 신뢰성 확보를 위해 다양한 처리를 한다. 1288 | - UDP는 신뢰성을 보장하지 않아 오버헤드가 적게 들며, 그만큼 더 빠른 시간에, 더 많은 클라이언트와 통신을 주고 받을 수 있다. 1289 | 1290 | --- 1291 | 1292 | ## 로드 밸런싱(Load Balancing) 1293 | 1294 | ### 트래픽이 증가해 기존의 컴퓨팅 자원으로 서비스할 수 없을 때, 대처할 수 있는 2가지 방법은? 1295 | 1296 | 1. Scale-up 1297 | 1298 | - 서버 자체의 성능을 확장하는 것. 1299 | 1300 | 2. Scale-out 1301 | 1302 | - 기존 서버와 동일하거나 낮은 성능의 서버를 2대 이상으로 증설해 운영하는 것. 1303 | 1304 | > - Scale-out은 트래픽을 증설한 서버로 분산시키기 위해 로드 밸런싱 기술이 필수적으로 필요하다. 1305 | 1306 | --- 1307 | 1308 | ### 로드 밸런싱이란? 1309 | 1310 | 네트워크 또는 서버에 가해지는 부하를 여러 대의 컴퓨팅 자원으로 분산하는 기술. 1311 | 1312 | > - 로드 밸런싱은 '부하 분산'이라고도 한다. 1313 | 1314 | --- 1315 | 1316 | ### 로드 밸런싱 알고리즘에 대해 설명해본다면? 1317 | 1318 | 라운드 로빈 방식(Round-Robin method) 1319 | 1320 | - 서버에 들어온 요청을 순서대로 돌아가며 배정하는 방식 1321 | - 여러 대의 서버가 동일한 스펙을 가지고 있고, 서버와의 연결(세션)이 오래 지속되지 않는 경우 적합하다. 1322 | 1323 | 가중 라운드 로빈 방식(Weighted Round-Robin method) 1324 | 1325 | - 각 서버마다 가중치를 매기고, 가중치가 높은 서버에 요청을 우선적으로 배분한다. 1326 | - 서버의 트래픽 처리 능력이 상이한 경우 적합하다. 1327 | 1328 | IP 해시 방식(IP Hash method) 1329 | 1330 | - 클라이언트의 IP 주소를 해싱해 특정 서버로 매핑하는 방식 1331 | - 사용자가 항상 동일한 서버로 연결되는 것을 보장한다. 1332 | 1333 | 최소 연결 방식(Least Connection method) 1334 | 1335 | - 요청이 들어온 시점에 가장 적은 연결 상태를 보이는 서버에 우선적으로 트래픽을 배분한다. 1336 | - 연결(세션)이 자주 길어지거나, 서버에 분배된 트래픽이 일정하지 않은 경우에 적합하다. 1337 | 1338 | --- 1339 | 1340 | ### 각 계층의 로드 밸런서에 대해 설명해본다면? 1341 | 1342 | > - 로드 밸런싱에는 L4 로드 밸런서와 L7 로드 밸런서가 가장 많이 사용된다. L4 로드 밸런서부터 포트 정보를 바탕으로 로드를 분산할 수 있기 때문이다. 한 대의 서버에 각기 다른 포트 번호를 부여해 다수의 서버를 운영하는 경우라면 최소 L4 이상의 로드 밸런서를 사용해야 한다. 1343 | > - 상위 계층에서 사용되는 장비는 하위 계층의 장비가 갖고 있는 기능/정보를 모두 가지고 있으며, 상위 계층일수록 더욱 정교한 로드 밸런싱이 가능하다. 1344 | 1345 | L4 로드 밸런서 1346 | 1347 | - 네트워크 계층(IP)이나 트랜스포트 계층(TCP, UDP)의 정보를 바탕으로 부하를 분산한다. 1348 | - MAC 주소, IP 주소, 포트 번호, 전송 프로토콜 등에 따라 트래픽을 나눌 수 있다. 1349 | 1350 | 장점 1351 | 1352 | - 데이터 안을 들여다보지 않고 분산하기 때문에 속도가 빠르다. 1353 | - 데이터의 내용을 복호화하지 않기 때문에, 인증서를 가지고 있을 필요가 없고, 따라서 잠재적 보안상의 위험으로부터 안전하다. 1354 | - L7 로드 밸런서에 비해 가격이 저렴하다. 1355 | 1356 | 단점 1357 | 1358 | - 패킷의 내용을 살펴볼 수 없기 때문에 섬세한 라우팅이 불가능하다. 1359 | - 사용자의 IP가 수시로 바뀌는 상황이라면 연속적인 서비스를 제공하기 어렵다. 1360 | 1361 | L7 로드 밸런서 1362 | 1363 | - 4계층의 정보를 포함해, 애플리케이션 계층(HTTP, FTP 등)의 정보를 바탕으로 부하를 분산한다. 1364 | - HTTP 헤더나 쿠키, 메시지(URL 등) 등 패킷의 구체적인 내용을 바탕으로 특정 서버에 트래픽을 분산하는 것이 가능하다. 1365 | 1366 | 장점 1367 | 1368 | - 풍부한 정보를 바탕으로 더 섬세한 라우팅이 가능하다. 1369 | - 비정상적 트래픽을 사전에 방지할 수 있어 서비스 안정성이 높다. 1370 | 1371 | > - L7 로드 밸런서는 특정한 패턴을 지닌 바이러스를 감지해 네트워크를 보호할 수 있다. 또한, DDoS와 같은 비정상적 트래픽을 필터링할 수 있어 네트워크 보안 분야에서 활용된다. (패킷의 내용을 분석해, 합법적인 트래픽만 수용하는 등의 방법으로 필터링할 수 있다.) 1372 | > - L7 로드 밸런서는 HTTP 메시지의 쿠키 등의 정보를 활용해 클라이언트와 서버 간 지속적이고 일관된 서비스를 제공할 수 있다. 1373 | 1374 | 단점 1375 | 1376 | - HTTP 메시지 패킷을 들여다보기 위해 복호화에 따른 오버헤드가 발생한다. 1377 | - 클라이언트, 서버와 인증서를 공유하고 있어야 하기 때문에, 공격자가 로드 밸런서를 타켓으로 민감한 데이터에 접근할 수 있어 잠재적인 보안 위험성이 존재한다. 1378 | -------------------------------------------------------------------------------- /os/OS e8aed882f45845d1a8fe27f71d71571b/Untitled 1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heech1013/study-note/9c5d4ee9887aed616e24701a9a43b1cd53dcf6a4/os/OS e8aed882f45845d1a8fe27f71d71571b/Untitled 1.png -------------------------------------------------------------------------------- /os/OS e8aed882f45845d1a8fe27f71d71571b/Untitled 2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heech1013/study-note/9c5d4ee9887aed616e24701a9a43b1cd53dcf6a4/os/OS e8aed882f45845d1a8fe27f71d71571b/Untitled 2.png -------------------------------------------------------------------------------- /os/OS e8aed882f45845d1a8fe27f71d71571b/Untitled 3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heech1013/study-note/9c5d4ee9887aed616e24701a9a43b1cd53dcf6a4/os/OS e8aed882f45845d1a8fe27f71d71571b/Untitled 3.png -------------------------------------------------------------------------------- /os/OS e8aed882f45845d1a8fe27f71d71571b/Untitled 4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heech1013/study-note/9c5d4ee9887aed616e24701a9a43b1cd53dcf6a4/os/OS e8aed882f45845d1a8fe27f71d71571b/Untitled 4.png -------------------------------------------------------------------------------- /os/OS e8aed882f45845d1a8fe27f71d71571b/Untitled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heech1013/study-note/9c5d4ee9887aed616e24701a9a43b1cd53dcf6a4/os/OS e8aed882f45845d1a8fe27f71d71571b/Untitled.png -------------------------------------------------------------------------------- /os/OS e8aed882f45845d1a8fe27f71d71571b/async.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heech1013/study-note/9c5d4ee9887aed616e24701a9a43b1cd53dcf6a4/os/OS e8aed882f45845d1a8fe27f71d71571b/async.png -------------------------------------------------------------------------------- /os/OS e8aed882f45845d1a8fe27f71d71571b/blocking&async.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heech1013/study-note/9c5d4ee9887aed616e24701a9a43b1cd53dcf6a4/os/OS e8aed882f45845d1a8fe27f71d71571b/blocking&async.png -------------------------------------------------------------------------------- /os/OS e8aed882f45845d1a8fe27f71d71571b/blocking&sync.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heech1013/study-note/9c5d4ee9887aed616e24701a9a43b1cd53dcf6a4/os/OS e8aed882f45845d1a8fe27f71d71571b/blocking&sync.png -------------------------------------------------------------------------------- /os/OS e8aed882f45845d1a8fe27f71d71571b/blocking.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heech1013/study-note/9c5d4ee9887aed616e24701a9a43b1cd53dcf6a4/os/OS e8aed882f45845d1a8fe27f71d71571b/blocking.png -------------------------------------------------------------------------------- /os/OS e8aed882f45845d1a8fe27f71d71571b/non-blocking&async.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heech1013/study-note/9c5d4ee9887aed616e24701a9a43b1cd53dcf6a4/os/OS e8aed882f45845d1a8fe27f71d71571b/non-blocking&async.png -------------------------------------------------------------------------------- /os/OS e8aed882f45845d1a8fe27f71d71571b/non-blocking&sync.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heech1013/study-note/9c5d4ee9887aed616e24701a9a43b1cd53dcf6a4/os/OS e8aed882f45845d1a8fe27f71d71571b/non-blocking&sync.png -------------------------------------------------------------------------------- /os/OS e8aed882f45845d1a8fe27f71d71571b/non-blocking.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heech1013/study-note/9c5d4ee9887aed616e24701a9a43b1cd53dcf6a4/os/OS e8aed882f45845d1a8fe27f71d71571b/non-blocking.png -------------------------------------------------------------------------------- /os/OS e8aed882f45845d1a8fe27f71d71571b/sync.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heech1013/study-note/9c5d4ee9887aed616e24701a9a43b1cd53dcf6a4/os/OS e8aed882f45845d1a8fe27f71d71571b/sync.png -------------------------------------------------------------------------------- /os/OS e8aed882f45845d1a8fe27f71d71571b/thread-by-level.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heech1013/study-note/9c5d4ee9887aed616e24701a9a43b1cd53dcf6a4/os/OS e8aed882f45845d1a8fe27f71d71571b/thread-by-level.png -------------------------------------------------------------------------------- /os/README.md: -------------------------------------------------------------------------------- 1 | # OS 2 | 3 | ## Table of Contents 4 | 5 | 운영체제 6 | 7 | - 운영체제란? 8 | - 운영체제의 역할은? 9 | 10 | 프로세스와 스레드 11 | 12 | - 프로세스란? 13 | - 메모리는 어떻게 구성되어 있을까? 14 | - 스레드란? 15 | - 스레드가 필요한 이유는? (스레드의 장점은?) 16 | - 프로세스와 스레드의 차이점은? 17 | - 스레드를 지원하는 주체에 따라 나눈다면 어떻게 나뉠까? 18 | - 사용자 레벨 스레드의 장단점? 19 | - 커널 레벨 스레드의 장단점? 20 | - 멀티 프로세스와 멀티 스레드의 차이점은? 21 | 22 | 스케줄링 23 | 24 | - Context Switching(문맥 교환)이란? 25 | - Context Switching이 필요한 이유는? 26 | - Context Switching이 진행되는 과정은? 27 | - Context에는 어떤 정보들이 있을까? 28 | - Context Switching는 어떤 상황에서 진행될까? 29 | - PCB(Process Control Block)란? 30 | - PCB가 가지고 있는 정보에는 어떤 것들이 있을까? 31 | - 프로세스의 상태가 전이되는 과정은? (프로세스 상태 전이도의 흐름은?) 32 | - 인터럽트(Interrupt)란? 33 | - 인터럽트의 종류에는 어떤 것들이 있을까? 34 | - 인터럽트가 동작하는 순서는 어떻게 될까? 35 | - 시스템 콜(System Call)이란? 36 | - 시스템 콜이 필요한 이유는? 37 | - 커널 모드(Kernel mode)와 사용자 모드(User mode)란? 38 | - 시스템의 성능을 어떤 기준으로 측정할까? 39 | - (참고) 용어 40 | - 스케줄링의 주기에 따라 3가지로 나눈다면 어떻게 나뉠까? 41 | - 선점형 스케줄링과 비선점형 스케줄링의 차이? 42 | - 자원 관리에 있어서 time sharing과 space sharing의 차이는? 43 | - FCFS(First Come First Service)란? 44 | - Round Robin이란? 45 | - SPN(Shortest Process Next)이란? 46 | - SRTN(Shortest Remaining Time Next)란? 47 | - HRRN(High Response Ratio Next)이란? 48 | - MLQ(Multi Level Queue)란? 49 | - MFQ(Multi level Feedback Queue)란? 50 | 51 | 동기화 52 | 53 | - 동기화란? 54 | - 동기화가 필요한 이유는? 55 | - Critical section(임계 구역)이란? 56 | - Race condition(경쟁 상태)이란? 57 | - Mutual exclusion(상호 배제)이란? 58 | - Mutual exclusion에 사용되는 기본 연산(primitive)의 조건은? 59 | - Mutual exclusion을 SW로 구현한 알고리즘에는 어떤 것들이 있나? 60 | - Dekker's algorithm을 설명해본다면? 61 | - Dekker's algorithm을 더 자세히 설명해본다면? (간단하게 코드로 표현해본다면?) 62 | - SW로 구현한 상호 배제 알고리즘의 단점은? 63 | - HW로 구현한 상호 배제 알고리즘에는 어떤 것들이 있나? 64 | - TAS(TestAndSet)란? 65 | - TAS를 이용해 ME가 보장되는 과정을 조금 더 자세히 설명? (코드로 설명?) 66 | - OS로 구현한 상호 배제 알고리즘에는 어떤 것들이 있나? 67 | - 스핀락이란? 68 | - 스핀락은 어떤 특성의 프로세스에서 사용하기 적절할까? 69 | - 뮤텍스란? 70 | - 뮤텍스는 어떤 상황에서 사용하기 적절할까? 71 | - 스핀락과 뮤텍스의 차이점은? 72 | - 세마포어란? 73 | - 세마포어에 사용되는 연산의 종류와 그 로직은? 74 | - 스핀락/뮤텍스와 세마포어의 차이는? 75 | 76 | 데드락 77 | 78 | - 데드락(dead lock, 교착 상태)이란? 79 | - 데드락이 발생하기 위한 조건은? 80 | - 데드락을 처리하는 방법은? 81 | - 데드락 회피 알고리즘 중 하나를 설명해본다면? 82 | - 데드락 탐지 알고리즘 중 하나에 대해 설명해본다면? 83 | 84 | 가상 메모리 85 | 86 | - 가상 메모리란? (메모리 가상화란?) 87 | - 메모리의 가상화가 필요한 이유는? 88 | 89 | 주소 변환(address translation) 90 | 91 | - 주소 변환이란? 92 | - 주소 변환이 필요한 이유는? 93 | - 주소 변환을 구현한 기술에는 어떤 것이 있는지? 94 | - base and bound란? 95 | - 베이스 레지스터란? 96 | - 바운드 레지스터(bound register)란? 97 | - 바운드 레지스터가 타 프로세스 메모리 침범을 막는 방법은? 98 | - base and bound에서 운영체제의 역할은? 99 | - base and bound에서 프로세스의 주소 공간을 옮기려면 어떻게 해야 하나? 100 | - base and bound의 장단점은? 101 | - base and bound의 내부 단편화 문제란? 102 | 103 | 세그멘테이션(segmentation) 104 | 105 | - 세그멘테이션이란? 106 | - 세그먼트란? 107 | - 세그멘테이션에서 가상 주소로부터 물리 주소를 얻는 과정은? 108 | - 세그먼트의 바운드 레지스터의 역할은? 109 | - 하드웨어가 가상 주소에서 세그먼트의 종류와 오프셋을 파악하는 방법은? 110 | - 가상 주소 변환에 있어서 스택과 나머지 종류의 세그먼트 간 차이는? 111 | - 하드웨어는 세그먼트가 어느 방향으로 확장해야 하는지 어떻게 알 수 있을까? 112 | - 세그멘테이션이 메모리 공유를 지원하는 방법은? 113 | - 세그멘테이션을 위한 운영체제의 역할은? 114 | - 세그먼트 테이블이란? `보충` 115 | - 세그멘테이션의 장단점은? 116 | - 외부 단편화란? 117 | - 외부 단편화에 대한 대응 방안은? 118 | - 압축이란? 진행되는 과정은? 119 | - 압축의 단점은? 120 | - 빈 공간 리스트를 관리하는 알고리즘에는 어떤 것들이 있으며, 각각의 장단점은? 121 | 122 | 페이징(Paging) 123 | 124 | - 페이징이란? 125 | - 페이징이 등장하게 된 배경은? 126 | - 페이징의 장단점은? 127 | - 페이징에서 물리 메모리의 구성은 어떻게 다른가? 128 | - 페이지 테이블(page table)이란? 129 | - 페이지 테이블 엔트리(PTE, Page Table Entry)란? 130 | - PTE의 구성 요소에는 어떤 것들이 있는지? 131 | - 페이징의 가상 주소에서 물리 주소를 얻어내는 과정은? 132 | - 현재 실행 중인 프로세스의 페이지 테이블 위치를 어떻게 알 수 있을까? 133 | 134 | TLB 135 | 136 | - TLB(Translation-Lookaside Buffer, 변환-색인 버퍼)란? 137 | - TLB가 필요한 이유는? 138 | - TLB가 도입된 상태에서 가상 메모리 참조 시 일어나는 과정은? 139 | - (TLB의) 지역성 2종류와 적용된 예시에 대해 설명? 140 | - TLB 미스를 처리하는 방법에는 어떤 것들이 있을까? 141 | - TLB 미스 트랩 핸들러가 실행될 때 TLB 미스가 나지 않도록 대응 방안? 142 | - TLB Cache가 설계된 방식은? (cache의 associativity와 관련하여) 143 | - TLB 각 항목의 구성은? 144 | - 페이지 테이블의 valid bit와 TLB의 valid bit 간 차이점은? 145 | - TLB에는 여러 VPN이 공존할 수 있다. 하지만 그럴 경우 여러 프로세스 간 VPN을 구분할 수 없다. 이에 대한 방안은? 146 | - 캐시 교체 정책에는 어떤 것들이 있나? 147 | - LRU란? 148 | - Random 정책이란? 장단점은? 149 | - TLB coverage를 벗어난다는 것의 의미는? 150 | 151 | 스와핑(Swapping) 152 | 153 | - 스와핑이란? 154 | - swap in과 swap out에 대해 설명? 155 | - page fault란? 156 | - 스와핑이 지원되는 상황에서 메모리가 참조되는 과정을 설명? 157 | - 운영체제가 Page fault를 처리하는 과정은? 158 | - 운영체제가 페이지 교체(스왑) 알고리즘을 작동시키는 시기는? 159 | - 페이지 교체(스왑) 알고리즘이 작동될 때(즉, 여유 공간이 최솟값보다 적어질 때) 일어나는 일은? 160 | 161 | Blocking/Non-Blocking & Synchronous/Asynchronous 162 | 163 | - Blocking과 Non-Blocking의 차이점? 164 | - Synchronous와 Asynchronous의 차이점? 165 | - Blocking + Sync 조합에 대해 설명해본다면? 166 | - Non-Blocking + Sync 조합에 대해 설명해본다면? 167 | - Blocking + Async 조합에 대해 설명해본다면? 168 | - Non-Blocking + Async 조합에 대해 설명해본다면? 169 | 170 | ## 운영체제 171 | 172 | ### 운영체제란? 173 | 174 | 하드웨어와 응용 프로그램 사이에서 인터페이스로서 시스템의 동작을 제어하는 시스템 소프트웨어. 175 | 176 | --- 177 | 178 | ### 운영체제의 역할은? 179 | 180 | - 자원의 관리와 보호 181 | - 하드웨어 인터페이스, 사용자 인터페이스 제공 182 | 183 | ## 프로세스와 스레드 184 | 185 | ### 프로세스란? 186 | 187 | - 메모리에 탑재되어(커널에 등록되어) 실행되고 있는 프로그램. 188 | - 운영체제로부터 자원을 할당 받는 작업의 단위. 189 | 190 | > - CPU는 한 번에 하나의 프로세스만 실행 가능하다. 191 | > - 프로그램: 실행할 수 있는 파일. 디스크에 저장되어 있지만, 메모리에는 올라가 있지 않은 정적인 상태의 파일. 192 | 193 | > 프로세스와 자원의 차이점은? 194 | > 195 | > - 자원은 프로세스에게 할당되고, 프로세스에 의해 반납되는 수동적 객체이다. 196 | > - 프로세스는 자원을 요청하고, 할당하고, 반납할 수 있는 능동적 객체이다. 197 | 198 | > 프로세스와 작업(job)의 차이점은? 199 | > 200 | > - job은 프로그램과 그 프로그램이 사용할 데이터를 의미한다. 201 | > (커널에 등록되기 전 디스크에 상주하는 상태) 202 | > - 프로세스는 실행을 위해 커널에 등록된 상태의 job이다. (메모리에 상주) 203 | 204 | --- 205 | 206 | ### 메모리는 어떻게 구성되어 있을까? 207 | 208 | ![OS%20e8aed882f45845d1a8fe27f71d71571b/Untitled.png](OS%20e8aed882f45845d1a8fe27f71d71571b/Untitled.png) 209 | 210 | 낮은 주소(위)부터 차례로 - 211 | 212 | - code(text) 213 | - 프로그램의 코드 자체. (Hex 파일이나 Bin 파일로 구성되어 있다.) 214 | - data 215 | - 전역 변수, 정적 변수, 배열, 구조체 등이 저장. 216 | - heap 217 | - 메모리를 동적으로 할당할 때 사용하는 영역. 218 | - 낮은 주소에서 높은 주소로 확장해나감. 219 | - (unused memory) 220 | - heap과 stack 사이에 존재 221 | - stack 222 | 223 | - 프로그램이 임시적으로 사용하는 영역. 224 | - 지역 변수 등이 저장. 225 | - 높은 주소에서 낮은 주소로 확장해나감. 226 | 227 | > - UNIX 시스템은 실행 중인 프로세스에게 4GB의 가상 메모리 공간을 할당한다. 228 | > - 상위 1GB는 커널이, 하위 3GB는 사용자 프로그램이 차지한다. 229 | 230 | > - code와 data 영역은 컴파일 단계에서 크기가 결정되는 정적 메모리 영역, heap과 stack은 런타임 단계에서 크기가 결정되는 동적 메모리 영역이다. 231 | > - heap이 stack을 침범하면 heap overflow, stack이 heap을 침범하면 stack overflow라고 한다. 232 | 233 | --- 234 | 235 | ### 스레드란? 236 | 237 | - 프로세스가 할당 받은 자원을 사용하는 실행의 단위 238 | - CPU의 최소 작업 단위 239 | 240 | > - "실행 단위": CPU에서 실행하는 하나의 단위. 프로세스와 스레드를 포괄하는 개념이다. 만약 프로세스 내부가 여러 스레드로 구분되어 있지 않다면, 이때의 실행 단위는 프로세스가 된다. 241 | 242 | --- 243 | 244 | ### 스레드가 필요한 이유는? (스레드의 장점은?) 245 | 246 | - 같은 프로세스 내 다른 스레드 간 context switching에 비용이 적게 든다. 247 | - 스레드를 새로 생성하는 데 더 적은 비용이 든다. 248 | - 다른 스레드가 지연되더라도 다른 스레드에 의해 작업이 계속될 수 있다. 249 | (반응성이 좋다.) 250 | 251 | > 프로세스보다 스레드 간 context switching이 더 적은 비용이 드는 이유: 스레드는 stack을 제외한 모든 메모리 영역을 공유하기 때문에, context switching 발생 시 stack 영역만 변경하면 되기 때문이다. 252 | 253 | --- 254 | 255 | ### 프로세스와 스레드의 차이점은? 256 | 257 | 프로세스 258 | 259 | - 자원을 할당 받을 때, 다른 프로세스와 독립된 메모리 공간을 할당 받는다. 260 | 261 | > - 프로세스는 기본적으로 서로의 데이터에 접근할 수 없다. 단, IPC를 사용하면 가능하다. 262 | > - 프로세스는 최소 1개의 스레드(→ 메인 스레드)를 가지고 있다. 263 | 264 | 스레드 265 | 266 | - 자원을 할당 받을 때, 자신이 위치한 프로세스 내에서 stack만 따로 할당 받고, 나머지 code, data, heap 영역은 같은 프로세스 내의 다른 스레드와 공유한다. 267 | 268 | > - 때문에, 특정 스레드 하나에서 오류가 발생하면, 자원을 공유하고 있는 프로세스 내 다른 스레드가 모두 강제 종료된다. 269 | > - 스레드가 스택만 따로 할당 받는 이유: 스택은 함수에 전달되는 인자, 지역변수 등이 저장되는 공간으로, 스택이 독립적으로 할당되면 독립적인 함수 호출이 가능하다는 것이고, 이는 독립적인 실행 흐름이 추가되는 것이다. 스레드의 정의에 따라, 최소 실행 흐름으로 동작하기 위한 최소한의 조건으로 스택을 할당하는 것이다. 270 | 271 | --- 272 | 273 | ### 스레드를 지원하는 주체에 따라 나눈다면 어떻게 나뉠까? 274 | 275 | ![OS%20e8aed882f45845d1a8fe27f71d71571b/thread-by-level.png](OS%20e8aed882f45845d1a8fe27f71d71571b/thread-by-level.png) 276 | 277 | 사용자 레벨 스레드 278 | 279 | - 사용자 영역에서 스레드 라이브러리로 구현되는 스레드. 280 | 281 | > - 커널은 사용자 레벨 스레드의 존재를 알지 못한다. 282 | > - 스레드 라이브러리는 커널에 의존적이지 않은 형태로 스레드의 기능을 제공한다. 283 | 284 | 커널 레벨 스레드 285 | 286 | - 커널에 의해 직접 관리되는 스레드. 287 | 288 | > - 커널에 종속적이다. 289 | > - 스레드를 생성하고 스케줄링하는 주체가 커널이다. 290 | 291 | --- 292 | 293 | ### 사용자 레벨 스레드의 장단점? 294 | 295 | 장점 296 | 297 | - 스케줄링이나 동기화가 커널에 의해 관리되지 않으므로, 스레드 관리에 대한 오버헤드가 적다(context switching을 위한 오버헤드가 없다). 298 | - (커널은 스레드의 존재조차 모르기 때문에) 모드 간 전환이 없어 성능상 이점을 가진다. 299 | - 사용자 영역에서 구현되므로, OS나 커널의 종류와 관계 없이 높은 이식성을 가진다. 300 | - 동일 메모리 내에서 생성/관리되므로(별도의 스택 할당 없이) 속도가 빠르다. 301 | 302 | 단점 303 | 304 | - 커널에 의해 관리되지 않으므로, 하나의 스레드가 입출력 등으로 중단/지연될 경우 나머지 스레드들도 함께 기다려야 한다. (커널은 스레드의 존재를 모르므로, 하나의 프로세스로 인식한다. 따라서 하나의 스레드가 중단되면 같은 프로세스 내 다른 스레드가 모두 중단된다.) 305 | - 스케줄링 우선순위를 지원하지 않는다(즉, 어떤 스레드가 먼저 동작할지 알 수 없다). 306 | 307 | --- 308 | 309 | ### 커널 레벨 스레드의 장단점? 310 | 311 | 장점 312 | 313 | - 하나의 스레드가 입출력 작업 등으로 중단/지연되어도 같은 프로세스 내의 다른 스레드들이 계속 실행 가능하다. 314 | 315 | 단점 316 | 317 | - 스케줄링과 동기화 등을 위해 커널을 호출하므로, 스레드 관리에 오버헤드가 들고 오래 걸린다. 318 | 319 | > ex) 디스크 입출력은 어떤 레벨 스레드에서 처리해야 효율적일까? 320 | > : 디스크 I/O를 위해서는 커널을 호출(시스템 콜)해야 하는데, 유저 레벨 스레드의 경우 시스템 콜마다 같은 프로세스 내 모든 스레드가 실행 중지될 것이다. 반면 커널 레벨 스레드는 커널에 의해 스레드가 관리되므로 다른 스레드가 실행 중지되지 않는다. 따라서 커널 레벨 스레드가 유리하다. 321 | 322 | --- 323 | 324 | ### 멀티 프로세스와 멀티 스레드의 차이점은? 325 | 326 | 멀티 프로세스 327 | 328 | : 하나의 작업을 여러 개의 프로세서(CPU)로 구성해, 각 프로세스가 작업을 병렬적으로 수행하는 것. 329 | 330 | 장점 331 | 332 | - 각 프로세스가 독립적이기 때문에, 하나의 프로세스가 다른 프로세스에 영향을 주지 않는다. 333 | - 동기화 작업이 필요하지 않다. 334 | 335 | 단점 336 | 337 | - 각 프로세스가 개별 메모리를 차지하기 때문에 자원을 많이 소모한다. 338 | - Context Switching 비용이 크다. 339 | - 프로세스 간 IPC를 통해 통신해야 한다. 340 | 341 | 멀티 스레드 342 | 343 | : 하나의 응용 프로그램/프로세스를 여러 스레드로 구성해, 각 스레드가 하나의 작업을 처리하도록 하는 것. 344 | 345 | 장점 346 | 347 | - 자원을 공유하기 때문에, 통신 비용이 들지 않으며 비교적 자원을 효율적으로(적게) 소모할 수 있다. 348 | - Context Switching이 빠르고 비용이 적다. 349 | 350 | 단점 351 | 352 | - 메모리를 공유하기 때문에, 동기화 작업이 필요하다. 353 | - 하나의 스레드에 오류가 생기면 전체 스레드가 실행 중지된다. 354 | 355 | > - 멀티 프로세스와 멀티 스레드는 모두 (한 어플리케이션에 대한) "처리 방식"의 일종이다. 356 | > - 멀티 태스킹/멀티 프로그래밍: 메모리에 여러 프로그램을 올려 실행하는 것. 프로세서가 특정 프로세스를 처리할 때 I/O로 인한 idle 등 낭비되는 시간동안 다른 프로세스를 처리한다. 작업이 동시에 진행되고 있는 것처럼 느끼게 해준다(동시성, concurrency) 357 | 358 | > 각각의 처리 방식이 어떤 시스템에 적합할지 상상해보자. 359 | 360 | ## 스케줄링 361 | 362 | ### Context Switching(문맥 교환)이란? 363 | 364 | 현재 진행하고 있는 task를 멈추고(CPU를 회수하고), 다른 task에게 CPU를 할당해 작업을 수행하는 과정이다. 365 | 366 | > - CPU는 한번에 하나의 프로세스만 처리할 수 있다. 367 | > - task: OS에서 처리하는 작업, 또는 명령어 집합. 프로세스나 스레드 등을 포함. 368 | 369 | --- 370 | 371 | ### Context Switching이 필요한 이유는? 372 | 373 | 멀티 프로그래밍을 구현하기 위해 필요하다. 즉, 하나의 프로세스가 시스템 콜 등으로 지연되는 동안 다른 프로세스로 전환해 CPU의 활용 시간을 늘리기 위해 필요하다. 374 | 375 | > Context Switching에는 오버헤드가 발생한다. 그럼에도 번거롭게 수행하는 이유는, 오버헤드가 발생함에도 CPU 활용성을 높이는 것이 더 이득이기 때문이다. 376 | 377 | --- 378 | 379 | ### Context Switching이 진행되는 과정은? 380 | 381 | 1. 커널이 레지스터에 있는 현재 프로세스의 Context를 PCB에 저장한다. 382 | 2. 다음 프로세스의 Context를 PCB로부터 읽어와 레지스터에 적재한다. 383 | 384 | > - 레지스터: 메모리 계층의 최상위에 위치. 가장 빠른 속도로 접근 가능한 메모리. CPU가 요청을 처리하는 데 필요한 데이터를 일시적으로 저장하는 기억 장치. 385 | > - Context: 프로세스에 대한 정보들의 모음 386 | 387 | --- 388 | 389 | ### Context에는 어떤 정보들이 있을까? 390 | 391 | - pid: 프로세스 id 392 | - Process State: 프로세스 상태 393 | - Process Counter: 다음에 실행할 명령어의 주소값 394 | 395 | 등이 있다. 396 | 397 | --- 398 | 399 | ### Context Switching는 어떤 상황에서 진행될까? 400 | 401 | - I/O 등으로 인해 Interrupt/Block이 발생했을 때 402 | - 실행 중인 프로세스가 허가 받은 CPU 사용 시간(`time quantum` / Round Robin 참고)을 모두 소모했을 때 403 | 404 | --- 405 | 406 | ### PCB(Process Control Block)란? 407 | 408 | OS가 프로세스를 관리할 때 필요한 정보들을 저장해놓는 곳. 409 | 410 | > - PCB는 프로세스가 생성될 때 함께 생성된다. 411 | > - PCB는 커널이 상주하는 메모리에 함께 상주한다. 412 | > - 프로세스 종료 후 대부분의 PCB는 제거되지만, 몇몇 PCB는 커널이 상주하는 메모리에 함께 남아있다. 이는 추후 프로세스 관리에 사용된다. 413 | 414 | --- 415 | 416 | ### PCB가 가지고 있는 정보에는 어떤 것들이 있을까? 417 | 418 | - process id(PID): 프로세스의 고유번호 419 | - process state: created, ready, running, block 등의 상태 420 | - program counter: 다음에 실행될 명령어를 가리킨다. 421 | 422 | 등이 있다. (이하 생략) 423 | 424 | --- 425 | 426 | ### 프로세스의 상태가 전이되는 과정은? (프로세스 상태 전이도의 흐름은?) 427 | 428 | ![OS%20e8aed882f45845d1a8fe27f71d71571b/Untitled%201.png](OS%20e8aed882f45845d1a8fe27f71d71571b/Untitled%201.png) 429 | 430 | **created** 431 | 432 | job이 커널이 등록되었을 때의 상태. 433 | 434 | > - 프로세스가 생성되고, 프로세스에 PCB가 할당된다. 435 | > - 이 때, 커널은 가용한 메모리 공간이 있는지 확인해서 프로세스 상태(ready/suspended)를 결정한다. 436 | 437 | **ready** 438 | 439 | 프로세스에 프로세서를 제외한 모든 필요한 자원이 할당된 상태. 440 | 441 | > - dispatch(schedule): 프로세서 할당, running 상태로 전이. 442 | > - ready 상태의 프로세스는 즉시 실행 가능한 상태이다. 443 | 444 | **running** 445 | 446 | 프로세스에게 필요한 모든 자원이 할당된 상태. 447 | 448 | > - preemption: 다른 프로세스에게 프로세서를 선점당하는 것. ready 상태로 전이. 449 | > preemption은 time-out, priority 등의 이유로 process scheduling에 의해 발생한다. 450 | > 451 | > - sleep(block): I/O 등의 자원 할당 요청이 완료될 때까지 기다리는 것. asleep 상태로 전이. 452 | > - exit: 모든 자원을 반납하고 프로세스를 종료. 453 | 454 | **blocked(asleep)** 455 | 456 | 프로세서가 아닌 다른 자원의 할당을 기다리고 있는 상태. 457 | 458 | > - wake-up: ready 상태로 전이. 459 | > 460 | > - 시스템 콜에 의해 자원 할당이 완료될 수 있다. 461 | > - 물론 프로세서 역시 할당이 되어있지 않은 상태이다. 462 | 463 | **Suspended** 464 | 465 | 메모리를 빼앗긴 상태. 466 | 467 | > - 디스크로 swap-out된 상태. 468 | > - suspended ready: ready 상태에 있던 프로세스가 디스크로 swap-out 469 | > - suspended blocked: blocked 상태에 있던 프로세스가 디스크로 swap-out 470 | 471 | **terminated** 472 | 473 | 프로세스 실행이 완료되어 모든 자원을 반납한 상태. 474 | 475 | --- 476 | 477 | ### 인터럽트(Interrupt)란? 478 | 479 | 프로그램을 실행하는 도중에 예기치 않은 상황이 발생했을 경우, 현재 실행 중인 작업을 중단하고, 발생한 상황을 처리한 후 다시 실행 중이었던 작업으로 복귀하는 것. 480 | 481 | > 예시: 프로그램 실행 중 사용자가 키보드를 입력, I/O block 등 482 | 483 | --- 484 | 485 | ### 인터럽트의 종류에는 어떤 것들이 있을까? 486 | 487 | 내부 인터럽트: 잘못된 명령이나 데이터를 사용했을 때 발생. 488 | 489 | 외부 인터럽트: 외부 전원이나 기계적으로 이상이 생겼을 때 발생. 490 | 491 | 소프트웨어 인터럽트: 소프트웨어가 발생시키는 인터럽트. 소프트웨어에 예외가 발생하거나, 시스템 콜 등으로 인해 발생. 492 | 493 | 하드웨어 인터럽트: 하드웨어가 발생시키는 인터럽트. CPU 이외의 하드웨어 장치가 CPU에게 어떤 사실을 알려주거나 서비스를 요청할 때 발생. 494 | 495 | --- 496 | 497 | ### 인터럽트가 동작하는 순서는 어떻게 될까? 498 | 499 | 1. 인터럽트 발생 500 | 2. 프로그램 실행 중단: 실행 중이던 명령어까지 수행 후 중지한다. 501 | 3. 상태 보존: 현재 실행 중이던 프로그램의 상태를 PCB에 저장한다. 502 | 4. 인터럽트 처리 루틴 실행 503 | 5. 상태 복구: 인터럽트 처리가 끝나면, 실행 중이던 프로그램의 상태를 PCB로부터 복구한다. 504 | 6. 실행 재개: PC(Program Counter) 값을 활용해 이전까지 수행한 명령의 다음 명령을 수행한다. 505 | 506 | --- 507 | 508 | ### 시스템 콜(System Call)이란? 509 | 510 | 프로세스(혹은 응용 프로그램, 사용자)가 커널이 제공하는 서비스에 접근하기 위한 인터페이스. 511 | 512 | --- 513 | 514 | ### 시스템 콜이 필요한 이유는? 515 | 516 | 커널 영역의 기능을 사용자 모드가 사용하기 위해(즉, 프로세스가 하드웨어에 접근해 필요한 기능을 사용하기 위해) 필요하다. 517 | 518 | > - 커널에 관련된 작업(커널 모드를 통한 작업)은 반드시 시스템 콜을 통해 수행하도록 설계되어있다. 519 | > - 시스템 콜의 예시로는 blocked(asleep) 상태인 프로세스가 자원을 할당 받을 때 등이 있다. 520 | 521 | --- 522 | 523 | ### 커널 모드(Kernel mode)와 사용자 모드(User mode)란? 524 | 525 | - 커널 모드: 모든 자원(드라이버, 메모리, CPU 등)에 접근, 명령할 수 있는 상태 526 | - 사용자 모드: 사용자가 접근할 수 있는 영역을 제한하는 상태. 527 | 528 | > - 하드웨어의 mode bit가 `0`이면 커널 모드, `1`이면 사용자 모드이다. 529 | > - 커널 모드가 별도로 필요한 이유는, 커널에서 관리하는 중요한 자원들을 사용자가 접근하지 못하도록 하기 위함이다. 530 | 531 | --- 532 | 533 | ### 시스템의 성능을 어떤 기준으로 측정할까? 534 | 535 | - response time: 요청으로부터 응답까지 걸리는 시간 (또는, 하나의 작업을 처리하는 데 드는 시간) 536 | - throughput: 단위 시간 내 처리하는 작업의 수 537 | - resource utilization: 주어진 시간 내 자원이 활용되는 시간 538 | 539 | 시스템의 목적에 따라, 위 기준 중 우선순위를 정해 스케줄링 전략을 택해야 한다. 540 | 541 | --- 542 | 543 | ### (참고) 용어 544 | 545 | ![OS%20e8aed882f45845d1a8fe27f71d71571b/Untitled%202.png](OS%20e8aed882f45845d1a8fe27f71d71571b/Untitled%202.png) 546 | 547 | waiting time(대기 시간) 548 | : 작업이 큐에 도착하고 실행되기까지의 시간 549 | 550 | response time(응답 시간) 551 | : 작업이 큐에 도착하고 첫번째 응답하기까지의 시간 552 | 553 | burst time(실행 시간) 554 | : 작업이 실행되고, 실행 종료까지의 시간 555 | 556 | turn-around time(반환 시간) 557 | : 작업이 큐에 도착하고, 실행 종료까지의 시간 558 | 559 | --- 560 | 561 | ### 스케줄링의 주기에 따라 3가지로 나눈다면 어떻게 나뉠까? 562 | 563 | 장기, 중기, 단기 스케줄링으로 나눌 수 있다. 564 | 565 | 1. 장기 스케줄링 566 | 567 | - 저빈도로 발생하는 스케줄링. 568 | - 예시: job 스케줄링 569 | 570 | - 커널에 등록되는 job을 결정하는(레디 큐에 삽입할 프로세스를 결정하는) 스케줄링 571 | - 메모리 위에서 돌아가는 프로세스의 수를 조절한다. 572 | - 프로세스 상태 전이: `new` -> `ready` 573 | 574 | > 현대의 OS에서는 일반적으로 장기 스케줄러(job 스케줄러)를 두지 않는 것이 일반적이다. 과거에는 적은 양의 메모리로 인해 메모리를 선점하고 있는 프로세스의 수를 조절해야 했지만, 현대에는 프로세스가 시작되면 바로 메모리를 할당에 레디 큐에 넣어주게 된다. 575 | 576 | 2. 중기 스케줄링 577 | 578 | - 중간 빈도로 발생하는 스케줄링. 579 | 580 | - 예시: 메모리에 적재된 프로세스 수 (동적으로) 조절 581 | 582 | - 너무 많은 프로세스가 메모리에 적재되어 있는 경우 swap out 583 | - 중기 스케줄러는 처음으로는 blocked 상태의 프로세스를(blocked 상태의 프로세스는 당장 CPU를 획득할 가능성이 없기 때문이다.), 그래도 부족하면 ready 상태의 프로세스를 순서대로 swap out 한다. 584 | - 프로세스 상태 전이: `ready` <-> `suspended ready`, `blocked` <-> `suspended blocked` 585 | 586 | > 메모리에 너무 많은 수의 프로세스가 적재되어 있을 때 발생하는 일 587 | > 588 | > - 프로세스 당 보유하고 있는 메모리량이 극도로 적어진다. 589 | > - CPU 수행에 필요한 주소공간 조차 메모리에 올려놓기 힘들어진다. 590 | > - 디스크 I/O가 수시로 발생, 시스템의 성능이 심각하게 저하된다. 591 | 592 | 3. 단기 스케줄링 593 | 594 | - 고빈도로 발생하는 스케줄링. 595 | - 예시: 프로세스(또는 프로세서, CPU) 스케줄링 596 | - CPU를 할당할 프로세스를 결정 597 | - 고빈도(ms 이하의 시간단위)로 발생하므로, 성능에 가장 큰 영향을 준다. 598 | - 프로세스 상태 전이: `ready` -> `running` 599 | 600 | > - 스케줄링의 목적은 성능이다. 601 | 602 | --- 603 | 604 | ### 선점형 스케줄링과 비선점형 스케줄링의 차이? 605 | 606 | 선점형 스케줄링: 할당된 자원이 다른 프로세스에 의해 선점될 수 있다. 607 | 608 | - 장점: 짧은 응답 시간 609 | - 단점: 잦은 context switching로 높은 오버헤드 610 | - real time system에 적합하다. 611 | 612 | 비선점 스케줄링: 할당된 자원을 스스로 반납할 때까지 사용. 613 | 614 | - 장점: 저빈도로 발생하는 context switching으로 낮은 오버헤드 615 | - 단점: 평균적으로 긴 응답 시간 616 | - batch system에 적합하다. 617 | 618 | > - batch system(일괄 처리): 사용자와의 상호작용 없이 실행할 수 있거나, 리소스가 허용되는 한 실행되도록 예약된 작업을 실행하는 것. 619 | 620 | --- 621 | 622 | ### 자원 관리에 있어서 time sharing과 space sharing의 차이는? 623 | 624 | time sharing 625 | 626 | - 여러 사용처가 하나의 자원을 차례대로 사용하는 것. 627 | - 예: 여러 스레드가 하나의 스레드를 차례대로 사용 (→ 프로세스 스케줄링) 628 | 629 | space sharing 630 | 631 | - 여러 사용처가 하나의 자원을 나눠 동시에 사용하는 것. 632 | - 예: 여러 스레드가 하나의 메모리를 나눠서 동시에 사용 633 | 634 | --- 635 | 636 | ### FCFS(First Come First Service)란? 637 | 638 | ready queue에 도착한 순서대로 스케줄링하는 전략. 639 | 640 | - 비선점형 스케줄링 641 | 642 | 장점 643 | 644 | - resource utilization이 높다. (쉬지 않고 cpu가 사용되므로) 645 | - 스케줄링 overhead이 낮다. 646 | 647 | 단점 648 | 649 | - convoy effect: 오래 걸리는 작업 하나 때문에 다른 작업들도 덩달아 오래 걸리게 만드는 현상 650 | - response time이 평균적으로 길다. 651 | 652 | 적합한 시스템 653 | 654 | - interaction이 없는 batch system 655 | 656 | --- 657 | 658 | ### Round Robin이란? 659 | 660 | ready queue에 도착하는 시간을 기준으로 스케줄링하되, time quantum(제한 시간)이 넘어가면 자원을 반납하도록 하는 전략. 661 | 662 | - 선점형 스케줄링 663 | 664 | 장점 665 | 666 | - 특정 프로세스가 프로세서를 독점하는 것을 방지한다. 667 | - Response time이 짧아진다. (time quantum으로 인해 어느 프로세스도 일정 시간 이상 기다리지 않는다.) 668 | - 프로세스가 기다리는 시간이 CPU를 사용할 만큼 증가한다는 측면에서, 공정한 스케줄링으로 볼 수 있다. 669 | 670 | 단점 671 | 672 | - context switching 오버헤드가 높다. 673 | 674 | 적합한 시스템 675 | 676 | - interactive system 677 | - time-sharing system 678 | 679 | > time quantum과 성능의 관계 680 | > 681 | > 1. time quantum이 아주 클때 682 | > 683 | > - FCFS와 동일해진다. 684 | > 685 | > 2. time quantum이 아주 짧을 때 686 | > 687 | > - 마치 모든 프로세스가 프로세서를 동시에 사용하는 것처럼 보인다. 688 | > - 그러나 context switching 오버헤드가 너무 높아 현실적으로 불가능하다. 689 | 690 | --- 691 | 692 | ### SPN(Shortest Process Next)이란? 693 | 694 | burst time이 적은 프로세스를 우선적으로 스케줄링하는 전략. 695 | 696 | - 비선점형 스케줄링 697 | 698 | 장점 699 | 700 | - waiting time이 평균적으로 짧다. (burst time이 짧은 프로세스는 나중에 도착해도 바로바로 서비스) 701 | - 대부분의 프로세스에 대해 response time이 짧다. 702 | - 시스템 내 운용되는 프로세스의 수를 적게 유지할 수 있다. (-> context switching 오버헤드가 적고, 사용되는 메모리가 적다.) 703 | 704 | 단점 705 | 706 | - starvation: burst time이 긴 프로세스는 한없이 기다려야 한다. 707 | - burst time을 예측하는 것은 복잡하고 어렵다. 708 | 709 | > SJF(Shortest Job First)이라고도 한다. 710 | 711 | --- 712 | 713 | ### SRTN(Shortest Remaining Time Next)란? 714 | 715 | burst time이 적은 프로세스를 우선적으로 스케줄링하되, 더 짧은 burst time을 가진 프로세스가 준비되면 해당 프로세스를 서비스하는 전략. 716 | 717 | - 선점형 스케줄링 718 | 719 | 장점 720 | 721 | - SPN의 장점을 극대화: 짧은 waiting time, response time, 적은 프로세스 수 유지 722 | 723 | 단점 724 | 725 | - starvation 726 | - burst time을 예측해야 한다. 727 | - 추가로, 현재까지 남은 burst time(remaining time)을 tracking해야 한다. (→ 오버헤드) 728 | - context switching 오버헤드 729 | 730 | > SRTF(Shortest Remaining Time First)라고도 한다. 731 | 732 | --- 733 | 734 | ### HRRN(High Response Ratio Next)이란? 735 | 736 | response ratio가 높은 프로세스를 먼저 스케줄링하는 전략. 737 | 738 | - `response ratio = (waiting time + burst time) / burst time` 739 | 740 | 장점 741 | 742 | - aging concept가 도입: 프로세스의 waiting time을 스케줄링에 고려 743 | → starvation이 방지 744 | - SPN의 장점: 짧은 평균 waiting time, 대부분의 프로세스의 짧은 response time, 시스템 내 적은 프로세스 수 유지 745 | 746 | 단점 747 | 748 | - burst time 예측 필요 749 | 750 | --- 751 | 752 | ### MLQ(Multi Level Queue)란? 753 | 754 | 작업을, 우선 순위에 따라 나뉘어진 여러 개의 큐 중 하나에 넣고, 높은 우선 순위를 가지는 큐의 작업을 먼저 스케줄링하는 전략 755 | 756 | - 각각의 큐는 각자의 스케줄링 전략을 갖는다. 757 | - 한 번 큐에 들어간 작업은 위치를 옮길 수 없다. 758 | 759 | 장점 760 | 761 | - 높은 우선순위를 가지는 작업은 짧은 response time을 가진다. 762 | 763 | 단점 764 | 765 | - 여러 개의 큐를 운용 → 오버헤드 766 | - 낮은 우선순위를 가진 큐에 대해 stavation 발생 767 | 768 | --- 769 | 770 | ### MFQ(Multi level Feedback Queue)란? 771 | 772 | (MLQ와 동일) 작업을, 우선순위에 따라 나뉘어진 여러 개의 큐 중 하나에 넣고, 높은 우선순위를 가지는 큐의 작업을 먼저 스케줄링한다. 773 | 774 | 단, feedback에 따라 작업이 큐 사이를 옮겨다닐 수 있다. 775 | 776 | > - feedback에는 waiting time 등이 있으며, MFQ가 취하는 전략에 따라 다르다. 777 | 778 | 장점 779 | 780 | - burst time 등의 사전 정보 없이도 SPN, SRTN, HRRN 전략들의 장점을 취할 수 있다. 781 | - 평균적으로 짧은 waiting time 782 | - 대부분의 프로세스가 짧은 response time 783 | - 시스템 내 적은 수의 프로세스 유지 784 | 785 | 단점 786 | 787 | - 구현하기 어렵다. 788 | - 스케줄링 오버헤드가 크다. 789 | - 전략에 따라, 경우에 따라 낮은 우선순위의 작업은 여전히 starvation 발생 가능. 790 | 791 | ## 동기화 792 | 793 | ### 동기화란? 794 | 795 | 여러 프로세스(or 스레드)에 대해, 하나의 자원에 대한 사용 권한을 주거나 이용 순서를 조정하는 기법. 796 | 797 | --- 798 | 799 | ### 동기화가 필요한 이유는? 800 | 801 | 동일한 자원을 여러 프로세스(or 스레드)가 동시에 수정할 경우, 그 순서에 따라 의도치 않은 결과값이 나올 수 있기 때문이다. 802 | 803 | > - 다중 프로그래밍 환경에서는 기본적으로 프로세스들은 서로 엄격하게 구분되어 상호 간섭이 불가하지만, 프로세스들이 메모리를 공유하거나(공유 메모리) 다중 스레드를 지원하는 경우, 여러 프로세스 혹은 스레드가 공유된 자원에 접근하는 상황이 발생할 수 있다. 804 | 805 | --- 806 | 807 | ### Critical section(임계 구역)이란? 808 | 809 | 공유 자원에 접근하는 코드. 810 | 811 | > - 공유 자원(shared data, critical data): 둘 이상의 프로세스에 의해 공유되는 데이터. 812 | 813 | --- 814 | 815 | ### Race condition(경쟁 상태)이란? 816 | 817 | 조작의 순서에 따라 결과값이 달라질 수 있는 상태. 818 | 819 | --- 820 | 821 | ### Mutual exclusion(상호 배제)이란? 822 | 823 | 어떤 프로세스가 공유 데이터를 사용하고 있을 때, 다른 프로세스가 공유 데이터에 접근하지 못하도록 하기 위해 사용되는 알고리즘. 824 | 825 | --- 826 | 827 | ### Mutual exclusion에 사용되는 기본 연산(primitive)의 조건은? 828 | 829 | 1. Mutual exclusion: 어떤 프로세스가 공유 자원을 사용하고 있다면, 다른 프로세스는 해당 공유 자원에 접근할 수 없다. 830 | 831 | 2. Progress: 공유 자원을 사용하고 있는 프로세스 이외에는, 어떤 프로세스가 공유 자원에 접근하는 것을 막아서는 안된다. 832 | (공유 자원을 사용하고 있는 프로세스만 공유 자원 접근을 막을 수 있다.) 833 | 834 | 3. Bounded waiting: 프로세스는 한정된 시간 동안에만 공유 자원을 사용할 수 있다. 835 | 836 | --- 837 | 838 | ### Mutual exclusion을 SW로 구현한 알고리즘에는 어떤 것들이 있나? 839 | 840 | Dekker's algorithm 841 | 842 | --- 843 | 844 | ### Dekker's algorithm을 설명해본다면? 845 | 846 | - `flag` 변수로 어떤 프로세스가 Critical section(이하 CS)에 접근하기를 원한다는 것을 나타냄. 847 | - `turn` 변수로 누가 CS에 들어갈 차례인지 나타냄. 848 | 849 | - 두 개의 프로세스에 대한 상호 배제 알고리즘이다. (두 개 이상의 프로세스에는 적용 불가) 850 | 851 | --- 852 | 853 | ### Dekker's algorithm을 더 자세히 설명해본다면? (간단하게 코드로 표현해본다면?) 854 | 855 | ```c 856 | /* P0 */ 857 | flag[0] <- true // P0이 CS에 접근하길 바래요. 858 | while (flag[1]) { // P1이 CS에 접근하길 바라고 있다면, 859 | if (turn == 1) { // P1이 사용하고 있다면, 860 | flag[0] <- false // 우선은 P0이 CS에 접근하고 싶지 않다고 물러서요. 861 | while (turn == 1) {} // P1이 사용하고 있는 동안 기다려요. 862 | // 이 때 P1이 CS로부터 나오면서 turn을 0으로 만들어줘요. 863 | flag[0] <- true // P1이 CS로부터 나왔다면, P0이 다시 들어가고 싶다고 말해요. 864 | } 865 | } // P1이 CS에 접근하길 바라고 있지 않다면, 바로 CS에 접근해요 866 | 867 | /* ..CS.. */ 868 | turn <- 1 // turn을 1로 만들어주고 CS에서 나와요. 869 | flag[0] <- false // 사용을 끝냈으니 CS에 접근할 생각이 없다고 밝혀요. 870 | 871 | /* P1 */ 872 | // P0과 같은 흐름으로 진행.. (flag, turn 변수만 변경) 873 | ``` 874 | 875 | --- 876 | 877 | ### SW로 구현한 상호 배제 알고리즘의 단점은? 878 | 879 | - busy waiting: 다른 프로세스가 CS 접근을 끝낼 때까지 반복문을 돈다. 880 | → 비효율적 881 | - 구현하기 까다롭다. 882 | - 기본 연산 중에 선점될 수 있다. (OS에서 보장하는 atomic 연산이 아니므로) 883 | 884 | --- 885 | 886 | ### HW로 구현한 상호 배제 알고리즘에는 어떤 것들이 있나? 887 | 888 | - TAS(TestAndSet) 889 | 890 | --- 891 | 892 | ### TAS(TestAndSet)란? 893 | 894 | test와 set을 한 번에 수행할 수 있는 machine instruction. 895 | 896 | ```c 897 | boolean TestAndSet(boolean *target) { 898 | boolean temp = *target; // 이전의 값을 기록. 899 | *target = true; // target 값을 true로 변경 900 | return temp; // 이전 값을 반환 901 | } 902 | ``` 903 | 904 | machine instruction이기 때문에, 실행 중에 선점되지 않는다. 905 | 906 | --- 907 | 908 | ### TAS를 이용해 ME가 보장되는 과정을 조금 더 자세히 설명? (코드로 설명?) 909 | 910 | ```c 911 | // 최초에는 lock = false; 912 | while (TAS(lock)) {} // lock이 true일 동안에는 CS에 접근하지 못한다. 913 | // lock이 false일 경우에는, lock을 true로 set하고 CS에 접근한다. 914 | /* ..CS.. */ 915 | lock <- false // CS를 나올 때 lockㅇ 916 | ``` 917 | 918 | - 위 코드는 3개 이상의 프로세스가 존재할 때, bounded waiting을 위반한다. 919 | - N개의 프로세스에도 유효한 P 920 | 921 | --- 922 | 923 | ### OS로 구현한 상호 배제 알고리즘에는 어떤 것들이 있나? 924 | 925 | - Spinlock(스핀락) 926 | - mutex(뮤텍스) 927 | - Semaphore(세마포어) 928 | 929 | --- 930 | 931 | ### 스핀락이란? 932 | 933 | - 특정 자료구조를 lock하거나 unlock해서 CS에 대한 접근 권한을 관리하는 방법. 934 | (여기서 특정 자료구조란 integer 변수 등이 해당된다.) 935 | - 권한을 획득하기 전까지는 (공유 자원을 사용하려는 다른 프로세스가) busy waiting 상태로 대기하고 있다가 접근 권한을 얻으면 CS 수행 후 권한을 반납 936 | 937 | > - 무한 루프를 도는 것은, 최대한 다른 프로세스/스레드에게 CPU를 양보하지 않기 위함이다. 938 | > - 조금만 기다리면 공유 자원을 금방 쓸 수 있는데, 굳이 컨텍스트 스위칭을 해서 부하를 줄 필요가 없다는 컨셉이다. 939 | > - "스핀락"은 접근 권한을 관리하는 자료구조(정수값) 자체를 칭하는 단어이기도 하다. 940 | 941 | 장점 942 | 943 | - (무의미한 코드를 수행하며) busy waiting 상태로 CPU를 선점하고 있기 때문에, 권한을 얻는 대로 바로 빠르게 작업을 수행할 수 있다. 944 | 945 | 단점 946 | 947 | - 해당 프로세스의 CPU 선점 기간(busy waiting)동안 다른 프로세스의 작업이 지연될 수 있다. 948 | - 어떤 스레드가 lock을 오랫동안 유지한다면, busy waiting 중인 스레드가 오히려 CPU 시간을 더 많이 소모할 가능성이 있다. 949 | 950 | --- 951 | 952 | ### 스핀락은 어떤 특성의 프로세스에서 사용하기 적절할까? 953 | 954 | 프로세스가 빠르게 작업을 수행할 수 있을 때. 955 | (context switching은 비싼 작업이기 때문이다. 프로세스 간 빠르고 잦은 context switching이 이뤄질 때는 스핀락을 사용할 때 context switching 비용을 아낄 수 있다.) 956 | 957 | --- 958 | 959 | ### 뮤텍스란? 960 | 961 | - (스핀락과 동일하게) 특정 자료구조를 lock하거나 unlock해서 CS에 대한 접근 권한을 관리하는 방법. 962 | - (스핀락과는 다르게) 권한을 획득하기 전까지 sleep 상태로 대기하고 있다가 wake-up되면 다시 권한 획득을 시도한다. 963 | 964 | > 뮤텍스는 화장실(공유 자원), 화장실 키(lock), 화장실을 이용하려는 사람(스레드)을 비유로 이해할 수 있다. 965 | 966 | ```jsx 967 | // 수도 코드 968 | wait(mutex); 969 | /* 970 | ...critical section... 971 | */ 972 | unlock(mutex); 973 | ``` 974 | 975 | --- 976 | 977 | ### 뮤텍스는 어떤 상황에서 사용하기 적절할까? 978 | 979 | - 프로세스가 길게 처리해야 하는 작업을 많이 가지고 있을 때. 980 | 981 | --- 982 | 983 | ### 스핀락과 뮤텍스의 차이점은? 984 | 985 | - 스핀락은 권한을 획득할 때까지 busy waiting 상태로 기다린다. 986 | → 해당 프로세스가 cpu를 계속 점유하고 있다. 987 | - 뮤텍스는 권한을 획득할 때까지 sleep 상태로 대기한다. 988 | 989 | --- 990 | 991 | ### 세마포어란? 992 | 993 | 정수형 자료구조를 사용해 여러 개의 공유 자원에 대한 접근 권한을 관리하는 방법. 994 | 995 | > 세마포어는 여러 개의 화장실(공유 자원), 비어있는 화장실 개수를 나타내는 전광판(counter), 화장실을 이용하려는 사람(프로세스), 화장실을 이용하려는 사람이 대기하고 있는 줄(wait queue)을 비유로 이해할 수 있다. 996 | 997 | --- 998 | 999 | ### 세마포어에 사용되는 연산의 종류와 그 로직은? 1000 | 1001 | `initialization()` 1002 | 1003 | - 세마포어의 값을 사용 가능한 자원의 개수로 초기화 1004 | 1005 | `P()` (또는 `wait()`) 1006 | 1007 | - 세마포어 값이(즉, 사용 가능한 자원의 개수가) 0 이상이면, 값에서 1을 빼고 CS에 접근한다. 1008 | - 세마포어 값이 0이면, wait queue에서 기다린다. 1009 | - atomic 연산이다. 1010 | 1011 | `V()` (또는 `signal()`) 1012 | 1013 | - wait queue에 프로세스가 대기하고 있으면 그 중 하나를 깨운다. 1014 | - 세마포어 값에 1을 더한 뒤, CS로부터 나온다. 1015 | - atomic 연산이다. 1016 | 1017 | ```c 1018 | // 수도 코드 1019 | struct semaphore { 1020 | int count; 1021 | queueType queue; 1022 | } 1023 | 1024 | void semWait(semaphore s) { 1025 | s.count--; 1026 | if (s.count == 0) { 1027 | // 락이 걸리고, 공유 자원에 접근할 수 없음. 1028 | } 1029 | } 1030 | 1031 | void semSignal(semaphore s) { 1032 | s.count++; 1033 | if (s.count == 0) { 1034 | // 아직 락에 걸려 대기 중인 프로세스가 있음. 1035 | } 1036 | } 1037 | ``` 1038 | 1039 | --- 1040 | 1041 | ### 스핀락/뮤텍스와 세마포어의 차이는? 1042 | 1043 | - 스핀락/뮤텍스는 접근 권한을 관리하는 자료구조가 0과 1(혹은 그와 상응하는 boolean 값)만 값으로 가질 수 있어, 하나의 공유 자원에 대한 접근 권한만을 관리할 수 있다. 1044 | 반면, 세마포어는 접근 권한을 관리하는 자료구조가 정수형으로, 여러 개의 공유 자원에 대한 사용 가능 여부를 표현할 수 있다. 1045 | 1046 | - 스핀락/뮤텍스는 자원을 소유하고 있는 프로세스만이 자원을 해제할 수 있다. 1047 | 세마포어는 해당 자원을 소유하고 있지 않은 다른 프로세스가 세마포어를 해제할 수 있다. 1048 | 1049 | - 세마포어는 스핀락/뮤텍스가 될 수 있지만, 스핀락/뮤텍스는 세마포어가 될 수 없다. 1050 | (0과 1의 값만 가지는 세마포어를 이진 세마포어(binary semaphore)라고 부른다. 이를 스핀락, 혹은 뮤텍스처럼 사용할 수 있다.) 1051 | 1052 | > - 뮤텍스는 locking 메커니즘을, 세마포어는 signaling 메커니즘을 사용한다는 점에서 '뮤텍스는 이진 세마포어이다'라는 말은 엄격한 정의에서는 맞지 않다. 그러나 뮤텍스와 바이너리 세마포어가 거의 동일하게 작동한다는 점에서 일반적으로 '뮤텍스는 이진 세마포어이다'라고 알려져있다. 1053 | 1054 | ## 데드락 1055 | 1056 | ### 데드락(dead lock, 교착 상태)이란? 1057 | 1058 | 서로 원하는 자원이 상대방에게 할당되어 있어 두 프로세스가 무한정 wait 상태에 빠지는 상황. 1059 | 1060 | > - 대표적인 예제로 '식사하는 철학자 문제'가 있다. 1061 | > (https://m.blog.naver.com/hirit808/221788147057) 1062 | 1063 | --- 1064 | 1065 | ### 데드락이 발생하기 위한 조건은? 1066 | 1067 | 1. 상호 배제(Mutual exclusion) 1068 | 1069 | - 자원은 한 번에 한 프로세스만 사용할 수 있다. 1070 | 1071 | 2. 점유 대기(Hold and wait) 1072 | 1073 | - 최소한 하나의 자원을 점유하고 있으면서, 다른 프로세스에 할당된 자원을 추가로 점유하기 위해 대기하는 프로세스가 존재한다. 1074 | 1075 | 3. 비선점(No preemption) 1076 | 1077 | - 다른 프로세스에 할당된 자원은 사용이 끝날 때까지 강제로 빼앗을 수 없다. 1078 | 1079 | 4. 순환 대기(Circular wait) 1080 | 1081 | - 프로세스의 집합이 순환 형태로 자원을 대기하고 있어야 한다. 1082 | 1083 | > - 위 조건들은 데드락의 필요 조건이다. 즉, 데드락이 발생했다면 위 조건을 만족하지만, 위 조건을 만족한다고 데드락이 발생하는 것은 아니다. 1084 | 1085 | --- 1086 | 1087 | ### 데드락을 처리하는 방법은? 1088 | 1089 | 예방(prevention): 데드락 조건 중 하나를 제거하는 방법. (상호 배제, 점유 대기, 비선점, 순환 대기 중 하나를 부정) 1090 | 1091 | - 단점: 자원의 낭비가 심하다. 1092 | 1093 | 회피(avoidance): 데드락이 발생하지 않는 알고리즘을 적용한다. 1094 | 1095 | - 예시: Dijkstra의 은행원 알고리즘 1096 | 1097 | 탐지(detection): 데드락 탐지 알고리즘으로 데드락을 탐지한다. 1098 | 1099 | - 예시: 자원 할당 그래프 알고리즘(Resource-Allocation Graph Algorithm) 1100 | 1101 | 회복(recovery): 데드락을 일으킨 프로세스를 종료시키거나, 할당된 자원을 회수한다. 1102 | 1103 | 무시(ignorance) 1104 | 1105 | - 데드락으로 인한 성능 저하보다 회복하는 데 발생하는 성능 저하가 클 때. 1106 | 1107 | --- 1108 | 1109 | ### 데드락 회피 알고리즘 중 하나를 설명해본다면? 1110 | 1111 | Dijkstra의 은행원 알고리즘 1112 | 1113 | - 안정 상태를 유지할 수 있는 요청만 수락하고, 불안정 상태를 초래할 수 있는 요청은 거절함으로써 데드락을 회피하는 알고리즘. 1114 | 1115 | 안정 상태 1116 | 1117 | - '안전 순서열'이 존재하는 상태. 1118 | 즉, 시스템이 데드락을 일으키지 않으면서, 각 프로세스가 요구하는 최대 요구량만큼 자원을 할당해줄 수 있는 상태. 1119 | 1120 | 불안정 상태 1121 | 1122 | - '안전 순서열'이 존재하지 않는 상태. 1123 | - 데드락의 필요 조건. 1124 | (데드락은 불안정 상태이지만, 불안정 상태가 곧 데드락은 아니다) 1125 | 1126 | > 은행원 알고리즘이 수행되기 위해 유지해야 하는 정보 1127 | > 1128 | > - `Max`: 각 프로세스가 최대로 얼만큼의 자원을 요청할지 1129 | > - `Allocated`: 각 프로세스가 현재 요청한 자원이 얼마인지 1130 | > - `Available`: 현재 할당 가능한 자원이 얼마인지 1131 | 1132 | 단점 1133 | 1134 | - 최대 자원 요구량(Max)를 미리 알아야 한다. 1135 | - 자원 활용률이 낮다. (불안정 상태를 방지해야 하므로) 1136 | 1137 | --- 1138 | 1139 | ### 데드락 탐지 알고리즘 중 하나에 대해 설명해본다면? 1140 | 1141 | 자원 할당 그래프 알고리즘을 통해 데드락을 탐지할 수 있다. 1142 | 1143 | - 프로세스 P로부터 자원 R을 향하는 간선은, 프로세스 P가 자원 R을 요청하고 있음을 나타낸다. 1144 | - 자원 R로부터 프로세스 P로 향하는 간선은, 자원 R이 프로세스 P에 할당되었음을 나타낸다. 1145 | - 그래프를 생성한 후, 데드락 발생 조건을 점검한다. 1146 | 1147 | --- 1148 | 1149 | ## 가상 메모리 1150 | 1151 | ### 가상 메모리란? (메모리 가상화란?) 1152 | 1153 | 각 프로세스에게 실제 물리 메모리 주소가 아닌, 가상의 메모리 주소를 줌으로써 용량이 매우 큰 메모리처럼 보이게 하는 기법. 1154 | 1155 | --- 1156 | 1157 | ### 메모리의 가상화가 필요한 이유는? 1158 | 1159 | (디스크 같은 느리지만 큰 저장 장치를 활용해서) 한정된 메모리 크기를 극복해 애플리케이션(또는 프로세스)이 더 많은 메모리를 활용할 수 있게끔 해주기 위함. 1160 | 1161 | > 프로그램을 실행하기 위해서는 실행하려는 프로그램의 용량보다 더 큰 메모리가 필요하다. 그러나 메모리 접근은 순차적이고 지역화되어 있다는 특성 때문에, 프로그램을 실행하는데 완전한 용량이 필요해보이지만 실제로 필요한 메모리는 더 적다. 1162 | 1163 | --- 1164 | 1165 | ## 주소 변환(address translation) 1166 | 1167 | ### 주소 변환이란? 1168 | 1169 | 하드웨어를 통해 가상 주소를 실제 물리 주소로 변환하는 것. 1170 | 1171 | > - 주소 변환은 가상 메모리를 구현하는 간단한 방법 중 하나이다. 1172 | 1173 | --- 1174 | 1175 | ### 주소 변환이 필요한 이유는? 1176 | 1177 | 프로그램의 모든 메모리 참조를 실제 메모리 위치로 재지정하기 위해. 1178 | 1179 | --- 1180 | 1181 | ### 주소 변환을 구현한 기술에는 어떤 것이 있는지? 1182 | 1183 | - base and bound 1184 | 1185 | > - base and bound는 동적 재배치(dynamic relocation)이라고도 불리운다. 프로세스가 실행된 후에도(→ "동적") 주소를 변경할 수 있기 때문이다. 1186 | 1187 | --- 1188 | 1189 | ### base and bound란? 1190 | 1191 | 프로세스의 메모리 참조가 사용하는 가상 주소에 베이스 레지스터(base register) 값을 더해 실제 물리 주소 값을 구하는 방법. 1192 | 1193 | --- 1194 | 1195 | ### 베이스 레지스터란? 1196 | 1197 | 프로그램이 참조하는 가상 주소로부터 물리 주소를 얻기 위해 더해야 하는 주소 값을 가지고 있는 레지스터. 1198 | 1199 | > - 프로그램이 메모리에 접근할 때 offset을 얻어낼 수 있다. 이 offset은 베이스 레지스터가 가리키는 위치로부터 떨어진 만큼을 가리킨다. 1200 | > - 즉, `physical address = base register + offset` 1201 | 1202 | --- 1203 | 1204 | ### 바운드 레지스터(bound register)란? 1205 | 1206 | 다른 프로세스가 사용하는 메모리 침범을 막기 위한 레지스터. 1207 | 1208 | > - 베이스 레지스터와 바운드 레지스터는 하드웨어로 구현된다. 정확히는 CPU 내에, MMU(Memory Management Unit, 메모리 관리 장치)의 일부로서 제공된다. 1209 | > - 베이스 레지스터, 바운드 레지스터를 포함한 하드웨어만으로는 메모리 가상화를 구현할 수 없다. 운영체제의 도움이 필요하다. 1210 | 1211 | --- 1212 | 1213 | ### 바운드 레지스터가 타 프로세스 메모리 침범을 막는 방법은? 1214 | 1215 | - 가상 주소에 베이스 레지스터 값을 더해 물리 주소를 구한 후, 바운드 레지스터의 값으로 유효 범위를 확인한다. 1216 | - 바운드 레지스터는 해당 프로세스에게 할당된 메모리의 크기 값을 가지고 있다. 1217 | - 범위를 벗어난 주소로 접근을 시도하면, 하드웨어가 예외를 발생시킨다. 1218 | (오프셋 값이 바운드 레지스터 값보다 작은지 확인하면 된다.) 1219 | 1220 | > - 하드웨어가 발생시킨 에러는, 운영체제가 제공하는(제공해야 한다) 예외 핸들러에 의해 처리된다. 1221 | > - 바운드 레지스터는 할당된 메모리의 크기 값을 가지고 있다. 1222 | 1223 | --- 1224 | 1225 | ### base and bound에서 운영체제의 역할은? 1226 | 1227 | - 프로세스가 생성될 때, 저장될 메모리 공간을 찾는다. 1228 | - 이를 위해 운용되는 빈 공간 리스트(free list)에서 공간을 찾고, 사용 중이라 표시한다. 1229 | - 프로세스가 전환될 시, PCB에 베이스-바운드 레지스터 쌍을 저장하거나 복원한다. 1230 | 1231 | > - 운영체제를 실행시키기 위해 커널 모드를 실행해야 한다. 1232 | > - process state word 레지스터의 비트 중 일부가 CPU의 실행 모드를 나타낸다. 1233 | 1234 | --- 1235 | 1236 | ### base and bound에서 프로세스의 주소 공간을 옮기려면 어떻게 해야 하나? 1237 | 1238 | - 먼저 운영체제가 프로세스의 실행을 중지한다. 1239 | - 해당 프로세스의 PCB에 저장된 베이스 레지스터의 값을 갱신해 새로운 위치를 가리키도록 한다. 1240 | 1241 | --- 1242 | 1243 | ### base and bound의 장단점은? 1244 | 1245 | 장점 1246 | 1247 | - 베이스, 바운드 레지스터가 하드웨어로 구현되어 효율적이다. 1248 | 1249 | 단점 1250 | 1251 | - 내부 단편화 1252 | - 가상 주소 공간이 실제 물리 메모리 공간보다 큰 경우 실행이 매우 어렵다. 1253 | 1254 | --- 1255 | 1256 | ### base and bound의 내부 단편화 문제란? 1257 | 1258 | - 프로세스가 고정된 크기의 슬롯으로(→ 단편화되어) 물리 주소에 배치된다. 1259 | - 프로세스의 스택과 힙이 그닥 크지 않기 때문에, 낭비되는 공간이 크다. 1260 | 1261 | --- 1262 | 1263 | ## 세그멘테이션(segmentation) 1264 | 1265 | ### 세그멘테이션이란? 1266 | 1267 | 가상 메모리를 세그먼트로 분할하고 할당하는 메모리 관리 기법. 1268 | 1269 | > - Segmentation Fault는 세그멘테이션을 사용하는 시스템에서 불법적인 주소로 접근 시에 발생하는 에러이다. 1270 | 1271 | --- 1272 | 1273 | ### 세그먼트란? 1274 | 1275 | 서로 다른 길이를 가지는 연속적인 주소 공간. 1276 | 1277 | > - 3종류의 세그먼트가 존재한다: 코드, 힙, 스택. ('data'는 아님) 1278 | 1279 | --- 1280 | 1281 | ### 세그멘테이션에서 가상 주소로부터 물리 주소를 얻는 과정은? 1282 | 1283 | - 각 세그먼트마다 베이스-바운드 레지스터 쌍을 가지고 있다. 1284 | - 프로그램에서 접근하는 세그먼트의 메모리의 주소(offset)에, 베이스 레지스터 값을 더해 실제 물리 주소를 구한다. 1285 | (`physical address = offset + base register`) 1286 | 1287 | > - 즉, 하나의 프로세스는 3쌍의 베이스-바운드 레지스터를 가지고 있게 된다. 1288 | > - 하드웨어는 프로그램이 어떤 종류의 세그먼트에 접근하는 것인지 파악해야 한다. 1289 | > - 어떤 종류의 세그먼트에 접근하는 것인지 알게되면, 해당 종류의 세그먼트를 위한 베이스-바운드 레지스터를 참조할 수 있다. (예: 힙의 베이스-바운드 레지스터) 1290 | > - 하드웨어는 세그먼트 레지스터를 통해 세그먼트 주소를 가지고 있다. 1291 | 1292 | > 요약) 1293 | > 세그먼트 레지스터 → 가상 주소 1294 | > 가상 주소 = 최상위 2비트(→ 세그먼트 종류) + offset 1295 | > → 세그먼트 종류에 해당하는 베이스-바운드 레지스터 & offset 1296 | > → 물리 주소 1297 | 1298 | --- 1299 | 1300 | ### 세그먼트의 바운드 레지스터의 역할은? 1301 | 1302 | - 세그먼트의 크기를 가지고 있다. 1303 | - 프로그램이 메모리에 접근할 때, offset이 바운드 레지스터 값보다 작은지 확인해서 불법적인 메모리에 접근하지 않도록 한다. 1304 | 1305 | --- 1306 | 1307 | ### 하드웨어가 가상 주소에서 세그먼트의 종류와 오프셋을 파악하는 방법은? 1308 | 1309 | - 하드웨어는 세그먼트 레지스터를 통해 세그먼트의 가상 주소 값을 얻는다. 1310 | - 세그먼트의 종류를 파악하기 위해 가상 주소의 최상위 2비트를 사용한다. 1311 | - 최상위 2비트를 제외한 나머지 비트는 offset이 된다. 1312 | 1313 | > - 3종류의 세그먼트가 있으므로, 2비트를 사용해 00, 01, 10으로 3종류의 세그먼트를 가리킬 수 있다. 1314 | > 1315 | > - 다른 방법: '암묵적 접근' 방식도 있다. 주소가 어떻게 형성되었는지를 관찰해 세그먼트의 종류를 파악한다. 예를 들어, 주소가 Program Counter에서 생성되었다면 코드 세그먼트일 것이다. 1316 | 1317 | --- 1318 | 1319 | ### 가상 주소 변환에 있어서 스택과 나머지 종류의 세그먼트 간 차이는? 1320 | 1321 | 확장되는 주소의 방향이 다르다. 1322 | 1323 | - 스택은 높은 주소에서 낮은 주소로, 1324 | - 나머지 종류의 세그먼트(코드, 힙)은 낮은 주소에서 높은 주소로 확장한다. 1325 | - 양수 방향으로 증가하는지("`grows positive?`")를 나타내는 하드웨어를 통해 파악할 수 있다. 1326 | 1327 | --- 1328 | 1329 | ### 하드웨어는 세그먼트가 어느 방향으로 확장해야 하는지 어떻게 알 수 있을까? 1330 | 1331 | 세그먼트가 확장하는 방향을 담은 레지스터를 통해 파악한다. 1332 | (베이스-바운드 레지스터 이외의 추가적인 레지스터가 된다.) 1333 | 1334 | - 주소가 커지는 방향으로 확장하면(순방향) 1 (코드, 힙) 1335 | - 주소가 작아지는 방향으로 확장하면(역방향) 0을 저장한다. (스택) 1336 | 1337 | --- 1338 | 1339 | ### 세그멘테이션이 메모리 공유를 지원하는 방법은? 1340 | 1341 | - 세그먼트마다 protection bit를 통해, 해당 세그먼트가 읽을 수 있는지 / 쓸 수 있는지 / 실행시킬 수 있는지 나타낸다. 1342 | - 세그먼트를 읽기 전용으로 설정하면, 여러 프로세스가 해당 세그먼트를 공유할 수 있다. 1343 | 1344 | > - 읽기 전용 세그먼트에 쓰기를 시도하면, 하드웨어가 예외를 발생시킨다. 해당 예외는 운영체제가 처리할 수 있어야 한다. 1345 | 1346 | (참고) 1347 | 1348 | ![OS%20e8aed882f45845d1a8fe27f71d71571b/Untitled%203.png](OS%20e8aed882f45845d1a8fe27f71d71571b/Untitled%203.png) 1349 | 1350 | --- 1351 | 1352 | ### 세그멘테이션을 위한 운영체제의 역할은? 1353 | 1354 | - context switching 시 세그먼트 레지스터 값을 저장/복원 1355 | - 미사용 중인 물리 메모리 공간 관리 1356 | 1357 | --- 1358 | 1359 | ### 세그먼트 테이블이란? `보충` 1360 | 1361 | --- 1362 | 1363 | ### 세그멘테이션의 장단점은? 1364 | 1365 | 장점 1366 | 1367 | - 내부 단편화가 발생하지 않는다. 1368 | 즉, 가상 주소 공간이 물리 메모리를 불필요하게 차지하는 것을 방지할 수 있다. 1369 | - 하드웨어 구현에 적합 1370 | (세그먼트 레지스터, 베이스-바운드 레지스터, grows positive, protection bit 등) - 속도가 빠르다. - 구현이 쉽다. - 오버헤드가 적다. 1371 | 1372 | 단점 1373 | 1374 | - 외부 단편화 1375 | 1376 | --- 1377 | 1378 | ### 외부 단편화란? 1379 | 1380 | 작은 메모리(세그먼트)가 물리 메모리의 중간 중간에 위치해, 여유 메모리 공간은 충분하지만 실제로 할당할 수는 없는 현상. 1381 | 1382 | > - 외부 단편화는 가변 길이 할당의 태생적인 문제이다. 1383 | 1384 | --- 1385 | 1386 | ### 외부 단편화에 대한 대응 방안은? 1387 | 1388 | - '압축'(compact) 1389 | - 빈 공간 리스트를 관리하는 알고리즘을 사용 1390 | 1391 | --- 1392 | 1393 | ### 압축이란? 진행되는 과정은? 1394 | 1395 | 기존의 세그먼트를 정리해서 물리 메모리를 압축하는 것. 1396 | 1397 | - (현재 실행 중인 프로세스를 중단하고) 1398 | - 흩어진 프로세스 데이터들을 하나의 연속된 공간에 복사한다. 1399 | - (세그먼트 레지스터가 새로운 주소값을 가리키도록 한다.) 1400 | 1401 | --- 1402 | 1403 | ### 압축의 단점은? 1404 | 1405 | 비용이 크다. 1406 | 1407 | - 세그먼트 복사는 메모리에 부하가 큰 연산이다. 1408 | - 상당량의 프로세서 시간을 사용. 1409 | 1410 | --- 1411 | 1412 | ### 빈 공간 리스트를 관리하는 알고리즘에는 어떤 것들이 있으며, 각각의 장단점은? 1413 | 1414 | 최초 적합(first-fit): 가장 먼저 발견되는 빈 공간에 넣는다. 1415 | 1416 | - 장: 구현과 실행이 쉽다. 1417 | - 단: 나중에는 빈 공간을 찾기 점점 어려워진다. (외부 단편화, 무지성 할당에 가까우므로) 1418 | 1419 | 최적 적합(best-fit): 다 비교해보고, 가장 자투리 공간이 적게 남는 공간에 넣는다. 1420 | 1421 | - 장: 가장 적합한 공간을 선택하므로 외부 단편화가 발생할 확률이 적다. 1422 | - 단: 어디가 최적의 공간인지 확인하기 위한 cost가 든다. 1423 | 1424 | 최악 적합(worst-fit): 다 비교해보고, 가장 자투리 공간이 넓게 남는 공간에 넣는다. 1425 | 1426 | > - 최적 적합으로 할당하면 나중에는 자투리 공간이 엄청 조금 남게 되는데, 그건 아예 쓰지도 못하게 되지 않으니, 차라리 조금이나마 넓게 냅두어서 나중에라도 쓸 수 있게 하는 것이 낫다는 논리이다. 1427 | 1428 | 순차 최초 적합(next-fit): 이전까지 할당된 기록을 확인해서, 그 다음 공간부터 탐색을 시작해 가장 먼저 발견되는 빈 공간에 할당한다. 1429 | 1430 | - 장: 비어있을 확률이 높은 곳부터 탐색하므로 효율적이다. 1431 | - 단: 할당이 적합한지 고려하지 않기 때문에 외부 단편화가 발생할 확률이 높다. 1432 | 1433 | > - 메모리 할당법(할당 알고리즘)이라고도 불린다. 1434 | > - 빈 공간 관리 알고리즘은 할당 가능한 메모리 영역들을 리스트 형태로 유지한다. 1435 | 1436 | --- 1437 | 1438 | ## 페이징(Paging) 1439 | 1440 | ### 페이징이란? 1441 | 1442 | 메모리 공간을 고정된 크기의 단위(→ '페이지')로 분할하는 메모리 관리 기법. 1443 | 1444 | --- 1445 | 1446 | ### 페이징이 등장하게 된 배경은? 1447 | 1448 | - 메모리를 가변 길이로 할당하게 됨에 따라 외부 단편화가 발생. 1449 | - 고정 길이 할당을 통해 외부 단편화를 방지하기 위해 등장. 1450 | 1451 | --- 1452 | 1453 | ### 페이징의 장단점은? 1454 | 1455 | 장점 1456 | 1457 | - 유연성: 프로세스가 주소 공간을 어떻게 사용하는지에 대해 신경쓰지 않아도 됨. 1458 | (어떻게 사용되는가, 힙과 스택이 어느 방향으로 커지는가 등) 1459 | - 빈 공간 리스트 관리가 용이 1460 | (세그멘테이션이 알고리즘이나 압축으로 외부 단편화에 대응했던 것에 대비되어, 단순히 빈 공간 리스트의 첫 번째 항목을 할당해주면 된다.) 1461 | 1462 | 단점 1463 | 1464 | - 상당한 성능 저하를 일으킬 수 있다. 1465 | 가상 주소 변환을 위해서는 메모리에 상주하는 페이지 테이블을 읽어야 하는데, 메모리 읽기 작업은 성능 저하를 유발한다. (모든 load/store 명령에 추가적인 메모리 읽기가 수반) 1466 | 1467 | > - 페이징의 성능 저하를 개선하기 위한 방법으로 TLB(Translation-Lookaside Buffer)가 있다. 1468 | 1469 | --- 1470 | 1471 | ### 페이징에서 물리 메모리의 구성은 어떻게 다른가? 1472 | 1473 | - 물리 메모리도 고정 크기의 슬롯의 배열, 즉 "페이지 프레임(page frame)"로 취급된다. 1474 | - 각각의 슬롯에 하나의 가상 메모리 페이지를 저장할 수 있다. 1475 | 1476 | --- 1477 | 1478 | ### 페이지 테이블(page table)이란? 1479 | 1480 | (가상 주소 공간 내) 각 가상 페이지의 물리 주소(혹은, 주소 변환 정보)를 저장해놓는 자료구조. 1481 | 1482 | > - 페이지 테이블은 메모리에 저장되어 있다. (메모리 중에서도, 운영체제가 상주하는 메모리에 함께 상주한다.) 1483 | > - 페이지 테이블은 프로세스마다(프로세스 수만큼) 존재한다. 1484 | > - 운영체제가 다른 프로세스를 실행하려면, 해당 프로세스를 위한 다른 페이지 테이블이 필요하다.(새 프로세스의 가상 페이지는, 공유 중인 페이지가 없는 한 다른 물리 메모리에 존재할 것이다.) 1485 | 1486 | --- 1487 | 1488 | ### 페이지 테이블 엔트리(PTE, Page Table Entry)란? 1489 | 1490 | 페이지와 관련된 여러 정보를 담고 있는, 페이지 테이블의 구성 요소. 1491 | 1492 | --- 1493 | 1494 | ### PTE의 구성 요소에는 어떤 것들이 있는지? 1495 | 1496 | - Valid bit: 해당 메모리 공간이 할당된 공간인지 표시. 1497 | - Protection bit: 해당 페이지가 읽을 수 있는지, 쓸 수 있는지, 실행될 수 있는지를 표시. 1498 | - Present bit: 해당 페이지가 물리 메모리에 있는지, 디스크에 swap-out 되었는지를 표시. 1499 | 1500 | --- 1501 | 1502 | ### 페이징의 가상 주소에서 물리 주소를 얻어내는 과정은? 1503 | 1504 | - 가상 주소를 이진 형식으로 변환한다. 1505 | `"21" → "010101"` 1506 | - 이진 주소는 VPN(Virtual Page Number, 가상 페이지 번호)와 offset으로 나뉘어진다. 1507 | - VPN을 페이지 테이블의 인덱스로 사용해 PFN(Physical Frame Number)를 얻어낸다. 1508 | `"01" → [페이지 테이블] → "111"` 1509 | - PFN과 offset을 합쳐 물리 주소를 얻어낸다. 1510 | `"111" + "0101" → "1110101"("117")` 1511 | 1512 | - 오프셋은 변환되지 않는다. "페이지 내"에서의 위치를 나타내기 때문이다. 1513 | 1514 | --- 1515 | 1516 | ### 현재 실행 중인 프로세스의 페이지 테이블 위치를 어떻게 알 수 있을까? 1517 | 1518 | 페이지 테이블 베이스 레지스터(page table base register)에 페이지 테이블의 시작 주소(물리 주소)가 저장되어 있다. 1519 | 1520 | --- 1521 | 1522 | ## TLB 1523 | 1524 | ### TLB(Translation-Lookaside Buffer, 변환-색인 버퍼)란? 1525 | 1526 | 자주 참조되는 가상 주소와 - 실 주소 변환 정보를 저장하는 하드웨어 캐시. 1527 | 1528 | > - TLB는 하드웨어, CPU 내 MMU(Memory Management Unit, 메모리 관리부)에 위치한다. 1529 | 1530 | --- 1531 | 1532 | ### TLB가 필요한 이유는? 1533 | 1534 | 페이징의 성능 저하를 극복하기 위한 대안으로 등장했다. 1535 | 1536 | > - 페이징에서는 가상 주소 변환을 위해 메모리에 상주하는 페이지 테이블을 읽어야 하는데, 메모리 읽기 작업은 성능 저하를 유발한다. 1537 | 1538 | --- 1539 | 1540 | ### TLB가 도입된 상태에서 가상 메모리 참조 시 일어나는 과정은? 1541 | 1542 | - 가상 주소에서 VPN을 추출한다. 1543 | - 하드웨어는 해당 VPN으로 TLB에 원하는 변환 정보가 있는지 확인한다. 1544 | - 있다면(TLB hit), TLB 항목에서 PFN을 추출한다. 1545 | - PFN을 가상 주소의 offset과 합쳐 물리 주소를 구성하고, 메모리에 접근한다. 1546 | - 없다면(TLB miss), 하드웨어가 메모리의 페이지 테이블을 조회한다. 1547 | (page table base register로 페이지 테이블의 위치를 알 수 있다.) 1548 | - 주소 변환 정보를 TLB로 읽어들인다. 1549 | - TLB가 갱신되면, 하드웨어는 명령어를 재실행한다. 1550 | (재실행 되었을 때는 TLB가 갱신되어 TLB hit이 발생할 것이다.) 1551 | 1552 | --- 1553 | 1554 | ### (TLB의) 지역성 2종류와 적용된 예시에 대해 설명? 1555 | 1556 | 시간 지역성: 한번 참조된 메모리 영역이 짧은 시간 내에 다시 참조되는 현상. 1557 | 1558 | - ex) 반복문 내에서 같은 배열을 다시 사용 / 반복문 후 해당 배열을 바로 다시 사용. 1559 | 1560 | 공간 지역성: 참조된 메모리에 가까운 위치의 메모리 영역이 다시 참조되는 현상. 1561 | 1562 | - ex) 배열의 인자를 순회할 때, 페이지의 첫 번째 항목을 접근할 때만 TLB 미스가 발생. 1563 | 1564 | ![OS%20e8aed882f45845d1a8fe27f71d71571b/Untitled%204.png](OS%20e8aed882f45845d1a8fe27f71d71571b/Untitled%204.png) 1565 | 1566 | > - TLB hit rate = hit / accesses 1567 | 1568 | --- 1569 | 1570 | ### TLB 미스를 처리하는 방법에는 어떤 것들이 있을까? 1571 | 1572 | 1. 하드웨어가 처리 1573 | 1574 | - 하드웨어가 페이지 테이블에서 원하는 PTE를 찾는다. 1575 | - TLB에 읽어들여 TLB를 갱신한다. 1576 | - TLB 미스가 발생한 명령어를 재실행한다. 1577 | 1578 | 2. 소프트웨어가 처리 1579 | 1580 | - 하드웨어가 예외 시그널을 발생시킨다. 1581 | - 시그널을 감지한 운영 체제는 명령어 실행을 중지하고 실행 모드를 커널 모드로 변경한다. 1582 | - 운영체제는 '트랩 핸들러(trap handler)'를 실행. 1583 | - 트랩 핸들러는 페이지 테이블에서 원하는 PTE를 찾고, TLB 접근이 가능한 특권 명령어로 TLB를 갱신한다. 1584 | - 트랩 핸들러가 리턴되면 하드웨어가 명령어를 재실행한다. 1585 | 1586 | > - CISC 기반 하드웨어가 TLB 미스를 하드웨어가 처리하고, RISC 기반 하드웨어가 소프트웨어로 처리한다. 1587 | > 1588 | > - 시스템 콜 호출 시 사용되는 트랩 핸들러는 리턴 후 시스템 콜을 호출한 명령어의 '다음' 명령어를 실행한다. TLB 미스를 처리하는 트랩 핸들러는 리턴 후 시스템 콜을 호출한 명령어를 '다시' 실행한다. 즉 운영체제는 트랩의 발생 원인에 따라 PC에 현재 명령어의 값, 또는 다음 명령어의 값을 넣어야 한다. 1589 | 1590 | --- 1591 | 1592 | ### TLB 미스 트랩 핸들러가 실행될 때 TLB 미스가 나지 않도록 대응 방안? 1593 | 1594 | (가상 주소 공간에 위치한 트랩 핸들러를 실행할 때 TLB 미스가 나면, 트랩 핸들러가 무한 반복으로 호출될 것이다.) 1595 | 1596 | 방법 1. 1597 | TLB 미스 핸들러를 가상 메모리가 아닌 물리 메모리에만 위치시킨다. 1598 | 1599 | 방법 2. 1600 | TLB의 일부를 트랩 핸들러의 주소 변환 정보를 위해 영구히 할당한다. 1601 | (→ "연결 변환(wired translate)" 라고 한다) 1602 | 1603 | --- 1604 | 1605 | ### TLB Cache가 설계된 방식은? (cache의 associativity와 관련하여) 1606 | 1607 | fully associative로 설계된다. 1608 | 1609 | - 변환 정보를 찾는 검색이 TLB 전체에서 병렬로 수행된다. 1610 | - 변환 정보가 TLB 내 어디든 위치할 수 있다. 1611 | 1612 | --- 1613 | 1614 | ### TLB 각 항목의 구성은? 1615 | 1616 | VPN, PFN, 기타 다른 비트들(valid bit, protection bit, ASID 등) 1617 | 1618 | --- 1619 | 1620 | ### 페이지 테이블의 valid bit와 TLB의 valid bit 간 차이점은? 1621 | 1622 | 페이지 테이블 valid bit 1623 | 1624 | - PTE의 valid bit가 "무효" 표시 → 해당 페이지가 프로세스에 할당되지 않았음을 의미. 1625 | 1626 | TLB valid bit 1627 | 1628 | - TLB에 탑재된 해당 변환 정보가 유효한지를 표시. 1629 | - 최초 시스템이 시작할 때, 또는 context switching이 발생할 때 valid bit를 "무효"로 표시함으로써 이전 context 정보를 사용하는 것을 방지한다. 1630 | 1631 | --- 1632 | 1633 | ### TLB에는 여러 VPN이 공존할 수 있다. 하지만 그럴 경우 여러 프로세스 간 VPN을 구분할 수 없다. 이에 대한 방안은? 1634 | 1635 | 1. context switching 때마다 TLB의 내용을 지운다. (= valid bit를 0으로 설정한다.) 1636 | 1637 | > - page table base register의 값이 변경될 때가 TLB의 내용을 지워야 하는 타이밍이 된다. 1638 | > - OS는 하드웨어 특권 명령어를 통해 TLB의 내용을 지울 수 있다. 1639 | > 1640 | > 단점 1641 | > 1642 | > - TLB miss rate가 증가한다. 1643 | > - context switching이 빈번하게 발생 시 성능에 큰 부담을 준다. 1644 | 1645 | 2. TLB에 ASID(Address Space Identifier, 주소 공간 식별자) 필드를 추가한다. 1646 | 1647 | - TLB 변환 정보를 프로세스 별로 구분할 수 있다. 1648 | 1649 | > - context switching 시 운영체제는 새로운 프로세스의 ASID 값을 특정 레지스터에 탑재한다. 1650 | 1651 | --- 1652 | 1653 | ### 캐시 교체 정책에는 어떤 것들이 있나? 1654 | 1655 | - LRU 1656 | - Random 1657 | 1658 | --- 1659 | 1660 | ### LRU란? 1661 | 1662 | 가장 오랫동안 사용되지 않은 항목을 교체하는 정책. 1663 | 1664 | --- 1665 | 1666 | ### Random 정책이란? 장단점은? 1667 | 1668 | 교체 대상을 무작위로 결정한다. 1669 | 1670 | 장점 1671 | 1672 | - 구현이 간단하다. 1673 | - 예상치 못한 예외 상황의 발생을 피할 수 있다. 이를테면 TLB coverage를 벗어나는 경우 등을 방지할 수 있다. 1674 | 1675 | 단점 1676 | 1677 | - 때때로 잘못된 결정을 내릴 수 있다. 1678 | 1679 | --- 1680 | 1681 | ### TLB coverage를 벗어난다는 것의 의미는? 1682 | 1683 | 프로그램이 짧은 시간동안 접근하는 페이지들의 수가 TLB에 들어갈 수 있는 수보다 많은 경우, 그 프로그램은 TLB 미스를 많이 발생시키게 되고 느리게 동작한다. 1684 | 1685 | --- 1686 | 1687 | ## 스와핑(Swapping) 1688 | 1689 | ### 스와핑이란? 1690 | 1691 | 디스크와 메모리 사이에서 swap-in, swap-out을 통해 메모리 가상화를 지원하는 방법. 1692 | 1693 | --- 1694 | 1695 | ### swap in과 swap out에 대해 설명? 1696 | 1697 | - swap in: 스왑 공간의 페이지를 읽어 메모리에 탑재시키는 것. 1698 | - swap out: 메모리의 페이지를 읽어 스왑 공간에 쓰는 것. 1699 | 1700 | > - 스왑 공간(swap space): 디스크에 페이지를 저장할 수 있는 일정 공간 1701 | > 1702 | > - 시스템이 사용할 수 있는 메모리의 크기는 스왑 공간의 크기가 결정한다. 1703 | > - 스왑 공간에만 스왑을 할 수 있는 것은 아니다. 물리 메모리에 추가 공간을 확보해야 할 때, 코드 영역의 페이지들이 차지하는 물리 페이지는 즉시 다른 페이지가 사용할 수 있다. (코드가 저장되어 있는 파일 시스템 영역이 스왑 공간으로 사용되는 셈이다. 해당 페이지는 디스크에 원본이 있으므로, 언제든지 다시 swap in이 가능하다.) 1704 | 1705 | --- 1706 | 1707 | ### page fault란? 1708 | 1709 | 물리 메모리에 존재하지 않는(디스크에 존재하는) 페이지에 접근할 때 발생하는 예외. 1710 | 1711 | > - 페이지 테이블의 PTE의 present bit가 0인 경우이다. 1712 | > - page fault는 운영체제의 page fault handler가 처리한다. 1713 | 1714 | --- 1715 | 1716 | ### 스와핑이 지원되는 상황에서 메모리가 참조되는 과정을 설명? 1717 | 1718 | - (프로세스가 가상 메모리를 참조한다.) 1719 | - 하드웨어는 가상 주소를 물리 주소로 변환하기 위해 VPN 추출 후 TLB를 참조한다. 1720 | - TLB hit: 물리 주소를 얻은 후 메모리로 가져온다. (끝) 1721 | - TLB miss → 하드웨어는 page table base register로 페이지 테이블의 위치를 파악 후, VPN으로 PTE를 추출한다. 1722 | - PTE가 유효하고(valid bit가 1이고), 해당 페이지가 물리 메모리에 존재하면(present bit가 1이면), 하드웨어는 PTE로부터 PFN을 추출해 TLB에 탑재한다. 그리고 명령어를 재실행한다. (끝) 1723 | - Page fault → 운영체제로 제어권이 넘어가 운영 체제의 page fault handler가 실행된다. 1724 | 1725 | --- 1726 | 1727 | ### 운영체제가 Page fault를 처리하는 과정은? 1728 | 1729 | (page fault가 발생하면 하드웨어는 예외를 발생시킨 후 운영체제로 제어권을 넘긴다.) 1730 | 1731 | - 운영체제는 해당 페이지를 메모리로 swap in 해온다. 1732 | - swap in(디스크 I/O)이 완료되면, 해당 PTE의 PFN 값을 물리 메모리에 탑재된 페이지의 위치로 갱신한다. 1733 | - page fault가 발생한 명령어를 재실행한다. 1734 | 1735 | > - page fault가 난 페이지의 디스크 상 위치는 페이지 테이블에 저장되어 있다. 1736 | > - 명령어 재실행으로 인해 TLB 미스가 발생하면, TLB 미스 핸들러를 실행시킨다. (이를 방지하기 위해 page fault를 처리할 때 TLB도 같이 갱신하도록 할 수 있다.) 1737 | > 1738 | > - 디스크 I/O 중에는 해당 프로세스가 blocked 상태가 된다. 이때 운영체제는 다른 프로세스들을 실행할 수 있다. 1739 | 1740 | --- 1741 | 1742 | ### 운영체제가 페이지 교체(스왑) 알고리즘을 작동시키는 시기는? 1743 | 1744 | 운영체제는 물리 메모리 상 여유 공간에 최댓값(high watermark)과 최솟값(low watermark)을 설정해 교체 알고리즘을 작동시킨다. 1745 | 1746 | --- 1747 | 1748 | ### 페이지 교체(스왑) 알고리즘이 작동될 때(즉, 여유 공간이 최솟값보다 적어질 때) 일어나는 일은? 1749 | 1750 | - 운영체제가 스왑 데몬을 작동시킨다. 1751 | - 스왑 데몬은 여유 공간의 크기가 최댓값에 이를 때까지 페이지를 제거한다. 1752 | 1753 | > - 스왑 데몬(swap daemon, page daemon) : 메모리 여유 공간 확보를 담당하는 백그라운드 스레드. 1754 | 1755 | --- 1756 | 1757 | ## Blocking/Non-Blocking & Synchronous/Asynchronous 1758 | 1759 | ### Blocking과 Non-Blocking의 차이점? 1760 | 1761 | 다른 주체(혹은, 호출한 함수)가 작업할 때, 자신에게 제어권이 있는지 여부에 차이가 있다. 1762 | 1763 | - Blocking: 자신의 작업을 진행하다가 다른 주체의 작업이 시작되면 해당 작업이 끝날 때까지 기다렸다가 자신의 작업을 다시 시작하는 것. 1764 | ![OS%20e8aed882f45845d1a8fe27f71d71571b/blocking.png](OS%20e8aed882f45845d1a8fe27f71d71571b/blocking.png) 1765 | - Non-Blocking: 다른 주체의 작업과 관련없이 자신의 작업을 이어 하는 것. 1766 | ![OS%20e8aed882f45845d1a8fe27f71d71571b/non-blocking.png](OS%20e8aed882f45845d1a8fe27f71d71571b/non-blocking.png) 1767 | 1768 | > 예를 들어, A가 B를 호출했다고 가정하자. 1769 | > 1770 | > - B가 자신의 작업을 모두 완료한 후, A에게 제어권을 넘겨주는 것이 Blocking이다. 1771 | > - B가 바로 제어권을 A에게 넘겨, A가 다른 일을 할 수 있도록 하는 것이 Non-Blocking이다. 1772 | 1773 | --- 1774 | 1775 | ### Synchronous와 Asynchronous의 차이점? 1776 | 1777 | 다른 주체(혹은, 호출한 함수)가 결과를 돌려주었을 때, 결과와 그 처리 순서에 관심이 있는지 여부에 차이가 있다. 1778 | 1779 | - Synchronous: 다른 주체의 작업 완료 여부를 지속적으로 체크하다가, 다른 주체의 작업이 끝나는 동시에 일을 시작하는 것. 1780 | ![OS%20e8aed882f45845d1a8fe27f71d71571b/sync.png](OS%20e8aed882f45845d1a8fe27f71d71571b/sync.png) 1781 | - Asynchronous: 작업 완료 여부를 체크하지 않고, 다른 주체의 작업이 끝나는 동시에 일을 시작하지 않는 것. 1782 | ![OS%20e8aed882f45845d1a8fe27f71d71571b/async.png](OS%20e8aed882f45845d1a8fe27f71d71571b/async.png) 1783 | 1784 | > 예를 들어, A가 B를 호출했다고 가정하자. 1785 | > 추가적으로, A는 B에게 요청한 작업 b가 끝나면 C(: callback) 작업을 수행하기를 요구했다. 1786 | > 1787 | > - Synchronous에서는 A가 B의 작업 b가 완료되었는지 여부를 지속적으로 체크한다. B의 작업이 완료되면, 즉시 작업 b에 대한 처리(C)를 시작한다. 1788 | > - Asynchronous에서는 A가 B의 작업 b가 완료되었는지 여부를 신경쓰지 않는다. B의 작업이 완료되면, 즉시 작업 b에 대한 처리(C)를 시작할 수도 있고, 아닐 수도 있다(언젠가는 한다). 1789 | 1790 | > Synchronous와 Asynchronous는 동기, 비동기로 번역된다. 1791 | 1792 | --- 1793 | 1794 | ### Blocking + Sync 조합에 대해 설명해본다면? 1795 | 1796 | 제어권이 없기 때문에 다른 주체가 작업하는 동안 일을 하지 않고 기다린다. 다른 주체의 작업 완료 여부를 지속적으로 체크하다가, 결과를 반환하면 바로 처리를 시작한다. 1797 | 1798 | ![OS%20e8aed882f45845d1a8fe27f71d71571b/blocking&sync.png](OS%20e8aed882f45845d1a8fe27f71d71571b/blocking&sync.png) 1799 | 1800 | > 예시: C에서 사용자에게 입력을 받는 것. 사용자가 입력하는 동안 프로그램은 동작을 멈추고, 입력을 마치면 뒤이어 다음 코드들을 동작시킨다. 1801 | 1802 | --- 1803 | 1804 | ### Non-Blocking + Sync 조합에 대해 설명해본다면? 1805 | 1806 | 다른 주체에게 작업을 요청한 뒤, 제어권을 가지고 자신의 일을 진행한다. 동시에 지속적으로 다른 주체에게 작업 완료 여부를 체크한다. 작업이 완료되면, 결과에 대한 처리를 바로 시작한다. 1807 | 1808 | ![OS%20e8aed882f45845d1a8fe27f71d71571b/non-blocking&sync.png](OS%20e8aed882f45845d1a8fe27f71d71571b/non-blocking&sync.png) 1809 | 1810 | > 예시: 게임에서 다른 맵으로 넘어가는 것. 다른 맵으로 넘어가는 처리를 요청한 뒤, 자신은 다른 일을 하고 있는다. 유저에게 로드율을 보여주기 위해, 작업 완료 여부를 지속적으로 체크한다. 맵을 넘어가기 위한 작업이 끝나면 바로 그에 대한 처리를 한다. 1811 | 1812 | --- 1813 | 1814 | ### Blocking + Async 조합에 대해 설명해본다면? 1815 | 1816 | 다른 주체에게 작업을 요청한 후, 제어권 없이 기다린다. 다른 주체가 결과를 응답하면, 그에 대한 처리를 바로 하지 않는다. 1817 | 1818 | ![OS%20e8aed882f45845d1a8fe27f71d71571b/blocking&async.png](OS%20e8aed882f45845d1a8fe27f71d71571b/blocking&async.png) 1819 | 1820 | > - 다른 주체의 작업에 대한 처리를 바로 하지 않아도 되기 때문에, 굳이 제어권 없이 기다릴 필요가 없다. 우선 자신의 일을 처리하고 있다가 나중에 결과에 대한 처리를 언젠가 하면 되기 때문이다. 1821 | > - 때문에, 이 조합은 Non-Blocking + Async 조합을 사용하려 했으나 개발자의 실수로 인해, 혹은 기타 이유로 발생한다. 1822 | > - 예시로 Node.js + MySQL 조합이 있다. Node.js 쪽에서 Async로 MySQL과 통신을 요청하지만, MySQL에서 제공하는 드라이버는 Blocking 방식으로 동작한다. 1823 | 1824 | --- 1825 | 1826 | ### Non-Blocking + Async 조합에 대해 설명해본다면? 1827 | 1828 | 다른 주체에게 작업을 요청한 뒤, 제어권을 가지고 자신의 일을 진행한다. 다른 주체가 작업을 완료해 응답하면, 결과에 대한 처리를 바로 진행하지 않는다. 1829 | 1830 | ![OS%20e8aed882f45845d1a8fe27f71d71571b/non-blocking&async.png](OS%20e8aed882f45845d1a8fe27f71d71571b/non-blocking&async.png) 1831 | 1832 | > 예시: JavaScript의 비동기 요청들. Web API 등의 작업을 요청한 후, 이어서 코드를 진행하다가 작업이 완료되면 콜백을 실행한다. 1833 | -------------------------------------------------------------------------------- /self-taught.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heech1013/study-note/9c5d4ee9887aed616e24701a9a43b1cd53dcf6a4/self-taught.jpg -------------------------------------------------------------------------------- /web/Web a8bd6cb86f15403fa6e62833f6c3d9f2/Untitled 1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heech1013/study-note/9c5d4ee9887aed616e24701a9a43b1cd53dcf6a4/web/Web a8bd6cb86f15403fa6e62833f6c3d9f2/Untitled 1.png -------------------------------------------------------------------------------- /web/Web a8bd6cb86f15403fa6e62833f6c3d9f2/Untitled 2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heech1013/study-note/9c5d4ee9887aed616e24701a9a43b1cd53dcf6a4/web/Web a8bd6cb86f15403fa6e62833f6c3d9f2/Untitled 2.png -------------------------------------------------------------------------------- /web/Web a8bd6cb86f15403fa6e62833f6c3d9f2/Untitled 3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heech1013/study-note/9c5d4ee9887aed616e24701a9a43b1cd53dcf6a4/web/Web a8bd6cb86f15403fa6e62833f6c3d9f2/Untitled 3.png -------------------------------------------------------------------------------- /web/Web a8bd6cb86f15403fa6e62833f6c3d9f2/Untitled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heech1013/study-note/9c5d4ee9887aed616e24701a9a43b1cd53dcf6a4/web/Web a8bd6cb86f15403fa6e62833f6c3d9f2/Untitled.png --------------------------------------------------------------------------------