프론트엔드 면접 질문 정리 Part1(CS, JS,React)

박먼지·2023년 9월 12일
13

CS지식

브라우저 주소창에 www.google.com을 입력하면 어떤 일이 일어나나요?

주소창에 www.google.com을 입력하면 웹 브라우저는 우선 캐싱된 DNS기록을 찾아보고 기록에 없을 경우 DNS에게 도메인 주소를 요청하여 IP주소를 응답받습니다. 웹 브라우저는 IP 주소를 이용하여 웹 서버에게 HTTP 요청을 하고, 서버에게서 응답 받은 HTML을 화면에 출력합니다.

GET과 POST의 차이는 무엇인가요?

GET은 정보를 요청할 때 사용하는 메서드이고, POST는 서버에 데이터를 보내는데 사용됩니다.

객체 지향 프로그래밍이란 무엇인가요?

객체 지향 프로그래밍은 컴퓨터 프로그래밍 패러다임 중의 하나로, 프로그래밍에서 필요한 데이터를 추상화시켜 객체로 만들고 그 객체들 간의 상호작용을 통해 로직을 구성하는 프로그래밍 방법입니다.

프로세스와 스레드에 대해 설명해주세요.

프로세스는 메모리 상에서 실행중인 프로그램을 말하고, 스레드는 이 프로세스 안에서 실행되는 흐름 단위를 말합니다.

DNS에 대해 설명해주세요.

DNSURLIP 주소를 변환해주는 역할을 하는 시스템을 말합니다. IP는 숫자로 되어있어 사람이 이해하기 어렵기 때문에 사람이 알아볼 수 있는 URL로 변환하는 작업이 필요합니다.

REST API에 대해 설명해주세요.

REST를 기반으로 만들어진 API를 말합니다.
RESTHTTP를 기반으로 필요한 자원에 접근하는 방식을 정해놓은 아키텍처입니다.
REST API는 자원(URI), 행위(HTTP 메서드), 표현(페이로드)으로 이루어져 있으며 HTTP 메서드를 사용해야 하고, URI가 리소스를 표현하는데 집중해야 합니다.

Javascript

Promise와 Callback의 차이를 설명해주세요.

Callback은 비동기 로직의 결과값을 Callback 안에서만 처리를 할 수 있고, 콜백 밖에서 비동기로 온 값을 알 수 없습니다. 하지만 Promise는 비동기에서 온 값이 promise 객체에 저장되어서 코드 작성이 용이합니다.

async, await의 사용 방법을 설명해주세요.

함수 앞에 async키워드를 붙이면 이 함수는 항상 promise를 반환합니다.
await키워드는 async함수 안에서만 동작하는데, await키워드를 promise객체 앞에 붙이면 자바스크립트가 promise를 처리할 때까지 기다리고, 처리가 완료되면 에러가 발생하거나 promise객체의 result 값을 반환합니다.

var, let, const의 차이를 설명해주세요.

var는 중복 선언이 가능하고 선언과 동시에 초기화가 이루어지기 때문에 호이스팅이 발생하는 것 처럼 보여서 코드를 파악하기 힘듭니다.
letconst는 선언만 이루어지고 초기화는 변수 선언문에서 이루어지기 때문에 호이스팅이 발생하지 않는 것 처럼 보입니다.
let은 중복 선언이 불가능하고, 재할당이 가능합니다.
const는 중복 선언과 재할당이 불가능합니다.

이벤트 버블링과 캡처링에 대해 설명해주세요(예시와 함께).

이벤트 버블링은 한 요소에 이벤트가 발생하면 최상단의 부모 요소의 이벤트까지 전파되는 것을 말합니다.
이벤트 캡쳐는 이벤트 버블링과 반대로 최상위 태그에서 해당 태그로 이벤트가 전파되는 것을 말합니다.

이벤트 버블링 예시
li태그 각각에 이벤트를 다는 대신 상위ul에 이벤트를 다는 방법

이벤트 캡처링 예시
버블링보다 성능이 좋다고 하지만.. 구체적인 예시는 조사 필요

클로저에 대해 설명해주세요.

