IT/기타

[IT] 프론트엔드 관련 면접 질문 등 지식

땅일단 2024. 9. 8. 23:17

자바스크립트

- 자바스크립트의 동기/비동기

setTimeout, Ajax, Event Listener 같은 비동기 함수들은 바로 실행되지 않음.

동기적으로 실행되는 코드들부터 한줄씩 Stack에 넣고, 이런 비동기 함수들은 Queue에 대기시킴.

그리고 Stack이 비어 있다면 Queue에서 하나씩 Stack으로 보냄.

그러니까 처리가 매우 오래 걸리는 코드가 Stack으로 들어간다면 Queue에 있는 비동기 함수들이 Stack으로 들어가지 못하게 됨. (이러면 웹사이트 프리징)

 

- 실행컨텍스트, this 관련

- 클로저

- Promise 객체, async/await

 

- 이벤트 루프(Event Bubbling, Capturing Delegation)

자바스크립트는 싱글 스레드 언어. (python이나 java는 멀티 스레드 언어)

멀티로 처리해야 되는 경우는 브라우저 내부 엔진인 Web APIs에서 비동기 & 논블로킹으로 처리된다.

 

동기는 작업 순서가 지켜지는 것, 비동기는 순서가 지켜지지 않는 것이라고 보면 됨

블로킹은 다른 작업을 처리하기 위해 현재 작업을 중단하는지(병렬 처리)에 대한 여부

 

Event Bubbling : 중첩된 요소가 있을 때, 가장 안쪽 요소부터 상위로 이벤트가 전파됨

event.stopPropagation(); 으로 막을 수 있지만, 꼭 필요한 경우가 아니라면 쓰지 않는 게 권장된다.

커스텀 이벤트를 사용해 해결하는 것이 권장됨.

 

Capturing: 하위 요소로 이벤트가 전파됨. 별로 쓸 일은 없을것.

이벤트는 캡쳐링으로 상위->하위까지 갔다가 버블링으로 하위->상위로 전파됨.

캡쳐링 단계에서 이벤트를 잡아내고 싶다면 addEventListener(..., {capture: true}); 로 설정해야 함.

 

 

- 자바스크립트 원시 값

객체가 아니면서 메소드도 가지고 있지 않은 데이터. 7가지가 있음.

string, number, boolean, bigint, undefined, symbol, null

 

- 가비지 컬렉션 알고리즘

자바스크립트 엔진이 자동으로 수행함. 개발자가 수동으로 관리할 수 없음

 

어떤 객체를 참조하는 것들이 모두 사라지면 가비지 컬렉터가 그 객체를 메모리에서 삭제함

let user = {name: "doringri"}; 에서 user = null로 바꾸면 메모리에서 삭제됨

그러나 그 이전에 let admin = user; 로 바꿨다면 참조하는 객체가 존재하므로 삭제되지 않음

 

가비지 컬렉터는 맨 처음, 루트 정보(global)를 마크(기억)함

루트가 참조하고 있는 모든 객체를 마크함.

루트에서 도달 가능한 모든 객체를 방문할 때까지 반복하며, 마크되지 않은 객체는 메모리에서 삭제함.

 

- Proxy 객체

대상 객체를 감싸서 그 객체의 기본 동작을 가로채 다른 동작을 추가시킴.

// target: Proxy로 감싸질 객체
// handler: target으로 할 여러 트랩(가로챌 동작)

const target = {};
const handler = {
    get(target, prop, receiver) {
        return `${prop} : ${target[prop]}`
    }
};

const proxy = new Proxy(target, handler);
proxy.num = 5;

console.log(proxy.num);    // num : 5

위 예시 코드에서는 handler의 트랩 중 하나인 get(프로퍼티의 값 가져올 때 동작함)을 사용하였다.

이외에도 set, has, deleteProperty, apply(함수 호출 시 동작), constructor 등이 있다.

 

왜 쓰나?

말그대로 기본 동작을 가로챌 때 사용하고, 데이터 변화를 감지할 때도 사용

 

Target 객체에는 직접 접근할 수 없고 참조만 가능함.

Alpine.js에서는 내부적으로 Proxy 객체를 사용하여 반응성을 관리함.

직면했던 상황 : Alpine.js 환경에서 비동기 요청으로 어떤 객체를 가져와서 전역 변수 data에 넣음. 이 비동기 작업이 끝나기 전에 data 변수에 접근하니까 해당 객체가 Proxy 객체로 조회됨.

 

- Reflect 객체

정적 메소드만 지원하는 내장 객체. Proxy의 모든 트랩과 같은 기능을 제공함.

handler에서 어떤 동작을 실행한 후, 일반적인 get 동작을 실행시키고 싶다면 아래와 같은 코드를 사용함.

const target = {};
const handler = {
    get(target, prop, receiver) {
        console.log("트랩 실행");
        
        Reflect.get(target, prop, receiver);    // target[prop] = value; 와 같음
    }
};

 

 

 

리액트

- 가상 DOM에 대해

