항해99 첫 주차는 생각보다 빠르게 지나갔다.
월요일부터 본격적으로 과제를 시작했는데, 선약으로 일요일은 아무것도 못 했고, 멘토링과 Q&A 등 공식 일정도 많아 실제로 과제에 집중할 수 있는 시간은 부족하게 느껴졌다.
결국 제출 전날 새벽까지 코드를 붙잡고 있는 내 모습을 보면서, "역시 쉽지 않다"는 생각이 들었다.
하지만 힘들었던 만큼 얻은 것도 컸다.
가장 좋았던 건, 멘토링과 코치님들의 피드백이었다.
다른 분들의 질문을 들으며 내가 놓친 시각을 얻을 수 있었고, 코치님들의 설명은 단순한 이론이 아니라 실제 경험을 기반으로 한 살아있는 조언이었다. 덕분에 과제의 방향성이 명확해졌고, 개념 하나하나가 현실적인 감각으로 다가왔다.
예를 들어 TDD라는 개념도 처음엔 "테스트를 먼저 쓴다"는 정도로만 이해했지만, 막상 해보니 더 중요한 건 설계의 흐름이었다.
“이 로직은 어느 계층에 있어야 하지?”,
“이 책임은 도메인이 가져가야 할까, 서비스에서 처리해야 할까?”
테스트를 작성하다 보면 자연스럽게 객체지향 설계에 대한 고민으로 이어졌다. 그리고 그게 바로 TDD의 핵심이라는 걸 깨달을 수 있었다.
이번 과제는 DB 없이 in-memory 환경에서 동작하는 구조였고, 여러 요청이 동시에 들어올 때 Race Condition이 발생할 수 있도록 설계되어 있었다. 지금까지 실무에서는 DB 트랜잭션으로 대부분의 동시성 문제를 넘겨왔기 때문에, 직접 애플리케이션 레벨에서 동시성 문제를 해결해보는 건 처음이었다.
결과가 들쭉날쭉하고, 로그를 추적하면서 문제의 원인을 파악하고, 락을 걸어 순서를 제어하는 과정에서
ReentrantLock, synchronized, AtomicLong 등 자바의 동기화 도구들을 하나씩 찾아보고 적용했다.
그리고 이걸 공부하다 보니 자연스럽게 운영체제 수업에서만 보던 프로세스 동기화 개념들까지 연결되기 시작했다.
무엇보다 좋았던 건, 이렇게 문제를 해결하면서 지금까지 막연하게 공부해왔던 CS 개념들이 실제로 내 코드와 연결되는 걸 경험했다는 점이다.
그동안 『컴퓨터 밑바닥의 비밀』 같은 책이나 OS 강의를 보면서 “개발자라면 알아야지”라는 생각으로 억지로 공부했지만, 항상 “이걸 도대체 어디에 써먹지?”라는 생각이 들었다.
그런데 이번 주, 실제 문제를 겪고 나니 그 개념들이 정말 필요하다는 걸 처음으로 체감했다.
문제를 해결하다 보니 처음 듣는 개념들과 알고리즘들이 튀어나오기 시작했다.
Dining Philosophers Problem, Readers-Writers Problem, Producer-Consumer Problem…
처음엔 이름조차 생소했지만, 하나하나 찾아보면서 “이런 문제들이 실제 동시성 제어에서 어떤 역할을 하는가”를 이해하게 됐다.
Dining Philosophers Problem은 자원을 점유하면서 생길 수 있는 교착 상태(Deadlock) 를 설명하는 문제였고, Readers-Writers Problem은 읽기와 쓰기 작업의 동시성 제어에 대한 접근 방식을 고민하게 만들었고, Producer-Consumer Problem은 작업 순서 보장과 자원 공유의 어려움을 보여주는 사례였다.지금 내가 마주한 문제들이 이들과 완전히 같진 않지만, 동시성을 안전하게 제어하기 위한 고민이라는 본질에서 깊이 연결된다는 걸 느낄 수 있었다.
그래서 자연스럽게 구글링도 더 깊이 하게 됐다. 단순히 테스트를 통과하기 위해서가 아니라 단순히 외우는 공부와는 차원이 다른 몰입감을 느꼈고, “아, 이게 진짜 내 공부구나” 라는 생각이 처음으로 들었다.
문제 해결 시 봤던 docs 는 다음과 같다.
한 가지 아쉬운 점이 있다면,
시간 관리를 잘 하지 못해 막판에 급하게 마무리하게 된 부분이다.
다음 주부터는 과제 요구사항을 더 빠르게 파악하고, 설계 흐름부터 먼저 잡는 방식으로 시간을 써보려 한다.
그리고 궁금한 개념은 넘기지 말고, 짧게라도 정리하고 넘어가자. 멘토링이나 Q&A를 듣고 나면 “그래, 맞아” 하고 끝나는 게 아니라, “이걸 내 코드에 적용하면 어떻게 될까?” 까지 고민해보는 게 진짜 내 공부라는 걸 느꼈으니까!