클로저는 자신이 생성될 때의 환경을 기억하는 함수라고 할 수 있습니다.
클로저는 외부 함수의 실행이 종료되어도 내부 함수에서 외부 함수를 참조하고 있다면 외부 함수 내 변수를 사용할 수 있습니다.

실행 컨텍스트에 대해 설명해주세요.

실행 컨텍스트는 실행할 코드에 제공할 환경 정보들을 모아놓은 객체입니다. 자바스크립트는 실행 컨텍스트를 콜스택에 쌓아올린 후 실행해서 코드의 환경과 순서를 보장할 수 있습니다.

호이스팅에 대해 설명해주세요.

호이스팅은 스코프 내의 선언을 해당 스코프의 최상단으로 끌어올린 것 처럼 보이는 현상을 말합니다. 자바스크립트 엔진은 런타임 이전에 실행 컨텍스트에 식별자의 정보를 등록하기 때문에 일어나는 현상입니다.

불변성을 유지하려면 어떻게 해야하나요?

객체의 불변성을 유지하려면 스프레드 문법을 사용하거나(얕은 복사만 가능), immer 라이브러리를 사용하거나 structuredClone 함수를 사용해 객체의 불변성을 유지할 수 있습니다.

자바스크립트가 유동적인 언어인 이유는 무엇인가요?

자바스크립트는 런타임 시점에 타입이 결정되는 동적 언어입니다. 매번 타입을 쓸 필요가 없기 때문에 빠르게 코드를 작성할 수 있습니다.

this에 대해 설명해주세요.

this는 자신이 속한 객체 또는 자신이 생성할 인스턴스를 가리키는 자기 참조 변수입니다.
this를 통해 자신이 속한 객체나 자신이 생성할 인스턴스의 프로퍼티나 메서드를 참조할 수 있습니다. this 바인딩은 함수 호출 방식에 의해 동적으로 결정됩니다.

콜백 지옥(Callback hell)을 해결하는 방법을 말씀해주세요.

콜백 지옥은 비동기 처리를 위해 콜백 함수를 연속해서 사용해서 코드가 깊어지는 것을 말합니다. 이를 해결하기 위해서는 PromiseAsync await을 사용하는 방법이 있습니다.

Promise를 사용한 비동기 통신과 async, await를 사용한 비동기 통신의 차이를 설명해주세요.

Promise를 사용하면 .catch()문을 통해 에러 핸들링이 가능하지만 async/await은 에러 핸들링 기능이 없어 try-catch문을 활용해야 합니다.
async/await은 비동기 코드가 동기 코드처럼 읽히게 해줘서 코드 흐름을 이해하기 쉽습니다.

함수 선언형과 함수 표현식의 차이에 대해 설명해주세요.

함수 선언식은 함수명이 정의되어 있고, 별도의 할당 명령이 없는 것을 말합니다.
함수 표현식은 함수를 별도의 변수에 할당하는 것을 말합니다.

함수 선언식과 함수 표현식의 주요 차이점은 호이스팅입니다.
함수 선언식은 함수 전체를 호이스팅해서 함수 선언 전에 함수를 사용할 수 있지만
함수 표현식은 선언부만 호이스팅 되기 때문에 함수 선언 전에 함수를 사용하면 오류가 납니다.

렉시컬 환경(Lexical Environment)에 대해 설명해주세요.

렉시컬 환경은 특정 코드가 선언된 환경을 말합니다.

데이터 타입에 대해 설명해주세요.

자바스크립트의 데이터 타입은 원시 타입객체 타입으로 나뉩니다. 원시 타입의 값은 변경 불가능한 값이며 값에 의한 전달이 일어납니다. 객체는 참조에 의한 전달이 일어납니다.

깊은 복사와 얕은 복사에 대해 설명해주세요.

얕은 복사는 참조 타입 데이터가 저장한 메모리 주소 값을 복사한 것을 말하고
깊은 복사는 새로운 메모리 공간을 확보해 완전히 복사하는 것을 말합니다.

requestAnimationFrame을 사용해본 적 있나요?

