기술면접 준비하기 - 4

강성일·2023년 8월 4일
0
post-thumbnail

💡 Hoisting과 Temporal Dead Zone이 어떻게 연관되어 있는지 설명하세요.


Hoisting과 Temporal Dead Zone(TDZ)은 JavaScript에서 변수 선언과 초기화 동작과 관련된 개념이다.

Hoisting (호이스팅)

호이스팅은 JavaScript에서 변수와 함수 선언이 해당 스코프의 최상단으로 끌어올려지는 동작을 말한다.
즉, 변수나 함수를 선언하기 전에 사용하더라도 오류가 발생하지 않는다.

하지만 변수는 실제 선언 부분까지 초기화되지 않으며,
함수도 변수와 마찬가지로 선언부만 끌어올려지고 함수의 정의는 끌어올려지지 않는다.

console.log(x); // undefined (변수 호이스팅, 선언은 되었지만 초기화되지 않음)
var x = 5;

foo(); // "Hello" (함수 호이스팅, 함수 정의가 끌어올려짐)
function foo() {
  console.log("Hello");
}

Temporal Dead Zone (TDZ) (일시적 사각 지대)

TDZ는 let, const 키워드를 사용한 변수의 선언이 해당 스코프에 도달할 때까지 변수를 참조할 수 없는 현상을 말한다.
즉, 변수가 선언되기 전까지의 구간에서 변수를 사용하면 참조 에러(ReferenceError)가 발생한다.

console.log(x); // ReferenceError: Cannot access 'x' before initialization
let x = 5;

💬 요약하면, Hoisting과 TDZ는 변수 선언과 초기화의 시점을 관리하는데 영향을 미친다.
호이스팅으로 인해 변수가 선언되기 전에 참조할 수 있지만, TDZ로 인해 let과 const 변수가 선언되기 전까지는 변수를 사용할 수 없다. 따라서 코드의 가독성과 예측 가능성을 위해 변수를 해당 스코프의 시작 부분에서 선언하고 초기화하는 것이 권장된다.



💡 Virtual DOM이 무엇이고, Virtual DOM이 어떤 면에서 좋은가요?


Virtual DOM은 리액트(React)와 같은 일부 UI 라이브러리에서 사용되는 개념으로, 가상의 DOM(Document
Object Model)을 메모리에 유지하고 실제 DOM과 비교하여 최소한의 변경사항만을 반영하는 방식을 말한다.

일반적으로 웹 애플리케이션은 사용자의 상호작용에 따라 DOM이 동적으로 변경된다.
DOM은 웹 페이지의 구조와 콘텐츠를 나타내는 객체 모델로, DOM이 변경되면 브라우저는 변경사항을 처리하고 화면을 다시 그려야 한다. 이러한 DOM 변경은 비용이 크고, 복잡한 웹 애플리케이션에서는 성능 문제를 야기할 수 있다.

Virtual DOM은 이러한 문제를 해결하기 위해 도입된 개념이다. 리액트와 같은 라이브러리는 실제 DOM 대신 가상의 DOM을 사용하여 웹 애플리케이션의 상태 변화를 추적한다. 가상 DOM은 메모리에 유지되므로, 실제 DOM과 비교하는 과정에서 렌더링 최적화를 수행할 수 있다.

Virtual DOM의 장점

  1. 성능 향상: 가상 DOM은 변경사항을 실제 DOM에 반영하기 전에 최적화된 방식으로 변화를 적용한다.
    이로 인해 불필요한 DOM 조작을 최소화하여 성능을 향상시킨다.

  2. 간결성과 유지보수성: 가상 DOM을 사용하면 개발자는 상태 변화를 추적하는 데 집중할 수 있으며,
    복잡한 DOM 조작 코드를 작성하지 않아도 된다. 이로 인해 코드의 간결성과 유지보수성이 향상된다.

  3. 크로스 플랫폼 지원: 가상 DOM은 브라우저 독립적으로 작동하므로, 리액트와 같은
    라이브러리를 사용하여 여러 플랫폼에서 일관된 사용자 경험을 제공할 수 있다.

  4. 선언적 프로그래밍: 가상 DOM 기반의 리액트와 같은 라이브러리는 선언적 프로그래밍을 지원한다.
    개발자는 원하는 결과물을 선언적으로 기술하고, 라이브러리가 상태 변화를 관리하고 적절한 DOM 업데이트를 수행한다.

