이번 기술 면접 중 기억나는 질문과 답변들 (프론트엔드)

Jim Kim
7 min readJun 15, 2017

이번에 이직하게 된 회사 기술 면접에서 주고 받았던 질문과 답변들 중 기억이 나는 몇 가지만 나열해 봤습니다. 제가 맞는 답변을 했는지 아닌지 정확히 모르는 부분도 있으니 염두에 두시고 읽어 주세요. 그리고 틀린 부분있으면 알려주시면 더욱 감사하겠습니다.

주로 어떤 프레임웍을 사용 했었나?
백본, 엥귤라, 리엑트를 사용했었다.

그 중 가장 선호하는건 어떤거냐?
현재는 리액트를 가장 선호 한다. 컴포넌트 개념이 가져다 주는 이점이 많은 것 같다.

어떤 이점들을 말하는지 설명 해줄 수 있나?
조그만 UI 컴포넌트를 만들어 재사용 하는 방법이 아주 간단하고 직관적이다.

백본과 엥귤라에서도 그런 컴포넌트를 만들 수 있지 않는가?
물론 만들 수 있다. 하지만 직관적이라는 관점에서 볼 때 백본이나 엥귤라 모두 리엑트를 따라 갈 수 없다고 생각 한다.
그나마 백본이 엥귤라에 비해 차라리 좀 더 직관적인 면이 있다. 엥귤라의 디렉티브는 신텍스도 쉽지 않고 테스트도 쉽지 않은 것 같다.

그렇다면 테스트 관점에서 다른 프레임웍들은 어떻게 생각 하는가?
테스트만 놓고 본다 하더라도 여전히 리액트가 가장 테스트하기 쉬운 것 같다. 엥귤라도 다이제스트 사이클만 아니면 테스트하기 편하다. 오히려 엥귤라가 유닛 테스트는 가장 쉬운 것 같기도 하다.

무슨 의미인가?
나에게 백본 뷰 테스트에서 가장 불편한 점은 유닛 테스트와 인테그레이션 테스트와의 경계를 구분하기가 쉽지 않다는 것이었다. 정말 유닛 테스트만 하고 싶지만 결국 jQuery를 이용한 DOM 수정이 많은 이유로 유닛 테스트만 한다는 것도 쉽지 않다. 그래서 종종 유닛 테스트와 인테그레이션 테스트가 뒤섞인 애매한 테스트 쪽으로 많이 유도 되는 것 같은 느낌이다.
그에 비해 엥귤라는 컨트롤러와 템플릿이 확실히 나뉘어져 있고 둘 사이에 연결되는 부분은 추상화 되어 있기 때문에 직접적인 DOM 수정 없이 개발이 가능 하다. 따라서 유닛 테스트가 훨씬 직관적인 것 같다.

그러면 엥귤라에 직접 DOM을 수정해야 할 때는 어떻게 수정할 수 있나?
(여기서는 질문의 의도를 정확하게 파악하지 못했다.)
아직까지 직접적으로 DOM을 수정해야 할 필요성을 발견하진 못했다. 하지만 정말 필요하면 jQuery를 의존성으로 주입해서 사용하면 되지 않을까?

하지만 jQuery를 사용하지 않고도 할 수 있지 않는가?
(…) 정확히 무슨 질문인지 잘 모르겠다.

(면접관) 엥귤라는 그런 DOM 변화 관련된 유닛들을 특별히 다루기 위해서 디렉티브를 만들었다. 디렉티브 단위에서 해당 DOM 변화를 커버해 주면 컨트롤러가 훨씬 깔끔해 진다.

맞다. 동의 한다.
(엥귤라 디렉티브는 UI 엘리먼트를 컴포넌트화 해주는건 맞지만 이것이 jQuery처럼 DOM 노드를 직접 수정하는 것과 무슨 상관이 있는지 질문을 하고 싶었지만, 자칫 더 깊은 질문으로 빠지면 그에 대답할 자신이 없어서 그냥 넘어감)

그럼 다시 테스트로 돌아가서, 백본의 경우 유닛 테스트와 인테그레이션 테스트의 경계가 모호하다 했고 엥귤라는 유닛 테스트가 편하다 했는데, 리액트는 어떻게 생각 하는가?
리액트는 둘 다 약간 섞여 있는 느낌이다. 백본의 경우 jQuery 때문에 Headless 브라우져에 직접 렌더링을 해서 테스트 하고 엥귤라의 경우 유닛 테스트만 할 수 있기에 브라우져 없이 빠르게 테스를 돌릴 수 있다(이 부분은 틀렸을 수 있다). 리액트는 이런 측면에서 유닛 테스트도 쉽게 할 수 있고 원하면 렌더링을 해서 테스트 할 수도 있다.

리액트는 왜 렌더링을 해서 테스트 하는가? 렌더링 없이 그냥 테스트 할 수 있지 않는가? 어떤 경우에 렌더링을 해서 테스트 하는가?
그렇다. 방금 말했듯이 선택이다. 반드시 렌더링을 해야 하는건 아니고 기본적으로 shallow 렌더링만으로 유닛 테스트가 가능하지만, 그리고 대게는 부모 컴포넌트의 테스트에서 자식 컴포넌트를 테스트 할 필요가 없지만, 만약 어떤 이유에서든 자식 컴포넌트까지 모두 테스트할 필요가 있는 경우 풀 렌더링을 해야 테스트가 가능해 진다.
하지만 대부분의 경우 풀 렌더링 없이 유닛 테스트와 더불어 몇 가지 경우의 수에 해당하는 DOM tree 스냅샷 테스트만으로 충분하다 생각 한다.

