혼자 적어보는 노트

프로그래머스 데브코스 TIL - Day 2 본문

스터디

프로그래머스 데브코스 TIL - Day 2

jinist 2022. 3. 22. 20:04

 

 

 학습 목차

- [Day 1] JavaScript 주요 문법 (2)

 

✅ 새롭게 학습한 부분

- 브라우저에 url을 입력했을 때 발생하는 일

- 객체지향 프로그래밍 / 함수형 프로그래밍

- 프로토타입 (추가적으로 학습 필요)

- 이벤트루프

 


 

💡 브라우저에 url을 입력했을 때 발생하는 일

 

기술면접 때문에 이전에 접해본 적 있는 개념들이였지만

세부적으로 잘 몰랐던 부분들이 있어서 전체적으로 정리를 하게 되었다.

 

1. URL을 해석한다.

 

scheme://<user>:<password>@<host>:<port>/<url-path>
Scheme : protocol을 의미하며 http, ftp, sftp, pop3, IMAP을 말한다.

-> 구조가 맞지 않다면 웹 브라우저의 기본 검색엔진으로 검색을 하게된다.

 

2. HSTS(HTTP Strict Transport Security)의 목록을 확인한다.

 

HSTS : Web Site에 접속할 때, 강제적으로 HTTPS Protocol로만 접속하게 하는 기능

HSTS의 목록을 받아와서 URL 내의 주소와 목록의 주소가 일치하면
https요청을 보내고 일치하지 않는다면 http로 요청을 보내게 된다.

 

 

3. DNS(Domain Name System)를 조회한다.

 

DNS : 도메인과 IP 주소를 변환해주는 시스템

Recursive server의 cache에서 IP를 먼저 확인하고 있다면 그 IP주소를 반환한다.

없을 경우 DNS 시스템에 따라, Root server - TLD server - Authoriative server에 ip 주소를요청한다.

 

 

4. 라우터를 통해 해당 서버의 게이트웨이까지 이동

 

​DNS 서버에게 IP 주소를 받았으니 해당 서버로 요청을 보낸다.
네트워크 장비인 라우터가 해당 주소까지의 경로를 라우팅 하여 통해 해당 주소에 요청을 전달한다.

 

 

5. ARP를 이용하여 MAC주소로 변환한다.

 

ARP : 논리적인 주소 (IP Address)를 물리적인 주소 (MAC Address)로 변환하는 프로토콜

MAC address : 컴퓨터간 데이터를 전송하기 위한 컴퓨터의 물리적 주소
IP주소는 변동 가능성이 있지만 맥주소는 변하지 않는 기계의 고유 주소 번호이다.
맥 주소는 2계층 데이터링크 계층에서 동작하는데 통신을 할 때 맥 주소가 필요하다.

 

[ ARP 동작순서 ]

 

1. 송신자는 본인의 출발지 MAC + 출발지 IP + 목적지 IP의 정보로 하나의 네트워크에 연결되어 있는
모든 PC들로 ARP 요청을 Broadcast 시킨다.

 

2. 네트워크에 연결되어 있던 모든 PC들은 이 프레임을 수신한다.
본인과 논리 IP가 맞지 않은 PC들은 수신받은 프레임을 버리고 , 맞는 PC만 응답을 보낸다.

 

3.논리 IP가 맞는 PC는 송신자에게 본인의 MAC Address를 추가해서 응답을 보낸다.
응답을 보낼 때는 Broadcast가 아닌 , unicast로 보내게된다.

 

4.  MAC주소를 응답 받으면, 다시 DNS프로세스를 시작하게되며
DNS에서 53번 포트를 통해 UDP로 실시하며 데이터 용량이 큰 경우, TCP로 진행한다.

 

 

6. TCP통신을 위한 socket을 연다.

 

네트워크를 통해 해당 기기로 패킷을 전달하고 3way handshake로 연결을 요청한다.
HTTPS의 경우 TLS(Seucure Sockets Layer)handshake가 추가되며 이 과정에서 세션키가 생성된다.

 

[TLS handShake의 과정]

 

1. Client Hello: 클라이언트가 서버에 연결을 시도하며 전송하는 패킷이다.