💬 요약하면, Virtual DOM은 성능 향상과 간결성을 제공하여
웹 애플리케이션의 사용자 경험을 향상시키는 데 도움이 됩니다.



💡 Class Component와 Function Component의 차이점이 무엇인가요?


Class Component와 Function Component는 리액트(React)에서 컴포넌트를 작성하는 두 가지 주요 방법이다.

주요 차이점

  1. 구현 방식:
  • Class Component: Class Component는 ES6 클래스로 작성되며, React.Component 클래스를 상속받아 구현된다. 클래스 내부에서 라이프사이클 메서드를 정의하고, 상태(state)를 관리할 수 있다.
  • Function Component: Function Component는 함수로 작성되며, 함수의 인자로 props를 받아와서 컴포넌트를 구현한다. 상태(state)를 직접 관리할 수 없으며, React의 Hooks를 사용하여 상태를 처리한다.

  1. 상태(State) 관리:
  • Class Component: Class Component에서는 상태(state)를 클래스의 멤버 변수로 관리할 수 있다.
    this.state를 사용하여 상태를 선언하고, this.setState() 메서드를 통해 상태를 업데이트한다.

  • Function Component: Function Component에서는 React Hooks 중 하나인 useState를 사용하여
    상태를 관리한다. useState 훅을 사용하여 상태 변수와 해당 상태를 업데이트하는 함수를 얻을 수 있다.

  1. 라이프사이클(Lifecycle):
  • Class Component: Class Component에서는 라이프사이클 메서드를 사용하여
    컴포넌트의 마운트, 업데이트, 언마운트 등의 상태 변화를 감지하고 처리할 수 있다.

  • Function Component: Function Component는 React Hooks를 통해 라이프사이클과 관련된 로직을 작성할 수 있다. 예를 들어, useEffect 훅을 사용하여 마운트, 업데이트, 언마운트 등의 상태 변화를 처리할 수 있다.

  1. 성능:
  • 일반적으로 Function Component가 Class Component보다 좋은 성능을 제공한다. 이는 Function Component가 더 간단하고 빠르기 때문이며, 클래스의 인스턴스를 생성할 필요가 없기 때문에 메모리 사용도 더 효율적이다. 따라서, 가능하면 최신의 React 버전에서 Function Component와 Hooks를 사용하는 것이 권장된다.

💬 요약하면, Class Component는 클래스로 작성되고 상태와 라이프사이클을 관리하는 반면, Function Component는 함수로 작성되며 상태는 Hooks를 사용하여 처리한다. 최신의 React 프로젝트에서는 주로 Function Component와 Hooks를 사용하여 개발하고 있다.



💡 React Hook의 사용 규칙에 대해 설명하세요.


React Hook은 함수형 컴포넌트에서 상태(state)와 라이프사이클 기능을 사용할 수 있도록 도와주는 함수이다.

React Hook 사용 규칙

  1. 최상위에서만 Hook 호출: Hook은 반드시 함수형 컴포넌트의 최상위 레벨에서 호출되어야 한다.
    반복문, 조건문, 중첩 함수 등 내부에서 호출하면 안 된다.

  2. 컴포넌트 내에서 같은 순서로 Hook 호출: 컴포넌트의 각 렌더링마다 Hook 호출 순서는 동일해야 하다.
    즉, 조건문에 따라 Hook을 호출하면 안 된다.
    이를 위해 조건문 내에서 Hook을 호출하려면 useState의 초기값으로 함수를 사용하면 된다.

  3. 커스텀 Hook은 'use'로 시작: 커스텀 Hook 함수는 반드시 'use'로 시작해야 한다.
    이는 리액트가 커스텀 Hook을 식별하고 이를 특별한 용도로 다루기 위함이다.

  4. Hook은 함수형 컴포넌트 내에서만 호출: Hook은 함수형 컴포넌트 내에서만 호출되어야 하며,
    일반 JavaScript 함수나 클래스 컴포넌트에서는 사용되면 안 된다.

  5. useEffect에서 비동기 함수 처리: useEffect에서 비동기 함수를 호출할 경우,
    async/await을 사용하면 안 된다. 대신, 함수 내에서 비동기 처리를 해야 한다.



