📚FOS Study
홈카테고리
홈카테고리
📚FOS Study

개발 학습 기록을 정리하는 블로그입니다.

바로가기

  • 홈
  • 카테고리

소셜

  • GitHub
  • Source Repository

© 2025 FOS Study. Built with Next.js & Tailwind CSS

목록으로 돌아가기
💼interview

Tossplace Node.js Developer

약 8분
GitHub에서 보기

Tossplace Node.js Developer

합류하게 될 팀에 대해 알려드려요

  • 토스플레이스 Node.js Developer는 SDK Platform 팀에 소속돼요.
  • SDK Platform 팀은 토스플레이스 서비스와 다양한 프랜차이즈를 유연하고 확장성 있는 구조로 연동하는 플러그인 SDK를 개발하고 고도화해요.
  • 토스플레이스 팀원들이 더 효율적으로 일할 수 있도록 필요한 업무 플랫폼을 개발하고, 이를 통해 모든 팀원에게 긍정적인 영향을 미치고 인사이트를 제공해요.
  • 최신 기술 스택을 활용해 빠르고 확장성 높은 제품을 구현하고 있으며, 성장하는 서비스의 핵심적인 역할을 하고 있어요.

합류하면 함께할 업무예요

  • 오프라인 결제 및 매장 경험을 혁신하기 위해, 토스플레이스가 만드는 토스 포스(POS)에서 실행되는 확장 프로그램 플랫폼(플러그인 SDK)을 설계하고 개발해요.
  • 토스 포스에 배달 연동 기능을 개발해 점주의 운영 효율을 극대화하고, 토스 포스 하나로 매장 운영이 가능하도록 도와요.
  • 토스플레이스 팀 전체의 생산성을 높이기 위한 업무 자동화 플랫폼을 구축해요.

이런 분과 함께하고 싶어요

  • 사용자들의 모바일 행동이 훨씬 쉬워지도록 도운 경험이 있으신 분을 찾고 있어요.
  • 외부 상황에 따라 서비스가 중단되지 않도록 데이터를 수집하고 모니터링해 보신 경험이 있으신 분을 찾고 있어요.
  • 유연하면서도 가독성이 좋은 코드, 유지보수가 가능한 코드를 작성하실 수 있는 분을 찾고 있어요.
  • 반복적인 업무 프로세스의 패러다임을 바꾸고 새로운 방식으로 전환한 경험이 있으면 좋아요.
  • 더 좋은 개발자 경험(Developer Experience)을 만드는 것에 관심이 많은 분이면 좋아요.

공식자료

  • 포스를 확장하는 가장 빠른 방법, 포스 플러그인
  • 조직의 생산성을 높이는 Process Mining
  • 토스플레이스 리더십 인터뷰 : '당연함을 재정의하는 경험'에 대한 제안

과제관련 질문 준비

HTTP 클라이언트 선택 관련

Http Client (Ky)를 선택한 이유에 대해서 알려주세요

  • ky는 fetch를 래핑한 얇은 추상화라, 브라우저/Node간 동작 차이가 적고 Web 표준에 가까운 라이브러리 입니다.
  • Node 18버전 이상부터는 fetch를 기본 제공하고, POS, 브라우저, 서버 코드 공유에 유리할 것으로 판단했습니다.
  • ky는 작지만 딱맞는 기능을 포함하고 있었는데요, 재시도, 타임아웃, 공통 헤더, JSON 처리, hook등의 기능이 포함되어 있어서 요구사항에 적절하다고 판단했습니다.

그렇다면 ky에서 타임아웃 처리는 어떻게 동작하는지 알고 계시나요?

  • fetch 자체엔 timeout 옵션은 없습니다.
  • AbortController의 signal을 fetch(url, { signal })로 넘기면, 우리가 특정 시간 뒤, controller.abort()를 호출해서 진행 중인 요청을 강제로 취소할 수 있습니다.
  • timeout 동작은 fetch 직전에, setTimeout을 설정해두고, 요청 시간이 초과되면 Proimse를 reject되게 하여 동작하도록 구현되어있습니다.

