토스 코딩테스트 준비는 자신이 지원한 전형을 식별하는 데서 시작합니다. NEXT 행사 후기에서 본 문제 수나 시험 시간이 현재 수시 채용에도 적용된다고 생각하면 준비할 형식을 잘못 고를 수 있습니다. 먼저 회사, 직무, 행사 연도와 본인의 초대장을 나란히 놓으세요. 그런 다음 확인된 평가 방식에 맞춰 구현, 설명과 검증을 연습하는 편이 좋습니다.

과거 NEXT 자료와 현재 채용공고를 별도 폴더로 나눠 확인하는 준비 장면

이 글의 공식 사실은 2024 NEXT 안내와 현재 열리는 특정 Platform 공고에 한정합니다. 후보자 보고는 같은 2024 행사에 참여한 서버와 Node.js 지원자의 개인 기록입니다. 준비 순서와 아래 이벤트 재생 프로그램은 편집적 제안과 PracHub의 원본 연습입니다. 2026 NEXT의 동일한 시행 여부, 모든 토스 계열사의 평가 단계나 합격 기준을 확인한 것으로 읽지 마세요. 최신 초대장과 담당자의 안내가 본인에게 적용되는 기준입니다.

관련 학습을 확장하려면 PracHub의 Stripe 코딩테스트 준비 가이드처럼 구현과 검증을 함께 다루는 자료를 참고할 수 있습니다. 회사별 전형을 가져오는 대신 입력 계약, 오류 처리와 테스트 설명의 연습 방법만 비교하세요. 토스의 일정과 도구 규정은 계속 본인의 안내에서 확인해야 합니다.

NEXT의 연도와 현재 공고를 먼저 분리하기

공식 사실: 2024 NEXT 개발자 챌린지 안내는 당시 당시 경력 3년 이하 개발자를 대상으로 안내한 행사 자료입니다. 안내된 최초 평가도 직무별로 달랐습니다. 프론트엔드, Node.js, 서버 직무는 코딩테스트, Python 직무는 과제테스트를 안내했습니다. 프론트엔드와 Node.js에는 추가 사전 과제 안내도 있었습니다. 이것은 해당 행사의 구분이며, 현재 지원자의 전체 전형을 대신 설명하지 않습니다.

공식 사실: 확인한 토스 Server Developer (Platform) 공고는 최소 1년 이상의 관련 경험과 Platform 역할을 설명합니다. 공개 단계에는 서류, 두 차례 직무 인터뷰, 문화적합성 인터뷰, 레퍼런스 체크 등이 나옵니다. 별도 코딩테스트 단계가 이 목록에 없다는 이유만으로 코딩 평가가 전혀 없다고 단정할 수는 없습니다. 인터뷰 내부 평가와 지원자별 추가 안내는 초대장으로 확인해야 합니다.

편집적 제안: 아래처럼 자료를 기록하면 서로 다른 정보를 섞는 실수를 줄일 수 있습니다. 숫자가 비어 있는 칸을 추정으로 채우지 말고 확인 질문으로 남겨두세요. 같은 Server Developer라도 조직과 공고가 다르면 별도 행을 만들어 비교하는 편이 안전합니다.

  • 자료: NEXT 2024 공식 안내; 확인된 범위: 2024 행사, 당시 직무별 최초 평가와 추가 과제 구분; 이 자료로 결정할 수 없는 것: 다음 행사 개최, 현재 동일 문제 수·시간·도구 규정
  • 자료: 현재 Platform 공고; 확인된 범위: 이 공고의 역할, 자격과 공개된 단계; 이 자료로 결정할 수 없는 것: 모든 토스 계열사의 단계, 인터뷰 내부 코딩 여부
  • 자료: 2024 서버 지원자 후기; 확인된 범위: 그 지원자의 당시 경험; 이 자료로 결정할 수 없는 것: Node.js·프론트엔드·Python의 동일 경험
  • 자료: 2024 Node.js 지원자 후기; 확인된 범위: 그 Node.js 지원자가 경험한 당시 코딩 평가와 후속 과제; 이 자료로 결정할 수 없는 것: 현재 서버 수시 채용의 필수 과제
  • 자료: 본인의 초대장; 확인된 범위: 본인 평가의 시간, 접속 방법과 제출 안내; 이 자료로 결정할 수 없는 것: 다른 지원자의 조건, 다음 채용의 변경 사항

이 표에서 먼저 할 일은 문제를 찾는 것이 아니라 마지막 행을 완성하는 것입니다. 공고 제목을 저장하고, 채용 법인과 팀을 확인하고, 행사명 또는 수시 채용 여부를 적으세요. 이메일의 제목만 보지 말고 본문과 첨부 안내를 함께 읽으세요. 허용 언어, 버전이나 저장 방식이 없다면 해당 항목이 아직 미확인이라는 사실 자체가 준비 정보입니다.