💡 Stack과 Queue의 차이점은 무엇인가요?


Stack(스택)과 Queue(큐)는 두 가지 다른 자료 구조로, 데이터를 저장하고 관리하는 방식에 차이가 있다.

Stack(스택)

  • 후입선출(LIFO, Last In, First Out) 방식을 따른다. 가장 마지막에 삽입된 데이터가 가장 먼저 제거된다.
  • 데이터를 스택의 맨 위에 삽입하는 연산을 "Push"라고 하며, 맨 위의 데이터를 제거하는 연산을 "Pop"이라고 한다.
  • 스택은 일반적으로 함수의 호출 스택, 뒤로 가기 기능 등에 사용된다.
  • 예시: 웹 브라우저에서 뒤로 가기 버튼을 누를 때, 이전 페이지의 URL이 스택에 쌓이고,
    다시 앞으로 가기 버튼을 누르면 스택에서 URL이 제거되며 해당 페이지로 이동한다.

Queue(큐)

  • 선입선출(FIFO, First In, First Out) 방식을 따른다. 가장 먼저 삽입된 데이터가 가장 먼저 제거된다.
  • 데이터를 큐의 뒤에 삽입하는 연산을 "Enqueue"라고 하며,
    앞에서 데이터를 제거하는 연산을 "Dequeue"라고 한다.
  • 큐는 일반적으로 작업 대기열, 메시지 큐 등에 사용된다.
  • 예시: 프린터 큐에서 인쇄 작업은 먼저 요청된 것이 먼저 처리되며,
    큐에 요청 순서대로 대기하다가 프린터가 사용 가능하면 큐의 가장 앞의 작업이 처리된다.

💬 요약하면, Stack은 후입선출(LIFO) 방식으로 동작하며, Queue는 선입선출(FIFO) 방식으로 동작한다. 두 자료 구조는 다른 용도와 동작 방식을 가지고 있으며, 각각 적절한 상황에 사용된다.



💡 Tree와 Graph의 차이점은 무엇인가요?


Tree(트리)와 Graph(그래프)는 두 가지 다른 자료 구조로, 데이터의 관계를 나타내는 방식에 차이가 있다.

Tree(트리)

  • 계층적인 구조를 가지며, 부모 노드와 자식 노드들 사이의 연결로 이루어진 비순환적인 구조이다.
  • 모든 노드들은 하나의 루트 노드로부터 시작하여 유일한 경로로 연결된다.
  • 각 노드는 하나의 부모 노드를 가질 수 있고, 여러 개의 자식 노드를 가질 수 있다.
  • 예시: 파일 시스템의 디렉토리 구조, 조직도 등이 트리 구조의 예시이다.

Graph(그래프)

  • 노드와 노드들 사이의 연결인 간선으로 이루어진 비선형적인 구조이다.
  • 간선은 방향성과 가중치를 가질 수 있으며, 순환적인 구조도 가능하다.
  • 그래프는 방향 그래프(Directed Graph)와 무방향 그래프(Undirected Graph)로 나눌 수 있다.
  • 예시: 지도에서 도시들을 노드로, 도시들 간의 도로를 간선으로 나타낼 수 있다.

💬 요약하면, Tree는 계층적이고 비순환적인 구조로 루트 노드에서 시작하여 자식 노드들로 연결된다. 그래프는 비선형적이고 순환적인 구조로 노드와 간선으로 이루어진다. Tree는 특별한 종류의 그래프로 볼 수 있다.



💡 이진 탐색 방법에 대해 설명할 수 있나요?


이진 탐색(Binary Search)은 정렬된 배열에서 특정 값을 빠르게 찾는 알고리즘이다.

배열의 중간 값과 찾고자 하는 값을 비교하여 찾고자 하는 값이 중간 값보다 크면 오른쪽 절반,
작으면 왼쪽 절반을 다시 탐색하는 방법을 반복하여 원하는 값을 찾아낸다.

이진 탐색은 선형 탐색과 비교하여 훨씬 빠른 탐색 속도를 제공한다.

