CS_study

[기술 면접 준비] Mockterview_React_50제_27~43번

soobin Choi 2023. 2. 16. 12:06

29. TCP 3 way handshake란 무엇인지 설명해주실 수 있을까요?

TCP/IP 프로토콜에서 연결 설정을 위해 사용하는 세 단계의 과정으로 클라이언트와 서버 간의 데이터 통신을 시작하기 위해 필요함. 1. SYN(Synchronize Sequence Numbers): 클라이언트는 서버에게 SYN 패킷을 보내고, 클라이언트가 사용할 초기 시퀀스 번호를 전송함. 이 패킷은 클라이언트에서 서버로 전송됨. 2.SYN-ACK(Synchronize-Acknowledgment): 서버는 클라이언트의 SYN 패킷을 수신하면, SYN-ACK 패킷을 클라이언트로 전송함. 이 패킷은 서버에서 클라이언트로 전송됨. 이 패킷에는 서버의 초기 시퀀스 번호와 클라이언트가 보낸 시퀀스 번호에 1을 더한 값이 포함됨. 3. ACK(Acknowledgment): 클라이언트는 서버의 SYN-ACK 패킷을 수신하면, ACK 패킷을 서버로 전송함. 이 패킷에는 서버의 초기 시퀀스 번호에 1을 더한 값이 포함됨. 이렇게 연결이 설정되면, 클라이언트와 서버 간의 데이터 통신이 시작됨.

31. TCP 와 UDP 를 비교하여 설명해주실 수 있을까요?

TCP(Transmission Control Protocol), UDP(User Datagram Protocol) 모두 패킷을 한 컴퓨터에서 다른 컴퓨터로 전달해주는 IP 프로토콜을 기반으로 구현되어 있고, 데이터 오류 검사를 위한 체크섬이 존재함. tcp는 신뢰성 있는 데이터 전송을 지원하는 연결 지향형 프로토콜. 일반적으로 tcp와 ip가 함께 사용되는데, ip가 데이터 전송을 처리한다면 tcp는 패킷 추적 및 관리를 함. 연결 지향형인 3 way handshaking의 과정을 통해 연결 후 통신을 시작하는데 흐름제어와 혼잡제어를 지원하며 데이터의 순서를 보장함. udp는 비연결 지향형 프로토콜로 인터넷상에 서로 정보를 주고받을 때 정보를 보내는 쪽에서 일방적으로 데이터를 전달하는 통신 프로토콜. tcp와는 다르게 연결 설정이 없으며 혼잡제어를 하지 않기 때문에 tcp보다 전송속도는 빠름. 그러나 데이터 전송에 대한 보장을 하지 않기 때문에 패킷 손실이 발생할 수 있음.

+ tcp는 연속성보다 신뢰성이 중요할 때 사용하며 udp는 신뢰성보다 연속성이 중요한 실시간 스트리밍과 같은 서비스에서 주로 이용함.

32. Base64 인코딩이란 무엇인가요?

Base64란 8비트 2진 데이터(Binary data)를 문자 코드에 영향을 받지 않는 공통 ASCII 영역의 문자로만 이루어진 일련의 문자열 text로 바꾸는 인코딩 방식임. 인터넷을 통해 전송되어야 하는 이미지, 오디오 파일 및 기타 유형의 데이터를 인코딩하기 위해 웹 응용 프로그램, 이메일 시스템 및 기타 네트워크 소프트웨어에 널리 사용됨. Base64 인코딩 데이터는 일반적으로 원래 이진 데이터보다 약 33% 더 크지만 다른 텍스트 기반 인코딩 체계보다 훨씬 더 압축적임. 소프트웨어가 텍스트를 처리할 수 있는 한 모든 플랫폼에서 사용할 수 있음. 대부분의 프로그래밍 언어와 운영 체제에서 지원됨. 즉, HTML 또는 Email과 같이 문자를 위한 Media에 Binary Data를 포함해야 될 필요가 있을 때, 포함된 Binary Data가 시스템 독립적으로 동일하게 전송 또는 저장되는걸 보장하기 위해 사용됨. 

+ 인코딩이란 파일에 저장된 정보의 형태나 형식을 데이터 표준화, 보안, 처리 속도 향상, 저장 공간 저장 등을 위해 다른 형태로 변환하는 처리 혹은 방식. 전반적으로 Base64는 안전하고 신뢰할 수 있는 방식으로 인터넷을 통해 이진 데이터를 전송하는 데 유용한 도구