과거 안내에 기재된 날짜가 지나도 페이지가 검색에 나타날 수 있습니다. 검색 결과의 최신 수집일은 행사의 개최일이 아닙니다. 두 날짜를 분리해야 오래된 행사를 현재 공고로 읽는 일을 줄일 수 있습니다. 읽은 날짜를 적는 것과 행사 연도를 적는 것을 구분하세요. 준비 노트에 둘을 함께 남기면 며칠 뒤 자료를 다시 볼 때 무엇이 역사적 사실이고 무엇이 현재 확인 사항인지 빠르게 알 수 있습니다.

후보자 후기는 형식 차이를 발견하는 데 사용하기

후보자 보고: 서버 지원자의 2024 회고는 코딩 문제와 서술형 문항을 경험했다고 적었습니다. 게시 시점은 2025년이지만 글이 다루는 응시 행사는 2024년입니다. Node.js 지원자의 2024 회고는 코딩테스트 이후 추가 과제와 인터뷰를 기록했습니다. 서로 다른 직무의 두 개인 기록이므로 두 글의 세부 형식을 하나의 공통 시험 규칙으로 합치지 않습니다.

후기를 읽을 때에는 그 사람이 실제로 경험한 것과 그 사람이 해석한 것을 분리하세요. 시험을 봤다는 기록, 사용한 언어와 후속 연락은 경험 보고입니다. 예상 합격선, 특정 풀이 개수의 가치나 다른 지원자의 결과에 대한 추측은 확인된 규정이 아닙니다. 글쓴이의 준비법이 본인에게 맞을 수도 있지만, 그 방법이 합격의 원인이었다는 인과관계까지 증명하지는 않습니다.

편집적 해석: 두 후기는 준비 범위를 나누라는 신호로 읽을 수 있습니다. 코드를 완성하는 연습과 자신의 선택을 글로 설명하는 연습은 별도로 점검할 가치가 있습니다. 그렇다고 현재 평가에 서술형이나 과제가 반드시 나온다고 예측하는 것은 아닙니다. 초대장이 코딩만 명시했다면 그 범위부터 준비하고, 추가 형식은 확인된 경우에 시간을 배분하세요.

허용 도구에 관한 과거 경험도 그대로 옮기지 마세요. 검색, 로컬 IDE, 생성형 AI, 외부 자료와 화면 공유는 서로 다른 항목입니다. 한 항목이 허용되었다고 다른 항목까지 허용되는 것은 아닙니다. 본인의 규정이 모호하다면 행사 후기의 문구를 인용해 스스로 허용 범위를 넓히기보다, 평가 담당자의 정확한 안내를 확인하는 편이 좋습니다.

초대장으로 준비할 범위를 좁히기

편집적 제안: 현재 공고와 초대장을 읽은 뒤 준비 항목을 세 묶음으로 나누세요. 첫째는 접속과 제출입니다. 평가 시작과 종료 시점, 시간대, 링크, 중단 후 재접속, 제출 완료를 확인하는 방법을 적습니다. 둘째는 실행 환경입니다. 언어 버전, 외부 패키지, 입력 형태와 파일 구조를 확인합니다. 셋째는 설명입니다. 실시간 설명, 서술 답변 또는 코드 리뷰가 안내되었는지 확인합니다.

확인이 끝나지 않은 항목이 있어도 독립적으로 준비할 수 있는 부분은 있습니다. 제한 시간 안에서 함수 하나를 완성하고, 실패 입력을 만들고, 결과를 설명하는 연습은 가능합니다. 다만 본문의 로컬 예제를 실행했다고 실제 시험 환경까지 검증한 것은 아닙니다. 지원자 계정의 연습 링크가 제공된다면 그 환경에서 별도로 실행해 보세요.

현재 Platform 공고를 목표로 한다면 공개 역할을 읽고 자신의 프로젝트에서 운영과 장애 대응의 증거를 찾을 수 있습니다. 어떤 요청이 재시도되었고, 어떤 로그로 최초 실패를 확인했으며, 데이터가 중복 처리되지 않도록 어디에서 보장했는지 설명해 보세요. 이는 공고를 읽고 적용한 준비 제안입니다. 특정 시스템 설계 문제가 출제된다는 공식 예고는 아닙니다.

원본 연습: 중복 이벤트를 한 번만 적용하기

원본 연습: 아래 프로그램은 가상 잔액과 이벤트 목록을 메모리 안에서 재생합니다. 토스 기출이나 실제 금융 시스템의 구현이 아닙니다. 목적은 요구사항이 애매할 때 질문하고, 중복과 실패의 의미를 코드에 드러내는 연습입니다. 같은 이벤트 ID가 다시 들어왔을 때 무조건 건너뛰면 되는지부터 따져보세요.