이진 탐색 알고리즘의 동작 방식

  1. 배열의 중간 인덱스를 찾습니다. (low + high) / 2를 사용하여 중간 인덱스를 계산한다.
  2. 중간 인덱스의 값과 찾고자 하는 값을 비교한다.
    • 중간 값과 찾고자 하는 값이 같으면 원하는 값을 찾은 것이므로 탐색을 종료한다.
    • 중간 값이 찾고자 하는 값보다 크다면, 오른쪽 절반을 탐색 대상에서 제외하고 왼쪽 절반만 탐색한다.
    • 중간 값이 찾고자 하는 값보다 작다면, 왼쪽 절반을 탐색 대상에서 제외하고 오른쪽 절반만 탐색한다.
  3. 남은 탐색 대상이 없을 때까지 1번과 2번을 반복한다.

이진 탐색은 반복적인 방법과 재귀적인 방법으로 구현할 수 있다.

배열이 정렬되어 있어야만 이진 탐색을 사용할 수 있으며, 탐색 시간 복잡도는 O(log n)이다.
이는 배열의 크기에 비례하지 않고, 배열을 절반씩 줄여가면서 탐색하기 때문에 매우 효율적이다.

💬 요약하면, 이진 탐색은 대량의 데이터를 빠르게 탐색해야
할 때 유용하며, 자료가 정렬되어 있을 때 효과적으로 활용된다.



💡 TypeScript는 정확히 무엇이며 JavaScript와 어떻게 다른가요?


TypeScript(타입스크립트)는 Microsoft에서 개발한 오픈 소스 프로그래밍 언어로, JavaScript의 상위 집합이다.

TypeScript는 정적 타입 시스템을 도입하여 JavaScript의 기능을 확장하고 개선한 언어이다.

기본적으로 TypeScript는 JavaScript의 문법과 기능을 모두 지원하며,
추가적으로 타입 어노테이션을 사용하여 변수, 함수, 객체 등의 타입을 명시할 수 있다.

TypeScript와 JavaScript의 주요 차이점

  1. 정적 타입 체크:

    • JavaScript: JavaScript는 동적 타입 언어로, 변수의 타입을 런타임 시점에 결정한다.
      따라서 변수에 어떤 종류의 값이 저장되어 있는지를 런타임 시점에만 확인할 수 있다.
    • TypeScript: TypeScript는 정적 타입 언어로, 변수의 타입을 선언할 수 있고, 컴파일 단계에서
      타입 검사를 수행한다. 이를 통해 런타임 에러를 사전에 방지하고 코드의 안정성을 높일 수 있다.
  2. 타입 어노테이션:

    • JavaScript: JavaScript에서는 변수의 타입을 명시적으로 선언하지 않는다.
      타입이 자동으로 추론되기 때문에 일반적으로 타입 어노테이션을 작성하지 않는다.
    • TypeScript: TypeScript는 변수, 함수 매개변수, 반환값 등의 타입을 명시적으로 선언할 수 있다.
      이를 통해 코드의 가독성을 향상시키고, 타입 오류를 사전에 방지할 수 있다.
  3. 클래스와 인터페이스:

    • JavaScript: JavaScript는 프로토타입 기반의 객체지향 프로그래밍을 지원한다.
      클래스와 인터페이스를 사용하지 않고도 객체를 생성하고 상속할 수 있다.
    • TypeScript: TypeScript는 클래스와 인터페이스를 명시적으로 정의하여
      객체지향 프로그래밍을 더욱 강력하게 지원한다.
  4. 컴파일:

    • JavaScript: JavaScript는 인터프리터 언어로, 코드를 작성하고 바로 실행할 수 있다.
    • TypeScript: TypeScript는 정적 타입 체크를 위해 컴파일 단계가 필요하다.
      TypeScript 파일(.ts)을 JavaScript 파일(.js)로 변환해야만 실행할 수 있다.

💬 요약하면, TypeScript는 JavaScript의 상위 집합으로, 정적 타입 체크, 타입 어노테이션, 클래스와 인터페이스 등의 기능을 제공하여 코드의 안정성과 가독성을 향상시키는 언어이다. TypeScript는 JavaScript의 모든 기능을 지원하며, JavaScript로 작성된 코드를 TypeScript로 쉽게 이전할 수 있다.