33. 프로세스와 스레드를 비교하여 설명해주실 수 있을까요?

✔️ 답변

프로그램은 보조기억장치에 존재하며 실행되기를 기다리는 명령어와 정적 데이터의 묶음. 프로그램의 명령어와 정적데이터가 메모리에 적재되면 프로세스.  프로세스는 운영체제로부터 시스템 자원을 할당받은 작업의 단위(프로그램의 단위) 스레드는 프로세스가 할당받은 자원을 이용하는 실행 흐름의 단위(프로세스 실행 단위) 운영체제는 프로세스마다 각각 독립된 메모리 영역을, Code/Data/Stack/Heap의 형식으로 할당함. 그러나 스레드는 프로세스가 할당받은 메모리 영역 내에서 Stack 형식으로 할당된 메모리 영역은 따로 할당받고, 나머지 Code/Data/Heap 형식으로 할당된 메모리 영역을 공유함. 스레드는 멀티스레드와 싱글스레드가 있음. 멀티스레드는 하나의 응용프로그램을 여러 개의 스레드로 구성하고 각 스레드로 하여금 하나의 작업을 처리하도록 하는 것을 뜻하고 싱글스레드는 하나의 프로세스에서 오직 하나의 스레드로만 실행하는 것을 뜻함.

 

✔️ 추가 : 프로그램, 프로세스, 스레드

실행이 안 되고 가만히 있으면 프로그램, 실행되면 프로세스임. 쉽게 말해서 코드 덩이리가 프로그램, 코드를 실행한 것이 프로세스, 코드에서 각각의 실행되는 함수가 스레드.

✔️ 추가 : 프로세스와 스레드의 차이 

따라서 각각의 스레드는 별도의 스택을 가지고 있지만 힙 메로리는 서로 읽고 쓸 수 있게 됩니다. 만약 한 프로세스가 실행하다가 오류가 발생하면 프로세스가 강제종료된다면 다른 프로세스에는 영향을 주지 않지만 스레드는 오류로 종료가 된다면 메모리 영역을 공유하고있는 스레드 모두 강제로 종료된다는 중요한 차이점이 존재합니다.

✔️ 추가 : 프로세스 vs 스레드

프로세스는 운영 체제에서 실행 중인 프로그램의 인스턴스입니다. 자체 메모리 공간, 자체 시스템 리소스 세트 및 자체 주소 공간이 있습니다. 프로세스는 서로 격리되어 있으므로, 특별한 메커니즘이 없으면 서로의 메모리나 리소스에 액세스할 수 없습니다. 반면 스레드는 운영 체제에서 관리할 수 있는 경량 하위 프로세스입니다. 프로세스와 달리 스레드는 동일한 프로세스 내의 다른 스레드와 메모리 및 리소스를 공유합니다. 여러 스레드가 동일한 주소 공간 내에서 실행될 수 있으므로 데이터를 공유하고 서로 더 쉽게 통신할 수 있음.

- 주요 차이점

1. 리소스 사용량: 각 프로세스에는 고유한 리소스 세트(예: 메모리, 파일 핸들 및 네트워크 연결)가 있지만 스레드는 프로세스 내에서 이러한 리소스를 공유합니다.

2. 생성 시간: 각 프로세스에는 자체 메모리 공간과 리소스가 필요하기 때문에 새 프로세스를 생성하는 것보다 새 프로세스를 생성하는 것이 리소스 집약적입니다.

3. 컨텍스트 전환: 운영체제가 프로세스를 전환할 때는 상대적으로 비용이 많이 드는 프로세스의 전체 상태를 저장하고 복원해야 한다. 프로세스 내에서 스레드 간에 전환할 때 스레드의 스택과 레지스터만 저장 및 복원하면 되기 때문에 컨텍스트 전환이 훨씬 빠릅니다. 내결함성: 프로세스가 중단되거나 종료되는 경우 다른 프로세스 또는 시스템 전체에 영향을 주지 않습니다. 그러나 스레드가 충돌하거나 오류를 발생시킬 경우 전체 프로세스와 모든 스레드가 중단될 수 있습니다.

요약하자면, 프로세스는 자체 메모리 공간과 시스템 리소스를 갖는 독립 실행 단위인 반면, 스레드는 동일한 프로세스 내의 다른 스레드와 메모리 및 리소스를 공유하는 경량 하위 프로세스입니다. 프로세스는 내결함성과 격리성을 향상시키는 반면 스레드는 높은 수준의 병렬 처리가 필요한 작업에 더 빠르고 효율적입니다.

