면접후기
얼어붙은 취업시장에서 저에게 기회를 주시고, 리소스를 사용해주신 '제로원리퍼블릭'팀에게 감사인사를 전합니다.
기회를 주셨음에도 제대로 붙잡지 못했고, 부끄러운 점이 많은 면접이어서 죄송했습니다.
함께하고 싶은 개발자, 함께하고 싶은 팀원임을 보여드리고자 면접을 준비하였지만 준비했던 것에 비해 많이 부족했습니다.
여쭙고 싶은 내용이 많았는데 이미 한시간 삼십분 가량을 면접에 사용해주셔서 일부만 질문드릴 수 있었습니다.
2점인 이유는 마음에 드는 대답을 딱 두 개 하였기때문에, 실제로 더 높은 점수를 주셨음에도 2점으로 스스로 평가하였습니다.
글을 쓰게 된 이유
사실 이 글은 3시간에 걸쳐 완성되었습니다.
다만 아주 사소한 실수로 이미 완성되었던 글이 날아갔기때문에 미흡한 부분이 많을 수 있습니다.(소리를 지르고 싶습니다)
아무튼, 글을 쓰게 된 이유는 제 부끄러운 모습을 기록하고 싶기때문입니다.
이를 통해 더 나은 개발자가 될 수 있을 것이라고 믿습니다.
코드 리뷰 중 컴포넌트의 리턴 값을 False로 처리한 부분에 대하여
면접 중 대답: (당황)어.. 평소라면 null을 리턴하거나, Fragment(<></>)로 처리하였을텐데.. 잠시만요 등 제대로 대답하지 못하고, 인근의 컴포넌트를 확인했음에도 이유에 대해 명확히 전달드리지 못했습니다.
면접 이후 복귀 중 생각: 오버레이 함수의 리턴 값 이었고, False로 처리한다는 것은 명시적으로 렌더링을 생략하겠음을 의미한다고 이야기할 수 있었을 것 같습니다. 전체적인 흐름 상 컴포넌트이기때문에 Fragment로 JSX를 동일하게 리턴해주어야함이 좋을 수 있겠으나, 해당 오버레이의 역할 상 open상태가 아니면 그릴 필요가 없고, 그려질 가능 성도 없기때문에 리턴 문에서 open상태에서만 그려지는 것이 더 명시적일 것이라고 생각했을 것 같았거든요.
다만 명시적으로는 False가 아닌 Shortcut을 통한 null이 더 좋은 방식이었을 것 같습니다.
useEffect와 useLayoutEffect 등의 사이드이펙트 트리거가 있다는 점에서 조금 문제의 여지가 있을 수 있지만 후자에 좀 더 의미를 뒀을 것 같습니다.
여기서 추가로 이어지는 질문인 JS의 False, null, void, undefined 등에 대한 차이점을 물어보셨을 수 있었겠습니다.
이 부분에 대해서는 아마 당시의 저라면 뭉뚱그려서 이야기 했을 것 같습니다.
일단 TF라는 표현식(Boolean)과 null이 object라서 다르다거나, 타언어(C)의 경우 0x0번 주소를 가리키고 있는지를 확인할 것(실제로 주소가 없음)을 표현하기 위한 용도 등을 이야기하였을 것 같습니다.
undefined는 말그대로 메모리 주소는 점유되어있으나 내용물이 없는 것이고, void는 타입에 대한 부분이라고 말씀드렸을 것 같습니다.
(공부를 더 제대로 했다면 조금 더 딥하게 포인터와 실제 메모리에 대하여 말을 했을 것 같은데 아쉽습니다.)
REST API에 대해 얼마나 알고 있으세요?
면접 중 대답:이전에 사용하던 프로토콜(SOAP)의 불편함을 해결하기 위해 만들어졌으며, DATA 전송을 위한 프로토콜, 아니 인터페이스이고 특징으로는 serverless(아찔), 아니 stateless가 있습니다. 이전의 방식과는 다르게 데이터 중심적입니다. 요즘은 JSON 형태의 전달을 위해 많이 사용됩니다.
얼마나 잘못대답했는지 보이시나요? 제가 전하고 싶었던 내용은 이렇습니다.
1. Resource 전달이라는 목표
2. HTTP Method와 같은 GET, POST 등을 매칭해서 사용함
3. Stateless
4. 발전에 따라 XML -> JSON으로 형식이 변경됨에 따라 근래에는 JSON 형태로 전달
이 과정에서 중언, 부언을 많이했고, 가장 중심이 되는 포인트일지도 모를 URI 등을 생략한 것이 아쉽습니다.
이전에 기록했던 내용을 발췌해왔습니다.
SOAP(Simple Object Access Protocol)
정의 → 컴퓨터 네트워크 상에서 HTTP or HTTPS 등을 통해 XML기반 메시지를 교환하는 프로토콜
목적 → SOA를 구현하는 규약
*SOA? Service Oriented Architecture, 소프트웨어의 기능을 비즈니스적으로 의미가 있는 단위로 묶은 것
구성 → 모든 Data가 XML로 표현되며, 데이터와 데이터를 다루는 오퍼레이션이 WSDL로 정의되면 UDDI에 등록되어 누구라도 서비스를 검색하고, 접근할 수 있도록 공개한다.
- WSDL(Web Services Description Language) → 웹서비스를 정의한 언어, 서비스 인터페이스(형태: 타입-데이터타입, 메세지-메서드, 포트타입-인터페이스 정의) | 서비스 임플리멘테이션(명령: 바인딩-네트워크 프로토콜과 포트타입 매핑, 서비스-서비스정의)
- UDDI(Universal Description Discovery and Integration) → WSDL이 저장되는 저장소
한계 →
복잡한 구조: HTTP에서 전달되기 무겁다.
개발 환경 지원 필요: 웹서비스 개발 난이도가 높다. UDDI를 거쳐야한다.
REST(Representational State Transfer)
정의 → 자원의 표현에 의한 상태 전달
Resource(사진, 음악, 글자 등 모든 자료)의 이름
상태 전달 → Data를 JSON 혹은 XML로 전달
목적 → ROA를 구현하기 위한 규약
*ROA ? Resource Oriented Arhitecture, UDDI같은 중간 매개체 없이 자원을 직접 주고받는 구조
구성 →
자원: 모든 자원은 고유한 ID(URI)가 존재하고, Server에 저장됨. | 자원이 어디에있는지를 식별
행동(Verb): http Method(get, post, put, delete)
표현: Client의 Data 요청에 서버가 응답
특징 →
Client - Server 구조: 명확히 구분되어 있어 개발이 쉽다 ? 요즘은.. 점점 영역 구분이 명확해지면서도 불명확한 것 같은데…
Stateless: 상태가 없다.
한계 →
- 표준이 없다.
- 사용할 수 있는 메서드가 제한되어있다.
- 때로는 RESTful하게 만드려고 method를 사용하여 속도가 느려질 수 있다.(GET이 POST보다 빠름에도 REST를 지키기 위해 POST를 사용..근데 Method의 사용처가 우선되어야 하지 않나? Read인데 POST를 사용하고, Write인데 GET을?)
#부족한 포인트
통합리소스식별자(URI), 서버 레벨에서 프록시나 로드밸런서 등 계층 구조에 대한 내용, 캐시에 대한 내용이 추가되면 좋을 것 같습니다.
#아쉬운 포인트
이후에 제대로 XMLHTTPRequest와 AJAX, fetch, promise 등과 잘 이어서 이야기를 했다면 더 재밌는 이야기를 할 수 있었을 것 같다고 생각이들었습니다.
GraphQL을 알고 있는지? REST API와의 차이?
면접 중 대답: 사용해본 적이 없어 자세히는 알고 있지 못합니다. 응답에 대하여 사전에 정의한 형태로 받아올 수 있습니다.
예를 들어 user라는 객체안에 name이 필요한 상황 등에서 name만을 받을 수 있도록 정의되어있다면 응답 비용을 감소시킬 수 있습니다.
BF(BFF를 언급하려고 했으나, 얕게 알고 있기로는 둘이 비슷하게 응답과 요청비용을 줄이기 위함 정도로만 알고 있어 이야기하지 않음)..아니 또, server에서의 연산 자체를 줄일 수 있어 비용 감소가 될 것 같습니다(잘못된 내용)
면접관님: 그러면, URL 쿼리 파라미터 등으로 key값을 받아서 서버에서 직접 파싱하는게 비용적으로 더 덜 들지 않을까요?
차이가 없을 것 같은데 GraphQL을 쓰는 의미가 없지 않을까요?
대답: 음..(당황)제가 서버는 잘몰라서(최악의 답변) 예를들어 로그인이라는 어떤 작업에 대해서 user객체 말고 다양한 객체에 대하여 응답이 조합되어야할 때는 비용 감소가 될 것 같습니다. 그리고 서버의 비용을 클라이언트와 같이 나눠서 부담하는 형태기 때문에 비용이 덜 할 것 같습니다(잘못된 내용)
면접관님: 여전히, 질문에 중심은 REST API와의 차이에 대한 것입니다.
얼마나 잘못 대답했는지 보이시나요,
제가 전달하고자 했던 바는
1. 사전 정의를 통해 Client에서 원하는 응답을 API를 통해 바로 받아올 수 있다(설사 여러개의 엔드포인트에 대한 것이라도)
2. 이를 통해 사전 비용이 조금 소비될 수는 있지만, 응답 사이즈가 줄어들 수 있기때문에 비용이 절감될 수 있을 것이다.
정도 일 것 같습니다.
이후에 면접관님이 피드백을 주신 내용을 덧붙이자면 아래와 같습니다.
GraphQL을 사용했을때의 장점은 API 호출 수를 줄일 수 있다는 것입니다. 호출 한번에 여러개의 데이터를 받을 수 있다는 장점 덕분에요.
다르게 말하면 REST는 같은 데이터를 받기 위해 여러번의 API 호출이 있을 수 있습니다.
반면에, FE에서 여러 번 호출을 하면 되는 일을 BE에서는 중복 코드 선언, 불필요한 연산 등 엔지니어링 작업이 더 필요해질 수 있다는 단점이 있습니다.
#동료 프론트엔드 개발자를 통해 얻은 인사이트
면접 이후 통화 중에 면접관님이 듣고 싶었던 내용에 대하여 바로 정리하여 들어볼 수 있었습니다.
그리고 GraphQL에 가장 큰 장점은 A/B테스트 등에서 클라이언트 주도적으로 테스트를 진행해볼 수 있다는 것이라는 실무적인 인사이트를 다양한 예시와 근거를 통해 얻을 수 있었습니다. 요약하자면, API에 대한 엔드포인트 분리나 응답구조 구분을 서버에서 할 필요 없이, 클라이언트에서 쿼리만 다르게 조절하여 사용할 수 있기 때문입니다.
트리 쉐이킹에 대해 들어본 적이 있는지?
면접 중 대답: 음.. 들어본 적이 있는데, 정확히 기억이 나지 않습니다. 브라우저와 CSS와 관련이 있는 내용입니까?(당황)
면접관님: 아닙니다.
대답: 음 노드를 렌더링 할때, CSS 변경 사항 등의 이유로 렌더링 할 필요가 없어진 노드를 제거하는 것으로 알고 있었습니다.(잘못된 내용,
비슷한 목적인 '불필요한 것 제거'라는 점이 있지만 다름)
면접관님: 제가 말씀드린 트리 쉐이킹은 자바스크립트에 대한 것입니다.
대답: 죄송합니다. 잘 모르겠습니다.
이후 면접관님은 ES Module 등에서 Import, Export 사용에 대한 예시, Named Export와 Default의 차이, lodash의 사례 등을 설명해주셨습니다.
대단히 부끄러웠습니다. 분명 들어본 적이 있는 내용이고, 이후의 면접관님의 설명을 듣고 나서는 제가 겪었고 마주했던 문제들이라는 것을 깨달았기 때문입니다.
Firebase 버전에 의해 고통을 받았던 기억과 react-native-cameraRoll 등 일부 라이브러리에서 경험했던 문제입니다.
또, 이전에 import와 export에 대하여 조심하여 사용하기로, 불필요한 코드 호출에 대해서 공부했던 것도 떠올랐습니다.
script태그에 대해서 헤드와 바디 최상단 최하단에 선언하는 의미, Defer와 Async에 대해서 알고있는지?
면접 중 대답: 작년에 이 부분에 대해서 경험했던 내용을 토대로 기억나는대로 전달드리자면, 위치에 따라 렌더링에 영향을 미치는 것으로 알고 있습니다. 목적에 따라 로드가 먼저 되어야 하는 경우 바디 상단에 위치하거나, 렌더링이 우선인 경우 하단에 미뤄두거나 하는 것으로 알고 있습니다. 헤드도 마찬가지로 목적이 있었던 것 같은데 명확하게 기억이 나지 않습니다.
아마 실제 대답은 저것보다 훨씬 뭉뚱그려 대답했을 것입니다.
NextJS에서 제공하는 Script를 사용하면 목적에 따라서 stratgey를 다르게 사용할 수 있습니다.
기본값이 AfterIntractive인 이유는 SPA이기때문에 BODY의 내용(UI요소)와 연관된 스크립트 사용이 많기때문이고, 이러한 내용을 알지 못하는 유저이더라도 편리하게 사용할 수 있게 하기 위함이라고 정리했던 기억이 납니다.
면접관님이 알려주신 내용과 제가 정리한 내용으로 다시 한 번 정리해보자면,
1. 헤드 최상단 -> 제일 전달이 빠르다. 렌더링이 중단되고, 문서 파싱전에 로드되거나 전달되기때문에 Polyfill 등 설정이 우선되어야하는 경우 사용
2. 헤드 최하단 -> Metadata 등에 대한 Analystic Data를 외부 서드파티 솔루션(GA, Amplitude 등)으로 보낼 때 사용,
정적 동적스크립트에 따라 브라우저가 처음부터 인식하는지, 아니면 HTML 파싱과 별개로 진행되는지 등에 차이에 따라 파서차단 여부가 달라지기 때문에 동작이 달라질 수 있음.
3. 바디 최상단 -> 아래 UI 요소 들에 대한 의존 Script이거나, 빠른 JS실행이 필요한 경우
4. 바디 최하단 -> JS실행보다 렌더링이 우선되어야 하는 경우, 무거운 것을 제일 아래로 두는 느낌
Defer와 Async
면접 중 답변: 너무 오래전에 봤던거라 기억이 잘 나지 않습니다. 사용에따라 스크립트를 비동기적으로 로드할지, 아니면 나머지 작업을 멈추고 로드를 진행할지? 이런 목적 들에따라 다르게 사용하는 것으로 알고 있고, 각 브라우저 별 기본 값이 다른 것으로 알고 있습니다.
분명 더 명확히 알고 있던 내용이고, 정리했던 내용이 있음에도 기록을 찾지 못하여 아래의 이미지로 대체합니다!