실제 DOM의 가벼운 복사판.(자바스크립트 객체임) 실제 DOM을 조작하는 것은 reflow, repainting을 통해 부하가 심해질 수 있기 때문에 가상 DOM을 이용한다. 상태가 변경될 때마다 리액트가 자동으로 UI를 변경시키고, 여러 최적화 기술을 통해 렌더링 성능을 향상시킴.

 

- useMemo, useCallback을 이용한 최적화, 리렌더링 조건

useMemo: 특정 상황일 때는 렌더링을 방지하고 싶다면 사용. 연산 결과를 메모리에 저장해놓고 의존성 배열의 값이 변경되면 다시 연산을 함.

 

(useEffect와의 차이점)

useEffect는 렌더링이 끝나면 실행되고, useMemo는 렌더링 중에 실행된다.

의존성 배열에 포함된 x가 처음에 0이라고 하자. useEffect는 맨 처음 렌더링되고 나서 x는 null이라고 출력한 다음 다시 렌더링 한 후 0이라고 출력될 것. (2번 렌더링됨)

그러나 useMemo는 곧바로 0을 출력함.

 

useEffect의 의존성 배열에 객체 state를 넣었다고 했을 때, 원시 값 state가 변경되면 해당 useEffect도 같이 실행된다. 리렌더링되면서 객체 state의 주소값이 변경되었기 때문.

이럴 때 useMemo 훅을 사용해 리렌더링을 방지한다. (형태는 useEffect와 같음)

const slowFunc = useMemo(() => {
	...
}, [targetNum]);

오래 걸리고, 렌더링되자마자 실행되는 함수에 쓰면 좋을듯.

 

 

 

 일반

- google.com이라는 도메인을 치면 어떤 일이 일어나는지에 대해 (What happens when you type google)

1. 구글의 IP 주소가 필요하기에 DNS 서버로 도메인을 요청하여 IP 주소를 받아옴.

2. TCP를 통해 사용자와 구글의 서버를 연결하고, IP 프로토콜을 통해 데이터 패킷이 올바른 목적지로 갈 수 있도록 함.

3. 방화벽이 패킷을 조사함.

4. HTTPS/SSL 프로토콜이 패킷을 암호화하여 사용자와 구글 서버의 보안 연결을 보장함.

5. 로드밸런서를 통해 트래픽을 여러 서버로 분산하여 과부하를 방지함.

6. 로드밸런싱이 끝나면 웹서버가 HTTP 요청을 처리함

7. API 서버를 통해 DB와 상호작용함

8. HTTP 응답이 도착하면 HTTP, CSS, JS를 렌더링함

 

 

- html/js/css가 어떻게 브라우저에 렌더링되는지, 브라우저의 작동방식

1. html을 파싱해서 DOM(Document Object Model) 트리 생성 (각 요소가 노드로 표현됨)

2. html에 연결된 CSS를 파싱해서 CSSOM(CSS Object Model) 트리 생성

3. 브라우저는 DOM과 CSSOM을 결합하여 렌더 트리 생성 (display: none;이나 <head> 태그 등은 제외됨)

4. 화면에 어떻게 배치될지 계산(reflow 단계)

5. 각 요소를 화면에 그림(painting 단계)

6. 페인팅된 여러 레이어를 합성하여 최종적인 화면 구현(Compositing 단계)

 

 

- repainting, reflow

- DOM에서 뭔가 변경되었다면 위의 렌더링을 다시 진행함(리렌더링)

 

 

- reflow, repainting을 줄이기 위한 최적화 방안

- 최대한 하위 노드에만 클래스 사용 (Repainting을 줄임)

- 인라인 스타일을 사용하면 Reflow가 많이 발생함. 지양하기.

- position을 absolute나 fixed로 하면 주변 레이아웃 영향을 받지 않아 Reflow가 줄어듦.

- 테이블로 구성된 레이아웃은 테이블 전체 노드가 Reflow 발생함

- JS를 통한 스타일 변화 자제

- CSS의 하위 선택자(ex: .wrapper .box)를 웬만하면 적게 쓰기(트리 따라가다 보면 성능 저하 문제)

언제 일어나는지는 아래 참고

 

CSS Triggers List - What Kind of Changes You Can Make

Check out our ultimate list of CSS triggers and learn which changes you can make on your website and it will affect your properties.

csstriggers.com

 

 

- display: none; 이면 어떻게 처리되는지

렌더 트리를 만들 때부터 제외되므로 reflow, painting 과정은 안 탐

 

- Date 객체의 부정확성과 Moment 라이브러리

Date 객체는 시스템의 로컬 시간대에 의존하므로 부정확할 가능성이 있음.

 

Moment.js 라이브러리는 npm install moment로 설치해 사용함.

date 문자열을 Date 객체로 변환할 때

moment().format("YYYY-MM-DD");

와 같이 간단하게 변환할 수 있음.

단점은 라이브러리 자체가 무거워서 현재는 잘 쓰이지 않고, date-fns 같은 라이브러리를 사용함.

 

 

프로젝트 관련

- 왜 그 기술, 라이브러리를 사용했는지 (Redux, Mobx)

- 프로젝트 시 힘들었던 점, 마찰이 있었을 때 해결했던 방법, 동료가 어땠으면 좋겠는지

 

 

(+) 자바스크립트로 코딩테스트를 보면 좋을 듯..