35. 깊은 복사와 얕은 복사의 차이는 무엇이고 JS에서 각각을 구현하는 방법은 어떻게 되는지 설명해주실 수 있을까요?

✔️ 답변

자바스크립트에서 객체를 변수에 할당하면 변수에는 참조값이 저장됨. 따라서 객체를 복사하는 경우 참조값만 복사되는 얕은 복사가 일어남. 원본 객체는 하나인 상태에서 참조값을 공유하기 때문에 복사된 객체에서 값을 수정하면 원본도 수정됨. 깊은 복사는 참조값이 다른 아예 완전한 새로운 객체를 만드는 복사. 원본 객체에 대한 변경 사항은 별도의 객체이므로 딥 복사본에 영향을 미치지 않음. 얕은 복사 구현 1. Object.assign()으로 첫번째 요소로 들어온 객체에 다음 인자로 들어온 객체를 복사 2. 전개 연산자. / 깊은 복사 구현 1. 재귀함수 이용 2. JSON.stringify()로 json 문자열로 변환 후 JSON.parse()로 다시 자바스크립트 객체를 만들어줌(함수, Date 객체, 정규표현식 등의 데이터는 복사되지 않고 두번째 이유는 다른 깊은복사 방법들(재귀함수, lodash) 보다 느리다는 단점) 3. lodash 라이브러리를 사용

 

✔️ 추가

보통 전개연산자를 이용해서 복사를 하는데 이 경우에도 객체안에 객체가 있는 중첩 형태인 경우 중첩된 부분이 또 다시 얕은 복사가 일어나게 됩니다. 따라서 이러한 경우에는 함수 안에 또 다시 함수를 호출하여 참조된 객체를 분리시키는 작업을 하여 깊은 복사를 하는 재귀함수를 만들어서 복사하면 됩니다. 이렇게 되면 가장 깊게 중첩된 부분부터 깊은 복사가 일어나므로 완전히 다른 두 복사본을 만들 수 있습니다.

✔️ 코드

JavaScript의 Shallow copy는 원래 객체를 참조하는 새 객체를 만듭니다. 원본 객체에 대한 변경 사항은 동일한 객체 참조를 공유하기 때문에 얕은 복사본에도 영향을 미칩니다.

let original = {a: 1, b: 2};
let shallowCopy = Object.assign({}, original);

JavaScript의 Deep copy는 새로운 오브젝트를 만들고 원본 오브젝트의 모든 속성과 중첩된 오브젝트를 복사한다. 즉, 원본 객체에 대한 변경 사항은 별도의 객체이므로 딥 복사본에 영향을 미치지 않습니다.

let original = {a: 1, b: {c: 2}};
let deepCopy = JSON.parse(JSON.stringify(original));

37. JS의 passed by value 와 passed by reference 에 대해 아는 만큼 설명해주실 수 있을까요?

프로그래밍에는 인수를 함수로 전달할 수 있는 두 가지 주요 방법, 값과 참조가 있음. passed by value 어떤 값을 메모리 공간에 직접 넣고 변수를 할당함. 값이 값으로 전달되면 값의 복사본이 만들어지고 함수로 전달됨. 즉, 함수 내부의 값을 변경해도 함수 외부의 원래 값에는 영향을 미치지 않음. numbers, strings, booleans 과 같은 기본 유형은 일반적으로 값으로 전달됨. 메모리의 새로운 공간에 저장을 하므로 메모리 비용이 큼. passed by reference 어떤 값을 저장한 메모리의 주소를 변수에 넣는 방법. 값이 참조로 전달되면 원래 값에 대한 참조가 함수에 전달됨. 즉, 함수 내부의 값을 변경하면 함수 외부의 원래 값에 영향을 미침. 객체와 배열은 일반적으로 참조를 통해 전달됨. 즉, 값을 전달하면 함수에 전달되는 값의 복사본이 생성되고 참조를 전달하면 함수에 전달되는 원래 값에 대한 참조가 전달됨.

38. 고차 함수란 무엇인지 설명해주실 수 있을까요?