requestAnimationFrame 메서드는 애니메이션 관련 최적화 API 입니다. 자바스크립트로 스타일을 변화시키는 방법은 CSS보다 성능이 좋지 않기 때문에 성능 최적화가 필요합니다.
requestAnimationFrame 함수는 시스템이 프레임을 그릴 준비가 되면 애니메이션 프레임을 호출합니다.
requestAnimationFrame을 사용하면 페이지가 비활성화 된 경우 페이지 화면 그리기 작업이 일시 중지되기 때문에 CPU 리소스를 낭비하지 않고, 모니터의 주사율을 따라 호출하기 때문에 별도의 반복 플래그가 필요 없습니다.

React

Virtual DOM이 무엇이고 작동 원리에 대해 설명해주세요

Virtual DOM은 실제 DOM의 복사본으로, JS 객체 형태로 메모리 안에 저장됩니다. 리액트는 state가 변경될 때 마다 re-rendering이 발생하는데, 이 시점마다 새로운 내용이 담긴 가상돔을 생성하게 됩니다. 렌더링 이전의 가상돔과 업데이트 이후의 가상돔을 비교해 차이가 발생한 부분만을 실제 DOM에 적용하게 됩니다. 리액트는 Batch Update를 통해 변경된 모든 Element들을 집단화 시켜 이를 한번에 실제 DOM에 적용시키기 때문에 효율적입니다.

*어마어마한 DOM조작이 필요할 때 Virtual DOM 사용이 좋음, 그 외는 기존 DOM 조작이 성능이 빠름

React를 사용하는 이유에 대해 말씀해주세요.

가장 큰 이유는 컴포넌트 기반 개발이 가능하다는 점입니다.
컴포넌트 단위 개발은 가독성이 좋고 재사용성, 확장성과 같은 이점이 있습니다.
또한 리액트의 생태계는 여타 다른 라이브러리, 프레임워크 커뮤니티보다 활발하고, React를 기반으로 React Native를 활용해서 모바일 앱을 만들 수 있습니다.

클래스형 컴포넌트와 함수형 컴포넌트의 차이에 대해 설명해주세요.

클래스형 컴포넌트는 LifeCycle API를 사용하고, 함수형 컴포넌트에서는 Hook을 사용합니다.
그리고 클래스형 컴포넌트는 this.props로 props를 받는데, this가 변경 가능한 object기 때문에 값이 달라질 수 있습니다. 함수 컴포넌트는 인자를 변경할 수 없기 때문에 렌더링 된 값들을 고정시킵니다.

생명 주기 메서드에 대해 설명해주세요.

리액트 컴포넌트는 생성(mount) > 업데이트(update) > 제거(unmount)의 생명주기를 갖습니다.

📌마운트시 호출되는 메서드

  • constructor : 컴포넌트를 새로 만들 때마다 호출되는 클래스 생성자 메서드
  • getDerivedStateFromProps : props 에 있는 값을 state 에 넣을 때 사용하는 메서드
  • render : 준비한 UI를 렌더링하는 메서드
  • componentDidMount : 컴포넌트가 웹 브라우저상에 나타난 후 호출하는 메서드

📌업데이트시 호출되는 메서드

  • getDerivedStateFromProps : 앞서 Mount 과정에서도 호출되고, props 변화에 따라 state 값에도 변화를 주고 싶을 때 사용
  • shouldComponentUpdate : 컴포넌트가 리렌더링을 해야 할지 말아야 할지를 결정, true 를 반환하면 다음 라이프사이클 메서드를 계속 실행, false 를 반환하면 작업을 중지(리렌더링 X)한다.
  • render : 컴포넌트를 리렌더링한다.
  • getSnapshotBeforeUpdate : 컴포넌트 변화를 DOM에 반영하기 바로 직전에 호출
  • componentDidUpdate : 컴포넌트의 업데이트 작업이 다 끝난 후 호출

📌언마운트시 호출되는 메서드

  • componentWillUnmount : 컴포넌트가 웹 브라우저상에서 사라지기 전에 호출

리액트에서 JSX 문법이 어떻게 사용되나요?

JSX는 Javascript에 XML을 추가한 문법으로 하나의 파일에 자바스크립트와 HTML을 동시에 작성할 수 있어서 편리합니다. 리액트 엔진은 JSX코드를 일반 자바스크립트 형태의 코드로 변환합니다.