#아쉬운포인트
이 문제들로 해결했던 문제들을 예시로 드는 것이 더 좋았을 것 같다는 생각을 합니다.
예를 들어 NaverMap API를 사용하며 겪었던 사례라던지 KAKAO Login 도입 과정 중에 사용했던 사례 또는 SSR 상황에서의 script 태그 사용 과 같은 내용이요!
CORS에 대하여 알고 있는지? 만약 CORS를 받으면 가장 먼저 확인할 것은?
면접 중 대답: CDN이나 Cloud가 연결되어 있는 API에 대한 CORS인지, 서버와의 API 통신 과정에서 일어난 문제인지를 확인할 것 같습니다. ..음 후자의 경우라면 화이트리스트를 제일 먼저 확인할 것 같습니다.
면접관님: 화이트리스트는 등록되어 있다고합니다. 그렇다면?
면접 중 대답:(머릿속으로 음..그럼 FE에서 API주소를 잘못, host에 오타를 냈던지 뭔가 사람의 오타로 인한 실수)음 제가 경험한 바에 의하면 두 가지 사례가 가장 많은 것 같습니다. 첫 번째는 휴먼에러에 의한 것이고(너무 축약함) 두 번째는..(CDN이나 외부리소스에 대한 접근 상황인데 이 경우는 앞서 이야기 했다고 착각) 음 네, 휴먼 에러가 제일 많은 것 같습니다.
이보다 더 대답을 못할 수가 없습니다.
면접관님이 클라이언트는 보통 열린 상태, 서버는 보통 닫힌 상태를 기본값으로 하고 있고 이에따라 외부 리소스에 대한 접근 그리고 URL에 대한 변경 등을 말씀해주셨을때서야 비로소 '아, URL 변경 되거나 하면.. 그렇겠네요!'라고 늦은 답변을 드렸습니다.
#아쉬운 포인트
너무 혼자서 생각을 하고 정리하지 않은 채 섣부르게 대답했습니다.
더 잘 대답할 수 있었을 내용입니다.
URL을 주소창에 입력하면 벌어지는 일? TCP/IP에 대하여 알고 있는지?
2연타로 굉장히 아프게 맞았습니다.
분명히 정리했던 내용이고, 알고 있던 내용이었거든요.
대답 전에 소켓을 열고, 커널을 통해 TCP/IP를 타고 내려가서 랜카드 드라이버를 거쳐 NIC을 통해 집에 연결된 ISP를 블라블라~
를 이야기 해야하나 잠깐 고민하다가 아래와 같이 대답했습니다.
면접 중 대답: 음.. 엔터를 치고, DNS를 찾습니다. 이를 통해 가장 인접한 서버로 갑니다. 이 서버를 통해 DB 또는 데이터에 접근 후 응답을 생성하고, 클라이언트로 발송합니다.
면접관님: 어.. 좀 더 자세하게 표현해주실 수 있을까요?
면접 중 대답: 음... 우선 웹서버에 도착을 하면, Redirect URI 또는 Block, Location 등의 규칙에 따라 데이터가 있는 곳으로 갑니다.
이 과정에서 WAS등의 미들웨어를 거치게 되고 이후에 DB 또는 데이터를 요청에 반환합니다.
이때 로드밸런서, 부하분산 등이 어떻게 처리되어있는가에 따라서 차이가 날 수 있습니다.
면접관님: 그럼 TCP/IP는 알고 계세요?
면접 중 대답: ..3년전에 공부했던거라(최악의답변) 기억나는대로 말씀드리면, 핸드쉐이킹을 하고 이 때 패킷헤더를 열어 플래그를 확인하거나 채우거나 하는 행위를 반복합니다.
저보다 더 잘못대답하신 분은 없을 겁니다.
위에 대한 내용은 아래의 글과 캡쳐로 대체하겠습니다!
https://helloian.tistory.com/37
브라우저에 URL을 입력하면 일어나는 일 by 널널한 개발자님 -1-
helloian.tistory.com