고차 함수(HOF: Higher-Order Function)는 함수를 매개변수(Parameter)로 사용하거나 함수를 반환하는 함수. 우리가 정의해서 사용하는 함수가 함수를 인자(Argument)로 받아서 사용하거나 결과 값으로 함수를 반환하게 한다면 고차 함수라는 뜻. 고차 함수는 동작(action)을 추상화할 수 있게 함. 함수형 프로그래밍의 핵심이기도 하며, 자바스크립트를 함수형 프로그래밍에 알맞은 언어로 만들어주는 특성이기도 함. 광범위한 상황에 적응할 수 있는 간결하고 유연한 코드를 작성하는 강력한 도구. 대표적으로 고차함수를 사용한 메서드는 map, filter, reduce가 있음. 예를 들어 map 함수로 문자열 목록을 대문자로 변환하거나 배열에서 각 숫자의 제곱을 계산하는 등 광범위한 시나리오에서 사용할 수 있음. 상수 let으로 함수 내부에서 바로 표현해주며 할당할 수 있어 한번에 표현이 가능하고 사이드 이펙트 발생을 막아주며, 간결하다는 장점이 있음. 

41. VanillaJS와 비교하여 리액트를 사용하는 이유에 대해 설명해주실 수 있을까요?

✔️ 답변

리액트는 컴포넌트 기반 아키텍처를 사용하여 UI를 구성하는 데 집중함. 1. 가독성과 유지 보수성이 높음: 리액트는 컴포넌트 기반 아키텍처를 사용하므로 코드를 작성하고 이해하기 쉬움. 각 컴포넌트는 자체 로직과 스타일을 포함하므로 유지 보수가 더 쉬워짐. 2. 높은 생산성: 리액트는 빠르고 반응이 빠르며, 개발자들이 재사용 가능한 컴포넌트 라이브러리를 사용하여 작업을 더 쉽고 빠르게 수행할 수 있음. 3. 가상 DOM: 리액트는 가상 DOM을 사용하여 브라우저에 렌더링되는 횟수를 줄임. 이는 성능을 향상시키고, 더 나은 사용자 경험을 제공함. 4. 대규모 애플리케이션 개발 용이: 리액트는 대규모 애플리케이션 개발을 위한 다양한 기능을 제공함. Flux와 Redux 같은 상태 관리 라이브러리를 사용하여 상태 관리를 보다 쉽게 처리할 수 있음. 5. 커뮤니티: 리액트는 매우 큰 개발자 커뮤니티를 보유하고 있으며, 이러한 커뮤니티는 유용한 도구, 라이브러리, 플러그인 및 리소스를 제공함.

✔️ 추가

React는 Virtual DOM을 활용해 실제 DOM에 접근하여 조작하는 대신, 이를 추상화한 자바스크립트 객체를 구성하여 사용한다. 즉 동적으로 데이터가 변화했을 때 직접적으로 DOM을 조작하는 것이 아니라 DOM의 사본이라고 할 수 있는 새로운 Virtual DOM을 생성한다. 그리고 새로 생성된 Virtual DOM과 이전에 저장된 Virtual DOM을 비교해 변경된 부분의 DOM 만을 변경한다.

✔️ 추가

바닐라 자바스크립트에 비해 리액트 등의 라이브러리나 프레임워크를 사용할 떄 두 가지 이점이 있습니다. 첫 번째는 데이터의 변화를 화면에 적용하기 쉽습니다. 예를 들면 바닐라 자바스크립트에서는 바꾸려는 데이터가 쓰인 돔 엘리먼트를 가져와서 변경 내용에 적용해야하는데 이 때도 어느 데이터가 어느 돔엘리먼트에 적용되었는지, 데이터의 업데이트가 많이 일어날수록 중복적으로 작성하는 코드의 양도 많아지는 현상이 발생합니다. 하지만 라이브러리나 프레임워크를 사용하면, 특히 React를 사용하면 state만 변경해줄 경우 Dom이 알아서 업데이트 되어버립니다. 두 번째로 컴포넌트화 하기 쉽다는 것입니다. 바닐라 자바스크립트로 작성할 경우 돔엘리멘트를 만드는데도 코드가 길어지고 감을 잡기 어려운데 React를 쓸 경우 쉽게 컴포넌트를 만들 수 있습니다.

42. 상태의 불변성이 중요한 이유가 무엇인가요?