JSX 문법이 반드시 부모 요소 하나가 감싸는 형태여야 하는 이유?
Virtual DOM에서 컴포넌트의 변화를 감지할 때 효율적으로 비교할 수 있도록 컴포넌트 내부는 하나의 DOM 트리 구조로 이루어져야 한다는 규칙이 있기 때문입니다.

왜 state를 직접 바꾸지 않고 useState를 사용해야 하나요?

리액트는 메모리 주소를 통해 값이 변경되었다는 것을 판단하기 때문에 새로운 객체를 만들어서 할당해야 합니다. 따라서 이를 위해 useState를 사용해야 합니다.(setState가 실행되면 새 scope를 만들어 state 변수도 새로 만들게 된다.)

useMemo와 useCallback에 대해 설명해주세요.

useMemo는 메모이제이션된 값을 return하는 hook이고, useCallback은 메모이제이션된 함수를 반환하는 hook입니다.

useMemo를 사용해야 할 때)
특정한 상황에서 동작되야 하는 함수가 Component의 렌더링 조건에 따라 지속적으로 실행되는 경우

그럼 useEffect를 사용하면 되지 않나?
사용 용도가 다릅니다. useEffect는 부수효과를 만들기 위해 사용합니다. 어떤 값이 바뀌었을 때 그 변화를 지정한 함수를 실행함으로써 전파합니다. useMemo는 특정 값을 메모하여 해당 값을 얻는 과정이 불필요하게 반복되는 것을 방지하기 위해 사용합니다.
useEffect는 side-effect를 위한 훅, useMemo는 side-effect가 존재하면 안된다. 즉 순수함수여야 합니다.

useCallback을 사용해야 할 때)
자식 컴포넌트에 함수를 props로 줄 때(자식 컴포넌트의 불필요한 렌더링 방지),
외부에서 값을 가져오는 api를 호출하는 경우

+ useMemo와 useState의 차이

useMemo는 의존성에 따라 값이 자동적으로 바뀌는 경우에 사용한다.

// b와 c를 더한 값이 a가 되는 경우
const a = useMemo(() => {b + c}, [b, c]);

useState는 서버에서 값을 받아오거나 사용자로부터 입력을 받는 경우(onChange마다 변경이 일어남)에 사용한다.

+ useMemo, React.memo

useMemo는 hook이라서 함수형 컴포넌트에서만 사용 가능하고,
React.memo는 클래스형 컴포넌트와 함수형 컴포넌트에서 사용 가능합니다.
useMemo는 리턴되는 값을 메모이제이션 하는데, 의존성 배열에 있는 값이 바뀌는 경우 호출됩니다.
React.memo는 컴포넌트를 메모이제이션하는데, 컴포넌트의 props가 바뀌지 않으면 리렌더링 하지 않습니다.

리액트에서 메모이제이션을 어떤 방식으로 하나요?

리액트에서 메모이제이션은 React.memo, useCallback, useMemo를 통해 사용할 수 있습니다.

React.memo의 경우 props의 값으로 변경을 확인하고
useCallbackuseMemo는 dependency 배열 내부의 값으로 변경 사항을 확인합니다.

리액트의 렌더링 성능 향상을 위해 어떻게 해야 하나요?

useMemo, React.memo, useCallback의 사용,
자식 컴포넌트의 props로 객체를 넘겨줄 때 객체를 변형하거나 새로 생성하지 않고 그대로 넘겨주기, 컴포넌트를 매핑할 때 key값으로 index를 사용하지 않기, useState의 함수형 업데이트 사용, 디바운싱과 쓰로틀링 적용 등이 있습니다.

React-query에 대해 설명해주세요.

React-query는 React 환경에서의 비동기 Query(질의)과정을 도와주는 라이브러리입니다.
React-query는 데이터를 캐싱해서 반복적인 데이터 호출을 방지하고, 서버 데이터와 클라이언트 데이터를 분리하고(클라이언트 데이터는 상태 관리 라이브러리가 관리하고, 서버 데이터는 React-query가 관리), useQuery가 반환하는 isLoadingerror객체를 통해 상황별 분기 처리를 쉽게 진행할 수 있습니다.

React 18 버전 업데이트 내용에 대해 말씀해주세요.