초기 잔액은 0부터 10**12 사이의 정수입니다. 이벤트는 최대 200,000개이고 각 이벤트에는 id, op, amount 세 필드만 있습니다. ID는 길이 1부터 32까지의 문자열, 연산은 ADD 또는 TAKE, 금액은 0부터 10**9 사이의 정수입니다. 불리언은 금액이나 초기 잔액으로 허용하지 않습니다. 이 범위는 예제의 편집적 계약입니다.

동일 ID에 동일 연산과 금액이 다시 오면 중복으로 세고 적용하지 않습니다. 동일 ID인데 내용이 다르면 오류입니다. 출금할 금액이 현재 잔액보다 크면 오류입니다. 유효한 이벤트만 차례대로 계산하고 결과에는 잔액, 적용 개수와 중복으로 건너뛴 개수를 넣습니다. 오류가 나면 함수는 결과를 반환하지 않으며 입력 객체를 변경하지 않습니다.

  • 순서: 시작; 이벤트: 초기 잔액 10; 처리 후 잔액: 10; 이유: 원본 입력
  • 순서: 1; 이벤트: A, ADD, 3; 처리 후 잔액: 13; 이유: 처음 본 ID
  • 순서: 2; 이벤트: B, TAKE, 4; 처리 후 잔액: 9; 이유: 현재 잔액 안에서 출금
  • 순서: 3; 이벤트: A, ADD, 3; 처리 후 잔액: 9; 이유: 같은 내용의 중복, 건너뜀
  • 순서: 결과; 이벤트: applied 2, skipped 1; 처리 후 잔액: 9; 이유: 세 입력을 모두 적용하지 않음

공식 자료의 범위와 원본 이벤트 재생 연습을 분리하고 중복 처리 결과를 보여주는 그림

코드 작성 전에 A의 세 번째 이벤트를 ADD, 4로 바꾸면 무엇을 해야 하는지 설명해 보세요. 같은 ID라는 이유만으로 무시하면 입력 충돌을 숨깁니다. 이 예제에서는 오류로 처리합니다. 다른 계약을 택할 수는 있지만 무엇을 왜 허용하는지 먼저 정해야 합니다. 구현 후 편리한 동작을 요구사항인 것처럼 설명하지 않는 것이 핵심입니다.

def replay(opening, events): if type(opening) is not int or not 0 <= opening <= 10**12: raise ValueError('opening balance') if type(events) is not list or len(events) > 200000: raise ValueError('event list') balance, seen, applied, skipped = opening, {}, 0, 0 for event in events: if set(event) != {'id', 'op', 'amount'}: raise ValueError('fields') key, op, amount = event['id'], event['op'], event['amount'] if (not isinstance(key, str) or not key or len(key) > 32 or op not in ('ADD', 'TAKE') or type(amount) is not int or not 0 <= amount <= 10**9): raise ValueError('event contract') payload = (op, amount) if key in seen: if seen[key] != payload: raise ValueError('conflicting duplicate') skipped += 1 continue if op == 'TAKE' and amount > balance: raise ValueError('insufficient balance') balance += amount if op == 'ADD' else -amount seen[key] = payload applied += 1 return {'balance': balance, 'applied': applied, 'skipped': skipped} 

seen은 이미 적용한 ID와 내용을 저장합니다. 중복 검사보다 먼저 새 이벤트를 적용하면 재시도가 두 번 반영될 수 있습니다. 이 코드에서는 필드와 값의 계약 검사, ID·내용 중복 검사, 출금 잔액 검사, 적용 순서로 처리합니다. 인터뷰에서 순서를 설명한다면 각 검사 앞뒤에 어떤 상태가 남는지 구체적으로 말해 보세요.

입력 길이를 n, 서로 다른 ID 수를 u라고 하면 일반적인 해시 테이블 비용 가정에서 처리 시간은 기대 O(n), 추가 공간은 O(u)입니다. 문자열 길이가 제한되어 있다는 조건도 포함됩니다. 반환 객체가 작다고 전체 공간이 O(1)이 되는 것은 아닙니다. 중복을 기억하는 자료구조가 공간을 사용하기 때문입니다.

결과 하나보다 반례와 검증 범위를 설명하기

로컬 실행 결과: 이 예제는 길이 0부터 5까지, ADD 0, ADD 2, TAKE 0, TAKE 2를 조합한 이벤트 열과 초기 잔액 0부터 3을 검사했습니다. 5,460개 입력에 대해 독립적인 접두 합 계산과 결과 또는 잔액 부족 오류를 비교했습니다. 별도로 충돌하는 중복 ID, 잔액 부족과 불리언 금액의 거부, 입력 객체가 바뀌지 않는지를 확인했습니다.