💡 TypeScript를 사용할 때 어떤 장단점이 존재하나요?


TypeScript 사용 장점

  1. 정적 타입 체크: TypeScript는 정적 타입 언어로서, 변수와 함수의 타입을 미리 명시하고 타입 검사를 수행한다.
    이로 인해 런타임에 발생할 수 있는 타입 관련 에러를 사전에 방지할 수 있다.
    또한 코드의 안정성과 신뢰성을 향상시키는 데 도움이 됩니다.

  2. 가독성과 유지보수성: 명시적인 타입 어노테이션과 클래스, 인터페이스 등의 기능을 사용하면 코드의
    가독성이 향상된다. 또한 타입 정보를 통해 다른 개발자가 코드를 이해하고 유지보수하기 쉬워진다.

  3. IDE 지원: TypeScript는 강력한 타입 추론 기능과 IDE(Integrated Development Environment)와의
    연동으로 개발 환경을 향상시킨다. 코드 자동 완성, 타입 오류 표시 등의 기능을 통해 개발 생산성이 향상된다.

  4. 코드 예측성: TypeScript를 사용하면 개발자가 의도한 타입을 명시하므로 코드의 의도를
    더 명확하게 전달할 수 있다. 이로 인해 잘못된 타입 사용으로 인한 버그를 줄일 수 있다.

TypeScript 사용 단점

  1. 추가 작업 필요: TypeScript를 사용하면 타입 어노테이션을 추가해야 하고,
    타입 정의에 시간을 할애해야 한다. JavaScript보다 더 많은 작업이 필요할 수 있다.

  2. 런타임 오버헤드: TypeScript의 타입 체크와 타입 정보를 위해 런타임 오버헤드가 발생할 수 있다.
    이는 TypeScript 파일을 JavaScript로 컴파일하는 과정과 브라우저에서 실행하는 과정에서 추가적인 부하를 초래할 수 있다.

  3. 타입 정의 충돌: 일부 라이브러리나 외부 모듈의 타입 정의가 충돌하거나 불완전할 수 있다.
    이러한 경우에는 직접 타입 정의를 수정해야 하는 번거로움이 있을 수 있다.

💬 요약하면, TypeScript는 코드의 안정성과 가독성을 향상시키는 데 도움이 되지만, 추가 작업과 런타임 오버헤드 등의 부분에서 비용이 발생할 수 있다. 따라서 프로젝트의 특성과 개발 환경을 고려하여 TypeScript를 도입할지 여부를 결정하는 것이 중요하다.



💡 TypeScript의 인터페이스를 설명해 주세요.


TypeScript의 인터페이스(Interface)는 변수, 함수, 객체 등의 타입을 명시적으로 정의하는 역할을 한다.
인터페이스를 사용하여 코드의 가독성을 향상시키고, 타입 검사를 강화하여 코드의 안정성을 높일 수 있다.

interface MyInterface {
  prop1: number;
  prop2: string;
  prop3?: boolean;
  prop4: (param: number) => void;
}

인터페이스의 주요 특징과 사용법

  1. 속성 정의: 인터페이스 내에서 각 속성은 이름과 해당 속성의 타입을 명시적으로 지정한다.
    속성의 타입은 기본 자료형이나 사용자 정의 타입(인터페이스, 클래스 등)이 될 수 있다.

  2. 선택적 속성: prop3?: boolean와 같이 속성 이름 뒤에 ?를 붙이면 해당 속성은 선택적으로 정의된다.
    즉, 해당 속성을 포함하거나 포함하지 않을 수 있다.

  3. 함수 정의: 인터페이스는 함수 타입을 정의할 수 있다. prop4 속성은 (param: number) => void
    같이 함수의 타입을 명시하고 있다. 이는 매개변수 타입과 반환값 타입을 함께 명시하는 것을 의미한다.

  4. 객체와의 호환성: 인터페이스를 사용하여 객체의 타입을 명시할 수 있다.
    이로 인해 객체가 인터페이스를 구현하고 있는지를 검사하여 코드의 안정성을 높일 수 있다.

profile
아이디어가 넘치는 프론트엔드를 꿈꿉니다 🔥

0개의 댓글