# 4/28 면접 스터디 ## 임태현 ### TCP https://www.notion.so/thsoon/TCP-841a3203ecf547599a88109759107f8d #### 1. TCP가 무엇인가요? TCP/IP 집합에서 Transport Layer에 해당되는 프로콜입니다. TCP는 기본적으로 IP 프로토콜로 순서가 보장되있지 않는 상대측 데이터 Chunk들을 모아 순서를 보장시켜 Application Layer로 보내주는 역할을 합니다. 그 밖에도 흐름제어, 오류제어, 혼잡제어를 담당합니다. #### 2. TCP의 특징(vs UDP) TCP의 특징은 Stream Delivery, Connection-Oriented 두가지라고 생각합니다. ![](https://i.imgur.com/bCzOp8l.png) UDP는 상위 Layer에서 받은 데이터를 임의의 크기로 나누어 하위 Layer에 전달합니다. 하지만 TCP는 Stream Delivery 특징으로 Buffer에서 수신측의 상황을 고려하기 위해 동적인 Chunk 단위로 데이터를 전달합니다. 또, UDP는 Connectionless이기 때문에 연결 없이 상대에게 데이터를 보내지만 TCP는 Connection-Oriented이기 때문에 연결을 먼저 설정한 다음 데이터를 전달합니다. #### 3. TCP는 어떻게 흐름제어를 하나요? TCP의 흐름제어는 Application Layer에게 받은 데이터를 Buffer에 저장한 다음 Sliding Window를 통해 보낼 데이터를 정하는 것을 말합니다. Buffer에 쌓인 데이터는 바로 보내지 않고 네트워크 트래픽을 가장 효율적으로 관리할 수 있는 타이밍에 보내게 됩니다.(5번 문항에 이유가 설명) 이 때, Window Size를 수신측과 혼잡 상황을 토대로 정하게 되어 데이터를 보내게 됩니다. ![](https://i.imgur.com/RiIBvJY.png) 이 뜻은 수신측에 받을 수 있는 버퍼 크기(rwnd)와 중간에 존재하는 라우터들의 버퍼의 혼잡으로 소실되지 않게 혼잡도를 따진 버퍼 크기(cwnd) 중 작은 값으로 Window Size가 결정된다는 것입니다. 이렇게 상대방과 망의 혼잡도를 따져 흐름을 제어해 데이터 손실을 줄여 최소한 필요한만큼만 패킷이 통신될 수 있게합니다. #### 4. Sliding Window가 무엇인가요? ![](https://i.imgur.com/xJaiORj.png) ![](https://i.imgur.com/wzbyQsV.png) TCP의 흐름제어의 중요한 매커니즘으로, 송신측에서 수신측 또는 망이 감당할 수 있는 데이터 크기를 영역으로 표시하고 상황마다 윈도우 영역을 조절하는 것입니다. Window 영역은 Left Pointer와 Right Pointer로 관리합니다. - Window Close: 전송하고 ACK를 받지 않는 데이터는 계속 window 내에 있으면서 재전송될 가능성을 염두해둡니다. 그리고 ACK 수신을 통해 보낸 데이터가 안전하게 수신측에 갔음을 알게 되면 window의 Left Pointer가 오른쪽으로 움직여 rwnd를 조정합니다. - Window Open: 송신측은 수신측에게 ACK를 받을 때마다 수신측의 감당 용량인 rwnd를 받아 윈도우 크기를 조정합니다. 만약 수신측에서 데이터를 소비하게 되면 rwnd가 증가하게 되므로 더 많은 데이터를 보낸다고 판단해 Right Pointer를 오른쪽으로 움직입니다. - Window Shrink: 보통의 경우 Shrink가 발생하지 않습니다. 왜냐하면 수신측에서 ACK를 받을 때 데이터를 아무것도 소비하지 못한 상태엔 rwnd가 그대로인데, 이 경우 전송했던 데이터만 Window에서 벗어나면 되기 때문입니다. 또, 데이터를 소비하고 ACK를 송신측에게 준 경우 Window 크기가 늘어나기 때문에 Shrink가 발생하지 않습니다. 하지만 망이 갑자기 혼잡해져 cwnd가 급격히 감소하게 되면 window size가 줄어들어 Shrinking이 발생할 수 있습니다. 혹은 데이터를 받지 못하는 상태가 되면 rwnd를 0으로 주는 상황에 발생할 수 있다. #### 5. Silly Window Syndrome이 무엇이고 해결 방법 Silly Window Syndrome은 전송할 데이터보다 TCP 헤더가 더 크기 때문에 발생하는 네트워크 트래픽 문제입니다. 이는 송신측과 수신측의 Syndrome이 존재합니다. - 송신측: Application Layer에서 1byte같이 작은 데이터를 TCP Buffer에 Write할 때마다 전송하게 되면 트래픽 낭비입니다. 그래서 어느정도의 데이터가 Buffer에 쌓이면 보내는 알고리즘인 Nagle Algorithm을 사용합니다. - Nagle Algorithm은 1byte라도 Buffer에 쌓이면 전송합니다. 하지만 ACK가 오거나 최대 세그먼트 크기만큼 버퍼에 쌓이게될 때까진 전송을 지연합니다. - 수신측: 수신측 TCP Buffer가 가득차 rwnd가 0이 되었는데 수신측 Application Layer가 TCP Buffer의 데이터를 조금씩 사용하게 되면 작은 데이터를 송신측에 요청하면서 비효율적인 트래픽을 발생시킵니다. 그래서 윈도우 크기를 설정해주는 해결법인 Clark Solution을 사용합니다. - Clark Solution은 Buffer 크기의 반 등 어느 정도의 수용력이 있는 상태일 때만 송신측에게 알려주며, 아닌 경우에 rwnd를 0으로 설정해 ACK를 보내는 것입니다. #### 6. TCP는 어떻게 오류제어를 하나요? TCP는 Checksum과 accumulative ACK 규칙에 따른 재전송 매커니즘으로 오류를 제어합니다. accumulative ACK는 지금 당장 다음에 보내야할 Sequence Number를 ACK Number로 담아 보내는 것입니다.(piggy backing) 이 시스템을 통해 순서가 맞는 정상적인 수신도 지연한 다음 한 번 더 정상적인 것을 받은 뒤에 ACK를 전송하거나 일정 시간 뒤에(RTO) ACK를 전송해 네트워크 트래픽을 줄여줍니다. 문제는 중간에 없어진 세그먼트를 인지해 Buffer가 순서대로 쌓이지 않을 때입니다. 우선 중간에 변조된 세그먼트를 checksum을 통해 유효성을 검사해서 잘 못됨을 인지하거나 Buffer에 쌓인 데이터 중 중간에 누락된 것을 발견하게 되면 문제의 Buffer Number를 ACK Number로 설정된 ACK를 바로 재전송하게 됩니다. ![](https://i.imgur.com/gXOBsY0.png) - RTO 재전송: 송신측에서 데이터를 전송할 때마다 타이머를 설정합니다. ACK를 받았을 때 ACK Number와 전송했던 데이터의 Sequence Number가 같다는 것은 수신을 못 했다는 것인데, 이를 인지한 상태에서 타이머 시간을 초과하게 되면 재전송하게 됩니다. ![](https://i.imgur.com/NrbzVaq.png) - 3-duplicated ACK: RTO 타이머 전에 3번 잘못된 동일한 ACK Number의 ACK를 받았을 경우 바로 재전송하는 ACK 시스템입니다. #### 7. TCP는 어떻게 혼잡제어를 하나요? TCP의 혼잡제어는 흐름제어의 연장선으로, Window Size를 결정하는 요소인 cwnd를 데이터 송신때마다 카운팅을 하는 것입니다. cwnd의 카운팅 단위는 Maximum Segment Size입니다. - Slow Start: cwnd를 1MSS로 설정합니다. 임계치는 첫 전송시엔 임의로 정하며, 혼잡 감지가 일어나면 기존 cwnd의 반이 됩니다. - ACK를 받을 때마다 cwnd는 2배가 되는데 임의로 정한 임계치에 다다르면 Congestion Avoidance가 일어납니다. - Congestion Avoidance: cwnd가 임계치에 다다르면 2배씩이 아닌, 1MSS씩 증가하게 됩니다. - Congestion Sense: RTO 초과가 발생하면 망이 심각하게 혼잡하다고 판단해 임계치를 현재 cwnd의 반으로 줄이고 Slow Start를 시작합니다. - 3-duplicated ACK가 발생하면 망이 비교적 혼잡하지 않다고 판단해 임계치를 cwnd의 반으로 줄이고 cwnd 또한 반으로 만든 뒤, `Congestion Avoidance`를 시작합니다. #### 8. 3-way HandShake가 무엇인가요? ![](https://i.imgur.com/kDIa7WD.png) TCP 프로토콜을 통해서 두 노드간 논리적인 연결을 수행하는 과정을 말합니다. 1. 클라이언트가 서버에게 SYN flag의 패킷을 전송하면 2. 서버가 클라이언트에게 ACK는 물론 SYN flag을 담아 연결 준비가 되었고 연결 하겠다는 패킷을 전송합니다. 이 때, 서버의 rwnd를 패킷에 넣습니다. 3. 서버의 패킷을 받은 클라이언트는 서버의 연결을 확인했다는 ACK 패킷을 보내면서 자신의 rwnd를 알려줍니다. #### 9. TCP 연결 Close시 Client에서 2MSL 시간동안 연결을 해제하지 않는 이유 ![](https://i.imgur.com/QPCGK8m.png) MSL: Maximum Segment Lifetime Client가 연결을 종료하지 않고 기다리는 이유는 2가지가 있습니다. 1. 첫 번째, TCP Close HandShake를 할 때 클라이언트가 서버에게 보낸 ACK가 유실되어 홀로 연결이 종료 안되는 것을 방지하기 위해서입니다. 이런 시스템덕분에 서버측에선 일정 시간 뒤에 ACK를 받지 못하면 다시 ACK+FIN을 보냅니다. 2. 두 번째, 다음 연결과 텀을 두기 위해서입니다. 연결을 종류한 뒤에 2MSL이 되기전에 다시 연결하게 되면, 이전 연결에서 서버가 전달했지만 이전에 미처 도착하지 못한 데이터가 수신되어 적절하지 않는 동작을 취할 가능성이 있기 때문입니다. ### IP https://www.notion.so/thsoon/IP-f5910bebcc1e467285c67ab693d505b2 #### IP Header의 Checksum과 TCP Header의 Checksum 차이 IP Header의 Checksum은 IP Header 내용의 유효성만을 검사합니다. 하지만 TCP Header의 Checksum은 TCP Header 뿐만 아니라 IP 수도 헤더, 데이터의 유효성 또한 검사합니다. IP 수도 헤더는 Transport Layer에서 IP Header의 데이터를 사용하기 위해 만들어진 헤더입니다. #### MTU가 무엇인가요? Maximum Transfer Unit로 Data Link Layer의 프로토콜에 따라 실질적으로 보낼 수 있는 데이터 크기를 정의한 것입니다. 그래서 Network Layer인 IP에서 넘겨준 패킷인 IP Packet을 한 번 더 Fragmentation을 진행합니다. #### Classful IP vs Classless IP Classful IP 체계는 옛날에 쓰였던 IP 체계입니다. 각 용도마다 #### Subnet Mask가 무엇인가요? #### Subnetting이 무엇인가요? #### Routing Table의 구성 방법은 무엇이 있나요? #### Classless IP에서의 Forwarding은 어떻게 일어나나요? #### Address Aggregation이 무엇인가요? #### Longest Mask Matching이 무엇인가요? ### 시스템 콜 --- ## 최지수 ### 동기식 처리(Synchronous) 요청과 결과가 한 번에 일어나는 방법이다. 요청을 하면 시간이 얼마가 걸리던지 요청한 자리에서 결과가 주어져야 한다. - 설계가 매우 직관적이다. - 결과가 주어질 때까지 아무것도 못하고 기다려야 한다. - 순차적으로 요청을 처리한다. - 요청을 보내고 결과를 받아야 다음 동작이 이루어지는 방식 - 결과가 오기 전에는 이후 테스크들은 모두 블로킹(blocking, 작업 중단)된다. ### 비동기식 처리(Asynchronous) 태스크가 종료되지 않은 상태라 하더라도 대기하지 않고 다음 태스크를 실행한다. 결과가 주어지는데 시간이 걸리더라도 그 시간 동안 다른 작업을 할 수 있으므로 자원을 효율적으로 사용할 수 있다. - 순차적으로 실행하지 않는다. - 응답을 기다리지 않고 다음 테스크를 수행한다. - 병렬적으로 테스크를 수행한다. - 자원을 효율적으로 사용할 수 있다. 오래 걸리는 작업은 비동기 처리 방식을 사용해 사용자가 해당 작업을 기다리지 않고 다른 작업을 진행할 수 있도록 하면 좋다. 사용자 측면에서 속도 개선을 유도할 수 있다. ### Celery Celery 는 Python 으로 작성된 분산 메시지 전달을 기반으로 한 비동기 작업 큐로, Worker 의 한 종류다. 별도로 실행 중인 Worker Process가 Broker로부터 Message를 전달 받아 작업을 대신 수행해 주는 라이브러리다. #### 흐름 요청을 받은 뷰에서는 Broker에게 해당 작업 실행을 위임하고 각 작업을 구분할 수 있는 Task ID 를 발급받게 된다. 해당 작업은 Broker가 놀고있는 Worker에게 넘겨서 Worker가 비동기로 수행하도록 한다. Django 서버에서 Task를 Message Borker를 통해 전달을 하면 하나 이상의 Celery Worker가 Message Broker Queue에 있는 Task를 받아서 이를 처리한다. `Celery`를 사용하기 위해서는 Message Broker가 필요한데 대표적으로 Redis와 RabbitMQ가 있다. ### Redis 디스크에 상주하는 인메모리 데이터베이스 / 컴퓨터 메모리를 이용한(in-memory) Cache 서버 Key-Value를 이용해 Celery가 처리할 작업을 Celery에 보낸 후 Cache 에서 해당 Key를 제거하는 방식으로 작동한다. - Redis는 데이터 검색을 위해 Database에 접근하기 전 메모리에서 Cache를 가져다 쓴다는 점에서 속도가 빠르다. - 매우 빠른 서비스 및 메모리 내 기능을 제공하기 때문에 지속성이 중요하지 않고 약간의 손실을 견딜 수있는 짧은 보존 메시지에 적합하다. - 큰 메시지를 처리 할 때는 대기 시간이 오래 걸린다. ### RabbitMQ 메시지 브로커이다. 응용 프로그램(applications)에게 메시지를 주고 받을 수 있으며, 메시지가 수신될 때까지 안전하게 있을 수 있도록 하는 공용 플래폼(common platform)을 제공한다. - 메시지를 다른 대기열로 보낼 수있는 라우팅 시스템을 갖추고 있다. - 우선 순위가 높은 메시지를 먼저 사용하기 위해 작업자가 사용할 수있는 메시지의 우선 순위를 지원한다. - 메시지 브로커로서 Redis와 비교할 때 훨씬 더 다양한 기능을 제공한다. - 크고 복잡한 메시지에 적합하다. - 오류 처리가 좋음 --- ## 문예지 ### 인증 > 필요한 이유 > 권한을 가진 리소스에만 접근 가능하게하기 위해 > 인증 방법 > 1. **계정정보를 request header에 넣는 방식** 장점 - 인증을 테스트 할 때 빠르게 시도가능 단점 - 보안에 매우 취약 - 서버에서는 신호가 올때마다 Id,Pw를 통해 유저가 맞는지 인증(비효율적) 2. **쿠키 / 세션** 세션 쿠키 방식의 인증은 기본적으로 세션 저장소를 필요(Redis를 많이 사용) ![](https://i.imgur.com/yBr38pt.png) - 세션 저장소는 로그인을 했을 때 사용자의 정보를 저장하고 열쇠가 되는 세션ID를 생성 - HTTP 헤더에 실어 사용자에게 response - 사용자는 쿠키로 보관하고 있다 인증이 필요한 요청에 쿠키(세션ID)를 넣어 request - 웹 서버에서는 세션 저장소에서 쿠키(세션ID)를 받고 저장되어 있는 정보와 매칭시켜 인증을 완료 **장점** - 쿠키가 담긴 HTTP 요청이 도중에 노출되더라도 쿠키 자체(세션 ID)는 유의미한 값을 갖고있지 않음(중요 정보는 서버 세션에) - 사용자마다 고유의 ID값을 발급 일일히 회원정보 확인이 필요 없음 **단점** - 세션하이재킹: 훔친 쿠키를 이용해 HTTP 요청을 보내면 서버의 세션저장소에서는 사용자를 오인해 정보를 알려줌 - 해결책 - HTTPS를 사용해 요청 자체를 탈취해도 안의 정보를 읽기 힘들게 한다. - 세션에 유효시간을 넣어준다. - 서버에서 추가적인 저장공간을 필요 - CORS, CSRF의 문제점 4. **토큰기반** [jwt](https://hackmd.io/HnCI06h6Tv2iQRDhxDa7AQ#JWT) ### DB 정규화 **필요한 이유** 불필요한 데이터 중복에 의한 공간 낭비 + 이상현상을 막기 위해 - 삽입이상: 새 데이터를 삽입하기위해 불필요한 데이터도 삽입해야하는 경우 - 갱신이상: 중복 튜플 중 일부만 변경하여 데이터가 불일치하게 되는 모순의 문제 - 삭제이상: 튜플을 삭제하면 꼭 필요한 데이터까지 함께 삭제되는 데이터 손실의 문제 <br> > 정규화 단계 > 1. **제1정규형(1NF)** 각 로우마다 컬럼의 값이 1개씩만(각 컬럼이 원자값을 가짐) | name | age | subject | | ---- | --- | ------- | | Jack | 21 |Bio, Math| | Mac | 20 |Art | :arrow_down: | name | age | subject | | ---- | --- | ------- | | Jack | 21 |Bio | | Jack | 21 |Math | | Mac | 20 |Art | 2. **제2정규형(2NF)** 기본키중에 특정 컬럼에만 종속된 컬럼(부분적 종속)이 없어야 한다는 것 기본키: name + subject age는 name에만 종속적 :arrow_right: age가 두번 들어가는건 불필요 | name | age | subject | | ---- | --- | ------- | | Jack | 21 |Bio | | Jack | 21 |Math | | Mac | 20 |Art | :arrow_down: | name | subject | | ---- | ------- | | Jack |Bio | | Jack |Math | | Mac |Art | | name | age | | ---- | --- | | Jack | 21 | | Mac | 20 | 3. **제3정규형(3NF)** 기본키 이외의 다른 컬럼이 그외 다른 컬럼을 결정할 수 없음 기본키: student_id 우편번호를 알면 시,구,동이 결정 :arrow_right: 중복발생 가능 |student_id|student_name|시|구|동|우편번호| |----------|------------|-|-|-|-| |150101|김철수|서울시|A구|AA동|12311| |170101|김영희|서울시|A구|AA동|12311| |173301|박철수|서울시|B구|BB동|25677| :arrow_down: |student_id|student_name|우편번호| |----------|------------|-| |150101|김철수|12311| |170101|김영희|12311| |173301|박철수|25677| |우편번호|시|구|동| |------|-|-|-| |12311|서울시|A구|AA동| |25677|서울시|B구|BB동| 4. **BCNF** 3차 정규형을 조금 더 강화한 버전 3차정규형을 만족하면서 모든 결정자가 후보키(기본키로 사용할 수 있는 속성) 집합에 속한 정규형 if. 교수당 한 과목만 강의 가능 기본키: 학생 + 과목 | 학생 | 과목 | 교수 | | --- | --- | --- | | 1 | A111 | kim | | 2 | B111 | park | | 3 | B111 | park | 데이터가 중복 + 갱신 이상이 발생 B111을 강의하는 교수가 바뀌었다면 두 개의 로우를 갱신함 :arrow_down: | 학생 | 과목 | | - | --- | | 1 | A111 | | 2 | B111 | | 3 | B111 | | 과목 | 교수 | | --- | --- | | A111 | kim | | B111 | park |