이 숫자는 로컬 입력 범위의 검증 기록입니다. 실제 평가의 숨은 테스트 통과율, 토스 합격 가능성이나 모든 입력에 대한 형식적 증명으로 읽지 마세요. 조합 검사에 사용한 이벤트는 고유 ID였으므로 중복 정책은 별도 사례로 확인했습니다. 검사 대상을 분리해서 설명하면 큰 테스트 개수가 다른 기능까지 검증한 것처럼 보이는 일을 피할 수 있습니다.

추가로 직접 써 볼 반례는 초기 잔액 3에서 TAKE 3, 다음 TAKE 1입니다. 첫 연산은 잔액을 0으로 만들고 다음 연산은 오류입니다. 최종 합만 보면 중간의 실패 이유를 놓칠 수 있습니다. 또 0 금액의 반복 이벤트는 금액 변화가 없어도 중복 여부가 적용 개수에 영향을 준다는 것을 보여줍니다.

이 함수의 중요한 한계도 설명하세요. 함수 호출 사이에 seen을 보관하지 않고 프로세스 종료 후에도 상태를 복구하지 않습니다. 데이터베이스 트랜잭션, 동시 요청, 네트워크 재시도와 실제 복식부기를 구현하지 않았습니다. 따라서 실제 결제에서 정확히 한 번 처리된다고 주장할 수 없습니다. 메모리 연습에서의 중복 정책과 운영 시스템의 지속적 보장은 다른 문제입니다.

설명 연습에서는 “중복을 처리했습니다” 다음에 세 문장을 붙여 보세요. 어떤 ID 범위를 기억했는지, 같은 ID의 다른 내용을 어떻게 다루는지, 오류가 나면 어디까지의 상태가 외부에 보이는지를 말합니다. 이 예제는 외부 상태를 쓰지 않기 때문에 오류 후 반환값이 없습니다. 실제 저장소를 붙인다면 부분 반영 여부를 별도로 설계해야 합니다.

확인된 형식에 맞춰 다음 연습을 고르기

편집적 제안: 코딩 평가를 준비할 때에는 위 계약을 읽고 풀이 전에 두 가지 질문을 적어 보세요. 구현 후 작은 입력으로 손 계산하고, 독립적인 기대 결과와 비교하세요. 설명 형식이 있다면 중복 정책과 실패 처리 순서를 짧은 글로 요약하세요. 과제가 안내되었다면 실행 명령과 검증 기록을 포함해 제출물의 재현성을 점검하세요.

다음 질문들은 토스에서 나온다는 예측이 아닙니다. PracHub에 있는 다른 회사·역할의 문제를 중복 처리, 상태 보존과 검증의 연습 자원으로 선택했습니다. 일부 상세 내용은 로그인이나 멤버십에 따라 제한될 수 있습니다. 제목과 표의 연습 목적을 보고 지금 점검할 기술 하나부터 골라 보세요.

후속 연습의 완료 기준은 풀이를 한 번 읽는 것이 아닙니다. 입력을 바꾸어 예상 결과를 먼저 적고, 코드를 실행한 뒤 어느 계약이 결과를 결정했는지 설명해 보세요. 중복 정책을 바꾸었다면 테스트도 바뀌어야 합니다. 예를 들어 동일 ID의 다른 금액을 허용하도록 수정하면 기존 오류 기대값이 더 이상 맞지 않습니다. 변경 전후의 동작을 구분해서 기록하세요.

준비 시간을 배분할 때에는 본인의 확인 상태를 기준으로 삼으세요. 알고리즘 풀이가 명시된 평가라면 작은 반례와 복잡도 설명을 먼저 점검합니다. 과제 형식이 명시되었다면 실행 명령, 파일 목록과 오류 동작을 확인합니다. 역할 설명만 있고 평가 형식이 아직 없으면 현재 프로젝트의 관련 경험을 정리하면서 안내를 기다릴 수 있습니다. 이 구분은 원본 예제로 만든 준비 제안이지 토스의 공식 학습 계획은 아닙니다.

처음에는 Implement idempotent request handling with idempotency keys에서 ID와 재시도의 의미를 정리해 보세요. 그 다음 이 글의 원본 함수에서 호출 간 기억이 사라진다는 한계를 설명하세요. 준비 결과에는 확인한 전형, 실행 가능한 코드와 남아 있는 질문이 함께 있어야 합니다. 그 세 가지가 명확하면 과거 후기와 현재 안내가 달라도 준비 방향을 다시 잡기 쉽습니다.

Sources and Further Reading

Originally published on PracHub.