AbortController의 abort(취소)가 왜 필요할까요?

  • 클라이언트(브라우저/Node)가 더 이상 응답을 기다리지 않고
  • 가능한 경우 네트워크 스트림도 끊어서 리소스(소켓/메모리)를 회수합니다.

왜 Node에도 fetch 구현이 생겼는지 알고 계시나요?

  • Node에 fetch가 들어간 건 단순한 API 추가가 아니라, 브라우저, 서버, 엣지, 툴링 생태계를 하나의 표준 인터페이스로 묶으려는 런타임 차원의 전략적 선택이라고 생각합니다.

대용량 CSV 및 스트림 처리 관련

Csv를 readFileSync로 처리하셨는데 csv 파일이 더 커지면 어떻게 될까요?

  • fs.readFileSync는 파일 전체를 한 번에 읽어서 Node 프로세스 힙 메모리에 Buffer (또는 String) 으로 올립니다.
  • 그래서 파일이 크면 메모리 사용량과 GC 부담이 증가할 수 있습니다.
  • 처리 완료 전까지 메모리 해제가 불가능하므로, 스트림으로 처리하는 편이 바람직합니다.

Stream 처리는 어떻게 동작하는 방식이고 Node에서 내부적으로 어떻게 동작하는지 알고 계시나요?

  • 파일을 작은 chunk 단위로 읽고, 읽자마자 처리하고, 처리 끝나면 버리는 방식으로 동작할 수 있습니다
  • 메모리에는 chunkSize 수준으로 올라가고, GC 부담이 적습니다.
  • 또한 CSV는 줄 단위로 처리 가능하기 떄문에 순차 처리에 적잡하고 스트림으로 처리하기 적합합니다.
  • Node에서는 fs.createReadStream() 으로 파일 스트림을 열 수 있습니다.

스트림에서 에러 처리는 어떻게 해야하나요?

Backpressure의 개념과 동작 원리에 대해서 알고 계시나요?

  • Backpressure는 소비자가 처리하지 못할 만큼 데이터가 빠르게 들어올 떄, 생산자의 속도를 늦추는 메커니즘 입니다.
  • 위 상황에서 CSV 파일은 빠르게 읽고, DB Insert가 느리다면, 메모리에 계속 데이터가 쌓여 OOM이 발생할 수도 있습니다.
  • Node 스트림에서는 내부 버퍼를 활용하게 되는데요, 이 때 최대 버퍼 크기가 있고, 이를 설정할 수 있습니다.
  • 최대 버퍼 크기는 기본 값으로 64KB이고, 소비자가 버퍼를 빠르게 소비하지 못하고, 최대 버퍼 크기에 도달하게 되면, 파일 읽기를 일시 정지하여, 생산 소비를 제어할 수 있습니다.

Node에서 pipe와 pipeline 메소드의 차이점을 알고 계시나요?

  • 단순히 동작시키는 코드라면 pipe()도 충분하지만, 운영 환경에서 안정성을 보장해야 배치는 pipeline()이 의도를 더 잘 드러내고 실패를 안전하게 다룰 수 있다고 생각합니다.

사전과제의 배치 애플리케이션에서 장애가 생기면 어떻게 로깅/재시도/회복을 설계할 것인가요?

POS Plugin SDK가 외부 API 의존이 많을 떄 시스템 안정성을 어떻게 보장하겠습니까?

대량 트래픽/장애 대응 관점에서 서버 확장/리소스 설계 전략을 설명해주세요

이력서 질문 준비