백본, 엥귤라, 리액트에서 렌더링 하는 방식에 차이가 있는가?
개인적 생각에 가장 큰 차이점은 엥귤라와 리액트는 자바스크립트와 HTML이 이미 바인딩되어 있고 왓쳐나 옵져버를 이용해 상태 변화에 따른 자동 리렌더링(re-rendering) 기능이 있는데 반해 백본의 경우 어떤 상태 변화에 따른 자동 리렌더링 기능이 없어서 필요할 때 마다 render() 메소드를 직접 실행 시켜야 한다는 점 인것 같다.

지난 프로젝트 들에서 state 관리는 어떤식으로 했었나?
백본에서는 네임스페이스 변수를 이용해 자체적으로 state 관리를 했고 엥귤라에서는 서비스를 이용해 자체적으로 관리 했다. 리액트는 가장 많이 사용되는 Redux를 사용했다.

리덕스를 사용하는 목적이 무엇인가? 리액트 자체적으로 이미 state를 관리할 수 있지 않는가?
물론 리액트 컴포넌트 별로 각각의 state를 외부 라이브러리 없이 관리 할 수 있는 것은 사실이다. 하지만 컴포넌트 양이 많아지고 컴포넌트 사이에서 state를 쉐어해야 할 경우가 늘어나면 해당 컴포넌트들이 공통으로 가지고 있는 부모 컴포넌트로 소위 말하는 state up lifting을 해야 한다(부모 컴포넌트에서 스테이트를 관리하고 각각의 자식 컴포넌트들에 props로 주입해줘야 다른 두 컴포넌트 사이에 똑같은 상태를 공유할 수 있다는 의미).

이 방식은 상태를 공유해야하는 컴포넌트들이 많아지면 급속도로 복잡해진다. Redux를 이용하면 state lifting 없이 각각의 컨테이너들에서 store에 바로 접근이 가능하기 때문에 코딩 및 디버깅이 훨씬 쉬워진다.

<추가 Jun 16>
이 다음 이어졌던 질문 하나가 더 기억나서 추가 합니다.

어떤식으로 복잡해 진다는 말인가?
특히 자식 컴포넌트에서 발생하는 이벤트에 의해 상태가 변경되는 경우 부모 컴포넌트에서 그 상태를 관리하므로 이벤트 핸들러를 부모 컴포넌트에서 정의하고 그 함수를 자식 컴포넌트로 props로 주입해 줘야 하는데, 자식 컴포넌트에 있어야할 비지니스 로직이 부모 컴포넌트에 있음으로 인해 이런 이벤트 핸들러가 많아질수록 정작 부모 컴포넌트와는 상관없는 함수들이 부모 컴포넌트에 너무 많이 쌓이게 되고 디버깅이 점점 힘들어 진다. (하지만 사실 이 부분은 리덕스를 사용해도 어느정도 발생하는 문제이긴 한 것 같음. 다만, 리덕스를 사용하면 그렇지 않을 경우에 비해 이런 복잡성을 많이 줄일 수 있다고 생각함)
</추가>

리덕스를 이용해 비동기 API 리퀘스트는 어떻게 했는가?
thunk 미들웨어를 사용했다. 리덕스 액션 크리에이터는 원래 함수를 반환하지 못하는데, thunk를 이용해 함수를 반환 할 수 있게 된다. 이 때 fetch등을 이용한 Promise를 반환하는 함수를 사용 할 수 있다.

비동기 함수들은 어떻게 테스트 하는가?
Jest, Jasmine, Qunit 등을 사용해 봤는데, 이들 모두 비동기 함수를 임의로 resolve 또는 reject 하는 메소드를 제공 하고 있어서, 비동기 함수를 테스트에서 실행시키고 또 resolve또는 reject 시키면서 콜백 함수를 테스트 한다.

마지막으로 클로져가 무엇인가?
클로져는 함수 안의 또 다른 함수를 이용해 하나의 독립된 스코프를 생성하는 메카니즘이다.

아무거나 간단한 예를 보여 줄 수 있나?
(화이트 보드에 적음)

코드에 대해 설명 해 줄 수 있는가?
counter 함수를 실행 함으로써 add 함수가 반환되는데 중요한 점은 counter 함수가 실행 된 후에도 반환된 내부 함수를 통해 count 변수에 접근이 가능 하다는 것이다. 즉, count 변수와 반환된 함수를 포함하는독립된 환경이 생성된 것이다.

알겠다. 하지만 그 독립된 환경이라는 것이 가져다 주는 특별한 의미가 있는가?
자바스크립트 코어에는 private 함수나 변수의 개념이 없다. 클로져를 이용해 이런 private 함수나 변수를 만들 수 있게 된다.

실제 코딩하면서 클로져를 많이 사용하는가? 주로 어떤 패턴으로 사용하는가?
자바스크립트에서 클로져를 사용하지 않고 모듈들을 만드는 건 거의 불가능 하다 생각 한다. 가장 많이 사용하는 패턴은 모듈 패턴 또는 revealing 모듈 패턴이다. 백본에서 모든 뷰나 모델들이 이 패턴을 사용하기 때문에 가장 익숙한 패턴이다.

--

--

Jim Kim

Frontend Dev / photography / hiking / coffee / Melbourne