클라이언트가 지원하는 TLS 버전, 지원되는 암호 제품군, 그리고 Random byte가 포함된다.

 

2. Server Hello : Client Hello에 대한 응답으로 서버가 서버의 SSL인증서,

서버에서 선택한 암호 제품군, 그리고 서버에서 생성한 또 다른 Random byte를 포함하여 전달한다.

 

3. 인증 : 서버가 보낸 SSL인증서에는 서버가 발행한 공개키가 있으며

CA의 개인키로 암호화된 SSL인증서를 CA(Certificate authority : 인증기관) 공개키를 사용하여 복호화 한다.

클라이언트가 서버의 SSL 인증서를 인증서 발행 기관을 통해 검증한다.

 

4. 예비 마스터 키 : 클라이언트가 Random byte를 하나 더 전송한다.

예비 마스터 키는 공개 키로 암호화되어 있으며, 서버가 개인 키로만 해독할 수 있다.

 

5. 개인키 사용 : 서버가 예비 마스터 키를 복호화한다.

 

6. 세션 키 생성 : 클라이언트 Random byte, 서버 Random byte, 예비 마스터 키를 이용해 세션 키를 생성한다.

 

7. 클라이언트 준비 완료 : 클라이언트가 세션 키로 암호화된 "완료" 메시지를 전송

 

8. 서버 준비 완료 : 서버가 세션 키로 암호화된 "완료" 메시지를 전송

 

9. 대칭 암호화 성공: 핸드셰이크가 완료되고, 세션 키를 이용해 통신이 계속 진행됩니다.

 

 

7. HTTP(HTTPS) 서버의 응답

프로토콜로 들어온 패킷을 읽고 처리하며 요청에 따른 응답을 반환한다.

 

8. 브라우저 렌더링

서버에서 보낸 응답을 브라우저에서 해석하여 페이지를 화면에 그린다.

 


💡 객체지향 프로그래밍 (Object Oriented Programming)

객체 지향 프로그래밍은 컴퓨터 프로그래밍 패러다임중 하나로, 프로그래밍에서 필요한 데이터를 추상화시켜 상태와 행위를 가진 객체를 만들고 그 객체들 간의 유기적인 상호작용을 통해 로직을 구성하는 프로그래밍 방법

 

- 코드 재 사용성이 용이하다.
한 번 작성된 코드를 활용하여 동일한 객체를 생성할 수 있고, 클래스 단위로 모듈화 시켜서 사용할 수 있다.

 

- 유지보수가 쉽고 확장성이 좋다.
수정해야 할 부분이 클래스 내부에 멤버변수 혹은 메서드로 있기 때문에 해당 부분만 수정하면 되고
만들어진 객체를 상속을 통해 확장해서 사용해나갈 수 있다.

 

단점

- 설계 시 많은 시간과 노력이 필요하다.

- 처리 속도가 상대적으로 느리다.

 


💡 함수형 프로그래밍

함수형 프로그래밍은 순수 함수(pure function)를 조합하고 공유 상태(shared state), 변경 가능한 데이터(mutable data) 및 부작용(side-effects)을 피하여 프로그래밍하는 패러다임

 

정의는 위와 같이 나와있지만 이해가 잘 되지 않았지만 특징을 살펴보며 조금 이해하게 되었다.😃

 

특징

1. 순수함수 (Pure function)

동일한 입력에는 항상 같은 값을 반환해야 하는 함수.

함수의 실행이 프로그램의 실행에 영향을 미치지 않아야 한다.

함수 내부에서 인자의 값을 변경하거나 프로그램 상태를 변경하는 Side Effect가 없어야 한다.

 

2. 비상태, 불변성을 가진다.

함수형 프로그래밍에서의 데이터는 불변성을 유지해야 한다.

데이터의 변경이 필요하다면 원본 데이터를 변경하는 것이 아닌 데이터의 복사본을 만들어서

일부를 변경하고 변경한 복사본을 사용한다.

 

3. 선언형 함수이다

기존 명령형 프로그래밍은 문제를 어떻게 해결해야하는지 컴퓨터에게 명령을 내리는 방식.
선언형 프로그래밍은 무엇을 해결해야 할 지 집중하고 해결방법은 컴퓨터에 게 위임하는 방법.

 