이력서에서 가장 자신 있는 경험을 중심으로 3분 요약해보세요

  • 제가 가장 자신 있는 경험은 NHN에서 슬롯 게임 서버를 개발하면서, 개발 생산성과 안정성을 구조적으로 개선한 경험입니다.
  • 슬롯 게임은 여러 개발자가 동시에 다양한 슬롯을 구현해야하는 환경이었는데, 각자 개발할 때마다 구현 방식이 다르고 테스트 방법이 어려워 생산성과 품질 편차가 컸습니다.
  • 그래서 저는 단순히 슬롯을 개발하는 것보다, 개발 자체를 패턴화 하는게 더 중요하다고 판단했고, 공통 스핀 로직을 템플릿 메서드로 분리하고, 각 슬롯별 동작은 핸들러 형태로 확장할 수 있도록 구조를 재설계했습니다.
  • 동시에 테스트 측면에서도 추상 슬롯 테스트 기반을 만들어, 테스트 할 수 있는 기반 환경을 만들었고, 그 결과 테스트 커버리지를 약 4% 수준에서 50% 이상으로 끌어올릴 수 있었습니다.

위와 같은 구조를 설계할 떄 가장 고민했던 점은 무엇인가요?

  • 목표는 이미 존재하던 스핀 종류를 어떻게 공통화할지가 출발점이었습니다.
  • 흐름은 명확했습니다. 유저 정보 및 이전 스핀결과를 조회하고, 각 슬롯 구현체에게 스핀을 요청하고, 결과를 합치고, 로그를 쌓을 수 있도록 이벤트를 발행하는 것이 전부였습니다.
  • 흐름 자체는 유사하지만 중간중간 조건과 처리 로직이 달라 기능이 추가될수록 중복과 분기가 늘어나는 상황이었습니다.
  • 그래서 전체 흐름은 템플릿으로 고정하고, 실제로 달라지는 지점만 핸들러로 분리했습니다.
  • 그 결과 이후에 바이피처 티켓 사용이나 RTP 부양 스핀 같은 기능이 추가될 떄도 기존 스핀 흐름을 건드리지 않고 비교적 안정적으로 기능을 얹을 수 있었습니다.
  • 당시에 반복되고 있던 흐름을 한 군데로 집중시키고, 변화되는 부분만 핸들러로 분리해서 다른 개발자도 쉽게 기능을 추가할 수 있는 형태가 되었습니다.

다시 설계한다면 뭘 바꾸고 싶나요?

  • 구조가 복잡해졌던 지점은 RTP 부양 기능이 유저 정보에 의존하고 있었다는 점입니다.
  • 스핀 전략을 선택하는 것은, 스핀 파라미터로만 결정하고 있었는데, 유저 정보를 조회한 다음 전략을 결정하도록 흐름의 순서가 변경될 필요가 생겼습니다.
  • 그래서 당시에는 구조를 더 복잡하게 추상화하기보다는, 테스트를 강화해서 안정성을 확보하는 방향을 선택했습니다.
  • 지금이라면 유저 정보를 기반으로 스핀 전략을 결정하는 단계를, 스핀 실행 로직과 분리해서 하나의 '결정 단계로' 명확히 나누는 구조를 고민해볼 것 같습니다

그렇다면 그 테스트는 어떤 테스트였고, 왜 그게 충분하다고 판단했나요?

  • 먼저 기존에 있던, 일반 스핀, 바이피처 구매 스핀, 바이피처 티켓 스핀이 기존과 동일하는게 동작하는지를 검증했습니다.
  • 그 다음으로는 RTP 부양 기능이 유저 정보에 의존했기 때문에, 외부 유저 서비스를 모킹해서 핸들러 결정 로직 자체를 집중적으로 테스트했습니다.
  • 어떤 전략이 선택되는가에 초점을 맞춘 테스트였고, 흐름 순서가 바뀌는 변경에도 기존 기능이 꺠지지 않는지를 확인하는데 목적이 있었습니다.
  • 흐름을 바꾸는 결정 지점과, 외부 의존성이 개입되는 지점을 모두 커버했고, 기존 스핀 타입에 대한 회귀 테스트까지 포함했기 때문에, 구조 변경으로 인한 주요 리스크는 제어 가능하다고 판단했습니다.

