최근 토스에서 진행한 Frontend Fundamentals 모의고사에 참여했습니다.
지원한 이유는 토스 구성원들이 기능을 어떻게 해석하고 구현하는지 그 관점을 직접 확인하고 싶었기 때문입니다.
과제를 직접 풀고 FE 챕터 리드분의 해설을 들으며 느낀 점은,
이 과정이 단순히 정답을 맞히는 시간이 아니라 프런트엔드 문제를 어떤 사고 틀로 바라봐야 하는지 배우는 시간에 가깝다는 것이었습니다.
그동안 코드 구조를 잡을 때 어렴풋이 느껴지던 여러 찝찝함도 이 과정에서 상당 부분 정리되었습니다.
해설 전반에서 강조된 주제는 인터페이스 설계, 역할과 책임의 범위, UI와 코드 구조의 위계였고,
이 모든 중심에는 공통된 개념이 있었습니다.
바로 추상화입니다.
그래서 본격적인 접근 방식으로 들어가기 전에, 이 개념을 먼저 짚고 넘어가고자 합니다.
추상화는 단순히 코드를 분리하는 작업이 아니라
무엇을 외부에 드러내고 무엇을 감출 것인지 먼저 결정하는 과정입니다.
FE 리드분은 이를 두고 “역할을 드러내고, 구현은 숨겨라”라고 설명했습니다.
이 지점을 더 명확하게 이해하는 데 도움이 되었던 부분이 리드분의 블로그 글이었습니다.
예를 들어 다음과 같은 함수가 있다고 할 때,
function sum(arr: number[]): number이 시그니처만 보아도 “숫자 배열을 받아 합계를 반환한다”는 역할이 충분히 드러납니다.
내부가 for-of인지 reduce인지 알 필요는 없습니다.
즉, 함수 시그니처는 역할을 드러내고 구현은 감추는 것이 핵심입니다.
이 원칙을 이해하고 나니 자연스럽게 “그렇다면 내가 해오던 분리는 무엇이었을까?”라는 질문으로 이어졌습니다.
프런트엔드를 하다 보면 흔히 하는 실수가 추출을 추상화라고 착각하는 것입니다.
저 역시 “리팩터링”이라는 이름으로 파일과 함수를 분리해 왔지만,
돌아보면 그중 상당수는 의미 없는 단순 추출에 가까웠습니다.
결과적으로 “이걸 왜 나눴지?”라는 찝찝함을 남깁니다.
정리하자면,
이 차이를 이해하고 나니 그동안 리팩터링에서 느껴지던 불편함의 원인도 자연스럽게 보였습니다.
이제 이 기반 위에서 FE 리드분이 실제로 과제를 어떻게 접근했는지도 살펴보겠습니다.
FE 리드의 접근 방식에서 가장 인상 깊었던 점은
구조를 먼저 설계하기 위해 구현 욕구를 의식적으로 제어하는 과정 자체였습니다.
문제 접근 순서는 다음과 같습니다.
그리고 리드 분의 이 말이 문제 접근 방식의 핵심을 잘 표현하고 있었습니다.
“구현된 화면부터 보면, 나도 모르게 바로 코딩하고 싶어진다.”
구조를 먼저 생각해야 한다는 사실은 모두 알고 있지만,
실제 작업에서는 화면을 보는 순간 손이 먼저 움직이기 쉽습니다.
저 역시 “일단 만들고 구조는 나중에 정리하는” 흐름이 반복되곤 했죠.
해설을 통해 중요한 점을 다시 한 번 확인했습니다.
⇒ 구현을 잠시 미루고 이상적인 구조를 먼저 그리는 집중이 필요하다는 것.
“구조 → 구현”이라는 흐름을 단순히 지키길 권장하는 원칙이 아니라 실제 개발 과정에서 의식적으로 유지해야 할 습관으로 받아들이게 되었습니다.
코드를 구조화하는 과정에서 특히 인상적이었던 것은
FE 리드분이 HTML 태그의 기본 속성을 기준으로 UI 컴포넌트를 설계하고 있었다는 점입니다.
HTML은 이미 전 세계적으로 합의된 인터페이스입니다.
태그마다 역할과 속성이 명확하게 정의되어 있고,
이를 토대로 인터페이스를 구현하면 별도의 팀 합의 없이도 일관된 구조를 유지할 수 있습니다.
이 과정을 보며 저는 다음 메시지로 받아들였습니다.
“새로운 규칙을 만드는 것보다, 이미 합의된 인터페이스를 그대로 활용하라.”
HTML 속성을 기반으로 컴포넌트를 설계하면
좋은 코드는 결국 새로운 규칙에서 나오는 것이 아니라
이미 존재하는 합의를 코드에 반영하는 데서 시작된다는 메시지를 다시 느꼈습니다.
구현을 마친 뒤 진행한 PR 리뷰에서는
예측 가능한 구조를 만들기 위한 핵심 기준들을 다시 정리할 수 있었습니다.
리뷰 중 이름이 모호한 컴포넌트 하나가 논의의 중심이 되었습니다.
예를 들어 Boundary라는 이름이 주어지면 대부분은 Error Boundary를 예상합니다.
이름만으로 역할이 떠오르지 않는다면 협업 비용은 즉시 증가합니다.
인터페이스는 이름만으로도 계약이 성립해야 한다는 점을 다시 한 번 느꼈습니다.
단순히 코드가 길어서 나누는 건 추출일 뿐입니다.
책임이 명확해졌을 때 비로소 분리해야 추상화가 됩니다.
여러 책임을 한 훅에 몰아넣으면
예측 가능성·확장성·테스트 용이성이 모두 떨어집니다.
훅은 작고 명확하게 유지하는 것이 핵심입니다.
전역 상태는 강력하지만 파급 범위가 넓습니다.
조금만 남용해도 전체 구조의 예측 가능성을 해치기 쉽습니다.
이 모든 기준은 아래 한 문장으로 수렴됩니다.
예측 가능한 코드가 좋은 코드다.
전달하고자 하는 핵심 인사이트는 세 가지였습니다.
이 세 가지는 아래의 원칙 하나로 귀결되는 것 같습니다.
⇒ “역할과 구조가 명확한 코드가 예측 가능성을 만든다.”
그리고 이 원칙이 실제 개발 과정에서도 유효한지 확인해보고 싶었습니다.
해설을 듣고 난 뒤, 그날 바로 실무 코드에 적용해 보기로 했습니다.
구현을 시작하기 전에 스스로에게 다음 질문을 던졌습니다.
이 기준을 바탕으로 다시 코드를 작성해 보니
그동안 작업하면서 느껴졌던 구조적 찝찝함이 대부분 사라지는 경험을 했습니다.
특히 예전에 “일단 분리해두자” 방식으로 만들어 놓았던 코드들이
왜 유지보수가 어려웠는지 더 명확하게 보였습니다.
구조는 그대로인데 조각만 많아져 역할이 흐려졌던 것이 원인이었습니다.
반면 지금은 작은 기능을 만들 때에도
이 자연스럽게 유지되고 있습니다.
작업 속도는 아주 살짝 느려졌지만, 이 흐름을 계속 반복하다 보면 구조를 먼저 떠올리는 방식 자체가 점점 더 자연스러워질 것이라고 생각합니다.
장기적으로는 전체 개발 속도와 구조 안정성도 더 크게 개선될 것이라는 확신이 생겼습니다.
앞으로도 설계 → 책임 정의 → 추상화 → 구현 이라는 순서를 중심에 두고 개발해 나갈 예정입니다.
이번 경험을 통해 이 흐름이 단순한 원칙이 아니라
실제 실무에서도 큰 효과를 발휘하는 접근 방식이라는 점을 몸소 느꼈습니다.
이번 모의고사 이벤트는 프런트엔드 구조를 어떻게 바라봐야 하는지 깊이 고민할 수 있었던 값진 시간이었습니다.
특정 기술이나 정답을 알려주는 형식이 아니라, 문제를 바라보는 관점 자체를 조정해주는 경험이었기에 더욱 의미 있었습니다.
무엇보다도, 이렇게 내부의 사고 과정과 설계 기준을 적극적으로 공유해 주는 시도가 국내 프론트엔드 생태계에 큰 도움이 된다고 느꼈습니다.
이런 지식 공유 활동을 꾸준히 이어가고 있는 토스 팀에게 감사한 마음입니다.