#아쉬운 포인트
좀 더 정리해서 전달드릴 수 있었을 것 같습니다. CDN에 대한 내용도 이야기드릴 수 있었을 것 같다는 생각이 듭니다.
마무리
저는 부끄러운 모습을 기록하는 것에 익숙합니다.
이를 통해 다음 번에 같은 실수를 반복하지 않을 수 있다고 생각하기 때문입니다.
모르는 것을 부끄러워할 줄 알고, 모르는 것을 인정하고 배울 수 있는 사람이고 싶어 기록합니다.
중간 중간 부끄럽다는 표현과, 자책의 표현 등도 이를 통해 더 강렬하게 기억하고 싶기 때문입니다.
다시 한 번 좋은 면접을 진행해주신 '제로원리퍼블릭' 팀에게 감사인사를 전합니다.
덕분에 많은 생각을 할 수 있었고, 되돌아볼 수 있었습니다.
이 글을 읽어주신 분들도 좋은 연휴가 하루가 되시기를 바래봅니다.
[출처]: defer & async timeline
'T.I.L. > Frontend' 카테고리의 다른 글
| 어쩌다 보니 360:1을 뚫은 1년차 프론트엔드 개발자의 회고 (2) | 2024.11.22 |
|---|---|
| [깨지면서 배우는 카카오톡 로그인 도입기] (3) | 2024.06.05 |
| [Refactor]작은 컨텐츠들을 위한 반복작업 (1) | 2024.02.07 |
| [Command] Shadcn-ui의 Yarn Command (0) | 2024.02.05 |
| [Refactor]아래 글과 이어지는, 단일 책임의 원칙 (4) | 2024.02.02 |


