그럼 장애는 실제로 없었나요? 있었다면 어떻게 대응했나요?

  • 위 핸들러 구조 자체로 인한 장애는 없었찌만, 서비스 운영 중에 네트워크 지연으로 인한 중복 스핀 요청 문제를 겪은 적이 있습니다.
  • 테스트 마케팅을 인도 지역에서 진행했는데, 서비스는 미국 리적에 구축되어 있었고, 인도에서 게이트웨이까지 요청이 도달하는 데, 예상보다 훨씬 긴 시간이 걸렸습니다.
  • 스핀 요청은 게임 도메인 특성상 반드시 원자성이 보장돼야 해서, 클라이언트에도 spinId를 두고 하나의 스핀 요청이 정확히 처리됐는지를 검증하는 구조였습니다.
  • 그런데 네트워크 지연으로 인해 클라이언트가 스핀 응답을 받지 못하고, 같은 스핀을 다시 요청하는 경우가 빈번했고, 이로 인해 중복 요청으로 인식되거나 상태 불일치로 오류가 발생하는 문제가 있었습니다.
  • 서버에서는 timeout이 발생했을 경우 스핀 결과를 조회하는 API를 제공해 클라이언트가 상태를 복구할 수 있도록 했지만, 네트워크 상황에 따라 그 조회 API마저 timeout이 발생하는 경우도 있어 완전히 깔끔하게 해결하기는 어려운 문제였습니다.

이 경험을 토스플레이스 POS / SDK 환경에 적용한다면 어떤 점을 먼저 고려할까요?

  • 토스플레이스는 현재 국내 위주로 서비스하고 있찌만, 국내 환경에서도 네트워크 지연이나 timeout은 충분히 발생할 수 있씁니다.
  • 그래서 POS나 SDK 환경에서도 요청이 한 번만 처리된다는 가정에 의존하기보다는, 중복 요청이 들어와도 안전한 구조를 기본값으로 가져가는게 중요하다고 생각합니다.
  • POS 환경에서도 결제나 거래처럼 원자성이 중요한 요청에 대해서는 클라이언트와 서버가 공유하는 식별자를 기준으로 '이미 처리된 요청인지'를 서버에서 한 번 더 검증하는 구조를 우선적으로 고려할 것 같습니다.

그럼 idempotency 키는 어디서 생성하고, 수명은 어떻게 관리할 건가요?

  • 멱등성 키는 요청을 보내는 클라이언트에서 발급하는 게 맞다고 생각합니다.
  • 멱등성 키의 역할은 요청이 성공했는지 실패했는지 알 수 없는 상황에서 '이 요청이 이전 요청과 동일한 요청인지'를 다시 확인하기 위한 식별자라고 보는데, 이 상태는 클라이언트에서 인지할 수 있기 때문입니다.
  • 서버는 전달받은 키를 기준으로 이미 처리된 요청인지 여부를 판단하고 결과를 재사용하거나 중복 처리를 막는 역할을 맡는게 올바른 설계라고 생각했습니다.
  • 멱등성 키의 수명은 네트워크 지연이나 응답 타임아웃 이후의 재시도를 고려해 약 1시간 정도의 TTL을 두는게 현실적이라고 봤습니다.
  • 실제로 요청은 서버에서 이미 처리됐지만 클라이언트가 응답을 받지 못한 경우에도, 이후 상태 조회나 재시도 시 동일한 멱등성 키로 안전하게 결과를 확인할 수 있도록 응답 캐시를 보장하는 시간이 필요하다고 판단했습니다.

그럼 멱등성 키 저장소는 어디에 두고, 동시성은 어떻게 제어할 건가요?

  • 멱등성 키 저장소는 TTL 기반으로 관리되는 휘발성 데이터이기 떄문에 Redis를 사용하는게 가장 적합하다고 생각합니다.
  • Redis에 멱등성 키를 저장하고 TTL을 설정하면 요청 결과를 일정 시간 동안만 보관할 수 있고, 개발자가 별도 정리 로직을 두지 않아도 자연스럽게 생명주기를 관리할 수 있다고 판단했습니다.
  • 동시성 측면에서는 단순히 같은 멱등성 키에 대한 중복 요청뿐만 아니라, 동일한 유저 계정에 대해 동시에 여러 원자적인 요청이 들어오는 상황도 고려했습니다.
  • 멱등성 키는 '같은 요청을 다시 처리하지 않기 위한 장치'로 사용하고, 분산 락은 '동시에 여러 요청이 들어와 상태가 꼬이는 상황'을 방지하는 보조 수단으로 역할을 분리해 가져갔습니다.