4. 1급객체와 고차함수

함수형 프로그래밍 안에서는 함수가 1급 객체가된다.

 

장점

- 함수단위로 나누어서 조합하기 때문에 재사용성이 높다

- 불변성을 지향하기에 동작을 예측하기 쉽고 사이드 이펙트를 방지한다.

 

단점

- 함수형 프로그래밍은 상태(State)를 배제하여 Side Effect가 없이 동작한다는게 단점이 될 수 있다.

- 함수형 프로그래밍에서는 반복이 for문이 아닌 재귀를 통해 이루어지는데 (deep copy),
재귀적 코드 스타일은 무한 루프에 빠질 수 있다

 

 

 


💡 프로토타입

기존의 객체를 복사하여 새로운 객체를 생성하는 방식.
생성자 함수를 new 연산자와 함께 호출 시
constructor에 정의된 내용을 바탕으로 새로운 인스턴스가 생성된다.
prototype은 객체이며 이 때 이 instence에는 __proto__라는 프로퍼티가 자동으로 부여되고
 __proto__는 생성자의 prototype이라는 프로퍼티를 참조한다.

즉 생성자함수의 prototype과 인스턴스의 __proto__가 같다. 

 

직접 작성해보면서 익혀보았다.

function Student(name, grade) {
  this.name = name;
  this.grade = grade;
  this.getName = function () {
    return this.name;
  };
}

const jay = new Student("Jay", "A");
const hey = new Student("Hay", "B");

console.log(jay); // Student {name: 'Jay', grade: 'A', getName: ƒ}
console.log(hey); // Student {name: 'Hay', grade: 'B', getName: ƒ}

jay와 hey의 인스턴스에 각각의 getName이 들어가있다.

인스턴스를 많이 생성하게되면 불필요하게 메모리를 할당하게 된다.


생성자함수의 prototype과 인스턴스의 __proto__가 같다는 개념을 생각하고

비교를 해보았다.

function Student(name, grade) {
  this.name = name;
  this.grade = grade;
  Student.prototype.getName = function () {
    return this.name;
  };
}

const jay = new Student("Jay", "A");
const hey = new Student("Hay", "B");

console.log(jay); // Student {name: 'Jay', grade: 'A'}
console.log(hey); // Student {name: 'Hay', grade: 'B'}
console.log(jay.getName()); // Jay
console.log(hey.getName()); // Hey
console.log(jay.__proto__); // {getName: ƒ, constructor: ƒ}
console.log(Student.prototype); // {getName: ƒ, constructor: ƒ}
console.log(jay.__proto__ === Student.prototype); // true
console.log(jay.__proto__.getName === Student.prototype.getName); // true

같은 값을 참조하기 때문에 안의 내용은 같다.

그렇기 때문에 메모리 또한 절약 할 수 있다.

또한 프로토타입으로 지정해 놓은 것은 jay.getName()와 같이 메소드를 통하여 접근할 수 있다.

 

object.create

지정된 프로토타입 객체 및 속성(property)을 갖는 새 객체를 생성한다.

const obj = {
  name: "Jay",
  age: 29,
  greeting: function () {
    return "hello";
  },
};

const jay = Object.create(obj);

console.log(jay); // {}
console.log(obj); // {name: 'Jay', age: 29, greeting: ƒ}
console.log(jay.__proto__); // {name: 'Jay', age: 29, greeting: ƒ}
console.log(jay.name); // Jay
console.log(jay.greeting()); //hello

jay.__proto__에 해당 객체가 들어가고 prototype으로써 호출할 수 있다.

 

 


💡 이벤트 루프

 

! 이벤트 루프를 위해 알아야 할 개념들

 

JS Engine

자바스크립트는 단일 스레드(Single-threaded) 기반 언어이며 단일 콜스택을 가진다.
이 말은 요청이 동기적으로 실행된다는 것을 의미한다. (한번에 하나씩 처리!)

 

Web API

Web API 는 브라우저에서 제공하는 API로, DOM, Ajax, Timeout등이 있다.

Call Stack에서 실행된 비동기 함수는 Web API를 호출하고,
Web API는 콜백함수를 Callback Queue에 밀어 넣는다.

 