새로운 Root API(ReactDOM.createRoot)가 적용되었습니다.
React Event Handler뿐만 아니라 promise, setTimeout, native event handler 등 다양한 로직에서 Batching 작업이 가능해졌습니다.
React에서 제공해주는 API를 통해 CRA에서도 SSR을 활용한 아키텍처를 설계할 수 있습니다.
Suspense를 통해 Streaming HTML과 Selective Hydration을 사용할 수 있습니다..

어려워서 다시 공부해야 할 듯.

hydration
정적 호스팅이나 SSR 서버에서 받은 HTML 웹 페이지를 동적 HTML 웹 페이지로 바꿔주는 기술을 말합니다.

useEffect와 useLayoutEffect의 차이점에 대해 말씀해주세요.

useEffect는 비동기적으로 렌더링 후에 호출되고, useLayoutEffect는 동기적으로, paint가 되기 전에 실행됩니다. useLayoutEffect는 애니메이션 구현 등 즉시 반응이 필요한 경우나 성능 모니터링의 경우 사용하면 좋습니다.

ContextAPI에 대해 설명해주세요.

Context는 리액트 컴포넌트 간에 값을 공유할 수 있게 해주는 기능으로, 주로 전역적으로 필요한 값을 다룰때 사용합니다.

Key Props를 사용하는 이유는 무엇인가요?

map을 사용할 때 리액트가 key를 통해 어떤 항목을 변경, 추가 삭제할지 식별하기 때문에 엘리멘트의 고유성을 부여하기 위해 key를 지정해야 합니다.

제어 컴포넌트와 비제어 컴포넌트의 차이에 대해 설명해주세요.

제어 컴포넌트는 사용자의 입력을 기반으로 자신의 state를 관리하고 업데이트합니다.(setState()사용)
비제어 컴포넌트는 기존의 바닐라 스크립트와 같이 사용자가 직접 트리거 하기 전까지 리렌더링을 발생시키지 않고 값을 동기화 시키지도 않습니다.(ref사용)

props와 state의 차이는 무엇인가요?

props는 부모 컴포넌트에서 상속 받는 데이터로 데이터를 변경할 수 없습니다.
state는 자기 자신의 컴포넌트에서 만들어낸 데이터이며 변경할 수 있습니다.

pure component에 대해 설명해주세요.

pureComponentshouldComponentUpdate()안에 얕은 비교가 적용된 버전입니다.
즉, pureComponent를 사용하면 리액트의 성능을 향상시키는 데 가장 중요한 것 중 하나인 shouldComponentUpdate를 신경쓰지 않아도 됩니다.

shouldComponentUpdate에 대해 설명해주세요.

shouldComponentUpdate()는 props또는 state가 새로운 값으로 갱신되어 렌더링이 발생하기 직전에 호출됩니다. shouldComponentUpdate()을 사용하면 조건에 따라 데이터가 변경되어 렌더링이 필요한 경우에만 렌더링 작업을 수행할 수 있습니다.

리액트 관련 패키지 중에 제일 좋다고 생각한 것은 무엇인가요?

styled-components입니다. css에 js를 적용할 수 있고, 스타일 컴포넌트의 변수명에 해당 컴포넌트의 기능을 넣었을 때 가독성이 좋아진다고 느꼈습니다.

참조
https://velog.io/@humonnom/React-useEffect-useMeme-%EA%B7%B8%EB%A6%AC%EA%B3%A0-useCallback-%EA%B0%81-%EC%82%AC%EC%9A%A9%EB%B2%95%EA%B3%BC-%EC%B0%A8%EC%9D%B4
https://velog.io/@shin6403/React-%EB%A0%8C%EB%8D%94%EB%A7%81-%EC%84%B1%EB%8A%A5-%EC%B5%9C%EC%A0%81%ED%99%94%ED%95%98%EB%8A%94-7%EA%B0%80%EC%A7%80-%EB%B0%A9%EB%B2%95-Hooks-%EA%B8%B0%EC%A4%80
https://velog.io/@youngminss/React-%EC%BB%B4%ED%8F%AC%EB%84%8C%ED%8A%B8-%EC%83%9D%EB%AA%85%EC%A3%BC%EA%B8%B0-%EB%A9%94%EC%84%9C%EB%93%9C
그 외 미처 올리지 못한 출처들

profile
개발괴발

0개의 댓글