해당 경험에서 가장 어려웠던 기술적 선택은 무엇이었고, 왜 그렇게 했나요?

Node.js의 single threaded model이 성능/동시성에 어떤 영향을 주며, 어떻게 보완할 수 있을까요?

Java, Spring을 쓰며 비동기/동시성 문제를 어떻게 다뤄본적이 있나요?

팀에서 기술 도중 의견 충돌이 있었을 떄 당신의 역할은 무엇이었나요?

사용자 입장에서 불편했던 경험을 개선한 사례가 있나요?

interview 카테고리의 다른 글 보기수정 제안하기
목차
  • Tossplace Node.js Developer
  • 합류하게 될 팀에 대해 알려드려요
  • 합류하면 함께할 업무예요
  • 이런 분과 함께하고 싶어요
  • 공식자료
  • 과제관련 질문 준비
  • HTTP 클라이언트 선택 관련
  • Http Client (Ky)를 선택한 이유에 대해서 알려주세요
  • 그렇다면 ky에서 타임아웃 처리는 어떻게 동작하는지 알고 계시나요?
  • AbortController의 abort(취소)가 왜 필요할까요?
  • 왜 Node에도 fetch 구현이 생겼는지 알고 계시나요?
  • 대용량 CSV 및 스트림 처리 관련
  • Csv를 readFileSync로 처리하셨는데 csv 파일이 더 커지면 어떻게 될까요?
  • Stream 처리는 어떻게 동작하는 방식이고 Node에서 내부적으로 어떻게 동작하는지 알고 계시나요?
  • 스트림에서 에러 처리는 어떻게 해야하나요?
  • Backpressure의 개념과 동작 원리에 대해서 알고 계시나요?
  • Node에서 pipe와 pipeline 메소드의 차이점을 알고 계시나요?
  • 사전과제의 배치 애플리케이션에서 장애가 생기면 어떻게 로깅/재시도/회복을 설계할 것인가요?
  • POS Plugin SDK가 외부 API 의존이 많을 떄 시스템 안정성을 어떻게 보장하겠습니까?
  • 대량 트래픽/장애 대응 관점에서 서버 확장/리소스 설계 전략을 설명해주세요
  • 이력서 질문 준비
  • 이력서에서 가장 자신 있는 경험을 중심으로 3분 요약해보세요
  • 위와 같은 구조를 설계할 떄 가장 고민했던 점은 무엇인가요?
  • 다시 설계한다면 뭘 바꾸고 싶나요?
  • 그렇다면 그 테스트는 어떤 테스트였고, 왜 그게 충분하다고 판단했나요?
  • 그럼 장애는 실제로 없었나요? 있었다면 어떻게 대응했나요?
  • 이 경험을 토스플레이스 POS / SDK 환경에 적용한다면 어떤 점을 먼저 고려할까요?
  • 그럼 idempotency 키는 어디서 생성하고, 수명은 어떻게 관리할 건가요?
  • 그럼 멱등성 키 저장소는 어디에 두고, 동시성은 어떻게 제어할 건가요?
  • 해당 경험에서 가장 어려웠던 기술적 선택은 무엇이었고, 왜 그렇게 했나요?
  • Node.js의 single threaded model이 성능/동시성에 어떤 영향을 주며, 어떻게 보완할 수 있을까요?
  • Java, Spring을 쓰며 비동기/동시성 문제를 어떻게 다뤄본적이 있나요?
  • 팀에서 기술 도중 의견 충돌이 있었을 떄 당신의 역할은 무엇이었나요?
  • 사용자 입장에서 불편했던 경험을 개선한 사례가 있나요?