상태의 불변성이란, 데이터나 객체의 상태가 변경되지 않는 것. 한 번 생성된 객체나 데이터는 그 값을 변경할 수 없으며, 새로운 값을 생성할 수 있음. 이전 상태와 비교해서 변경된 부분만 리렌더링해야 하기 때문에 이전 상태가 원본을 유지해야 함. 또한 state는 객체 형태이므로 내부 속성값만 변경해서는 참조 값이 변경되지 않는데, 참조 값이 변경되지 않은 경우 상태가 변경되지 않은 것으로 판단하고 리렌더링되지 않음. 상태가 불변해야 하는 이유는 1. 값이 변경됐는지 알기 위해서 2. 값을 수정하면, 이전 상태와 바뀐 상태값이 같아지므로 비교할 수 없어서 두 가지가 있음. 리액트에서는 상태가 변하면, 컴포넌트가 리렌더링됨. 리렌더링될 때 값 자체가 아니라 참조 값을 비교하기 때문에 참조 값이 동일하면, 변경을 감지할 수 없음. 또한, 값을 수정하면 이전 상태와 바뀐 상태값이 동일해지기 때문에, 이전 상태와 현재 상태를 비교하여 렌더링할 수 없게 됨.

43. Lazy loading과 Code splitting에 대해 아는 만큼 설명해주실 수 있을까요?

✔️ 답변

Lazy loading은 사용자가 실제로 필요할 때까지 중요하지 않은 리소스의 로딩을 지연시키는 기술. 필요 시점까지 객체의 초기화를 연기시키기 위해 프로그래밍에 흔히 사용되는 디자인 패턴(반복적으로 일어나는 문제들에 대한 솔루션). 사용자가 페이지를 스크롤하거나 특정 요소와 상호 작용할 때 이미지, 비디오 및 기타 멀티미디어 콘텐츠와 같은 추가 리소스가 필요한 경우에만 로드되어 페이지 로드 시간이 크게 향상되고, 데이터 사용량이 감소하며, 전체 사용자 환경이 개선됨. code-splitting은 덩치가 큰 번들을 작은 사이즈로 분할하는 것. 필요하지 않은 코드를 불러오지 않게 하고 페이지를 분리시켜서 필요할 때마다 로딩되도록 할 수 있고 로딩 속도를 개선시킬 수 있음. 번들, 즉 파일이나 라이브러리의 묶음이 커져 렌더링 성능이 저하되거나 많은 리소스가 낭비되는 거대화를 방지하는 방법으로 런타임에 여러 번들을 동작으로 만들고 불러오는 것으로 웹팩, 롤업, 브라우저리파이들이 지원함.

✔️ 추가

리액트는 SPA이기 때문에 전체 페이지를 받아오면서 초기 렌더링 시간이 오래 걸림. 대부분의 리액트 파일들은 Webpack, Rollup, Browserify 등을 사용해서 파일들을 번들링 시킴. 그 다음에는 쪼개져 있었던 여러 개의 파일들을 하나로 합치는 과정을 거침. 그런데, 어플리케이션의 크기가 커지게 된다면 번들파일도 따라서 커지며 특히 굉장히 거대한 서드파티 라이브러리를 포함하고자 하는 경우에는 엄청나게 큰 파일을 맞닥뜨리게 됨. 이를 해결하기 위한 방법으로 code-splitting이 있음. code-splitting을 하기 위한 방법으로 suspense, lazy를 불러와서 lazy-loading을 적용하여 모든 페이지를 로드하지 않고 필요한 페이지만 로드할 수 있음. 즉 code splitting은 lazy loading을 통해 획기적인 성능 향상을 할 수 있음. lazy loading은 무한 스크롤링 기법과도 어느 정도 연관성이 있는 웹 성능 최적화 기법

 

*추후

27. 앞으로 3개월, 6개월, 1년 동안 어떤 것을 공부할 계획인지, 그리고 그러한 계획을 세운 이유는 무엇인지 알려주실 수 있을까요?

28. 삶에서 중요하게 생각하는 가치가 있다면 무엇인가요?

30. 우리 회사에 지원한 동기를 말씀해주실 수 있을까요?

34. 즐겁고 행복했던 경험을 하나 이야기해주실 수 있을까요?

36. 개발자가 되기로 한 이유에 대해 말씀해주실 수 있을까요?

39. 힘들고 쉽지 않았지만 극복한 경험을 하나 이야기해주실 수 있을까요?

40. 다음 함수의 결과의 예측과 근거를 설명해주실 수 있을까요?

46. 재미있게 공부한 알고리즘이 있다면 설명해주실 수 있을까요?