Event loop

비동기 요청은 자바스크립트를 실행하는 환경인 브라우저나 Node.js가 담당한다.

자바스크립트 엔진과 실행 환경을 상호 연동시켜주는 장치가 Event Loop이다.

Call Stack과 Callback Queue의 상태를 체크하여 Callstack이 비어있을 때

Queue에 있는 콜백함수를 꺼내와서 Callstack에 쌓는다. 이것을 tick이라고 부른다.

 

태스크큐/ 마이크로 태스크 큐

위에 Callback Queue라고 묶어서 적었지만 자바스크립트의 실행 환경은 2가지의 큐를 가지고 있다.

각각 스크립트 실행, 이벤트 핸들러, 콜백함수 등의 태스크가 담기는 공간이지만

종류에 따라 다른 큐에 담긴다.

 

태스크큐 : setTimeout() , setInterval() , UI 렌더링, requestAnimationFrame()

마이크로 태스크큐: Promise, MutationObserver

 

* 마이크로 태스크 큐의 콜백함수가 우선순위를 가진다.

 

우선순위 및 동작방식 예시

console.log('콜 스택');
setTimeout(() => console.log('태스크 큐'), 0);
Promise.resolve().then(() => console.log('마이크로태스크 큐'));

1. 스크립트가 실행되면 전역 객체가 테스크 큐에서 콜스택으로 이동되며 실행된다.

2. 전역에 있던 console.log('콜 스택');를 실행하고 콜 스택에서 사라진다.

3. 콜 스택이 비게되어 setTimeout을 콜 스택에 가져오고 실행된다.

4. 콜 스택에서 실행된 비동기 함수인 setTimeout의 콜백함수는 web API로 옮겨지고

   setTimeout의 타이머를 동작시킨다.

5. 타이머가 종료되면 setTimeout의 콜백 함수를 태스크큐에 넣는다.

6. 그리고 promise를 콜 스택으로 가져오게되고 실행하여 promise의 콜백함수를 마이크로 태스크 큐에 넣는다.

* 현재 콜 스택은 비어있고 태스크큐에는 setTimeout의 콜백함수, 마이크로 태스크큐에는 promise의 콜백함수가 있게된다..

7. 마이크로태스크큐의 콜백함수가 우선순위기 때문에 이벤트 루프는 마이크로 태스크큐에서

   가장 오래된 태스크인 promise의 콜백함수를 가져와서 콜스택에 넣어 실행시킨다. 

8. 마이크로 태스크큐가 비어있으니 태스크큐에서 가장 오래된 태스크인 setTimeout()의 콜백함수를

콜스택에 넣어 실행시킨다.

 

 

처음 접했을 때 헷갈렸는데 함수를 실행하려면 콜스택으로 가야 한다는 점.

각각의 콜백함수는 해당 하는 큐에 들어 간다는 점.

처음에 실행되는 함수와 콜백함수를 구분해야한다는 점을 생각하면서 보니 이해가 되었다.


✍ 느낀점

 

면접 기술질문을 준비하며 접했던 개념들을 다시 접하게 되어

반가운 마음에 빈약했던 부분을 다시 알아보고 스스로에게 설명해보면서 적게되었다.

이전에는 깊게 살펴보지는 못했는데 오늘 다시 보니 한 가지 개념만 파도 하루 종일 볼 수 있을 것 같다..

객체 지향, 절차 지향, 함수형 프로그래밍에 대해 알게되니 대체적으로 나는 절차지향적인 코드를 짜왔던 것 같다.. 🤣

이후의 함수형 프로그래밍에 대한 사고에 대해 궁금하고

함수형 프로그래밍 파트의 강의들이 기대된다!! 

프로토타입도 아직 이해가 끝까지 되지는 않지만 좀 더 많이 접해봐야 할 듯 하다.

 

 

참고:

책: 코어자바스크립트

이벤트루프

객체지향 프로그래밍과 함수형 프로그래밍

TLS 핸드셰이크의 원리는 무엇일까요?
브라우저에 URL을 입력했을 때 발생하는 일들
맥 어드레스란 무엇인가?

Comments