티스토리 뷰

"개발에 완벽한 정답은 없다. 개발은 트레이드오프와 선택의 연속이다."

수강 전의 나는 개발에 "정답이 있는데 내가 아직 그걸 모를 뿐이다"라고 생각했다.

10주가 지나서야 알았다. 모든 것은 트레이드오프의 연속이라는 것을.


1. 수강 전 — 어딘가에 '정답'이 있다고 믿었다

원래도 코드를 짤 때 고민은 많이 하는 편이었다. 기능을 받으면 "다른 방식은 없나?", "이게 실패하면 어떻게 되지?"를 먼저 생각했다. 아마 모든 개발자가 여유가 된다면 고민을 많이 할 것이다.

근데 지금 돌아보면 고민의 방식이 이상했다.

문제를 만나면 가장 먼저 이런 생각을 했다.

  • "이 상황에서 맞는 답이 뭐지?"
  • "이것도 문제가 있고 저것도 문제가 있네.. 어떻게 해야하지?"
  • "내가 뭘 놓치고 있는 거지?"

어딘가에 정답이 있을 거라고 믿었다. 내가 지금 확신이 없는 건, 내가 아직 그 정답을 모르기 때문이라고 생각했다. 블로그를 뒤지고, 책을 읽고, 컨퍼런스 발표를 보면서 "경력이 쌓이면 언젠가 이걸 다 알게 되겠지"라고 막연히 믿었다.

그래서 기술 선택을 할 때마다 찜찜했다. "내가 모르는 더 좋은 방법이 있는 건 아닐까?" 하는 불안이 항상 깔려있었다. 확신이 없으니 설득할 자신도 없었다. "책에서 이렇게 하라고 해서요"가 내 근거의 끝이었다.


2. 수강 후 — 정답이 없다는 걸 빅테크 멘토들에게 배웠다

멘토링을 받으면서 가장 충격적이었던 순간들이 있다. 내가 "정답이 뭐죠?"라는 뉘앙스로 질문하면, 멘토들이 한번도 "정답은 .."라고 답하지 않았다. 대신 이렇게 말했다.

  • "정답은 없습니다."
  • "이 상황에서는 맞을 수 있는데, 이런 상황이면 어때요?"
  • "그 선택의 비용은 뭐라고 생각해요?"

처음엔 당황스러웠다. 명확한 답을 주지 않는 게 답답하기도 했다. 근데 주차가 쌓일수록, 그게 답답한 게 아니라 그게 진실이라는 걸 받아들이게 됐다.

빅테크에서 몇 년을 굴러본 사람들이 도달한 결론은 "정답의 목록"이 아니라 "정답이 없다는 것을 받아들이는 태도"였다.

그 태도가 실무에서 어떻게 드러나는지 10주 동안 배웠다.

  • 낙관적 락과 비관적 락 중 뭐가 맞나? → 상황에 따라 다르다. 경합 빈도, 데이터 성격, 실패 비용을 따져봐야 한다.
  • Cache-Aside가 정답인가 Write-Through가 정답인가? → 트레이드오프다. 쓰기 부담, 정합성 요구, 캐시 효율을 저울질해야 한다.
  • 서킷 브레이커 failureRateThreshold는 얼마로? → 완벽한 값은 없다. 운영 환경에 적용하고, 부하 테스트를 돌리고, 지표를 보면서 계속 조정해나간다.
  • 비정규화 vs 실시간 집계? → 서비스 성격에 달렸다. 이커머스와 SNS는 답이 다르다.
  • 배치 실패 시 어떻게? → 멱등성을 설계해야 한다. DELETE+INSERT와 INSERT only의 비용이 다르다.

이 모든 질문에 공통된 답은 "그때그때 다르다"였다. 그리고 그게 무책임한 답이 아니라, "여러 요소를 저울질해서 근거 있는 선택을 한다"는 실무의 본질이라는 걸 배웠다.

달라진 건 질문의 방식이다

예전엔 문제를 만나면 "답이 뭐지?"를 물었다. 이제는 이렇게 묻는다.

  • 이 선택지들의 비용은 각각 뭔가?
  • 이 선택이 깨지는 엣지 케이스는 뭔가?
  • 내가 지금 어떤 가정 위에서 이걸 선택하고 있나?
  • 이 가정이 틀어지면 어떤 대가를 치러야 하나?

질문 자체가 바뀌니까, 고민의 끝에 남는 것도 바뀐다.

예전엔 "아마 이게 맞을 것이다"로 끝났다. 이제는 "이 트레이드오프를 감수하고 이걸 선택했다"로 끝난다. 전자는 불안을 남기고, 후자는 설명할 수 있는 선택을 남긴다.


3. 가장 인상 깊었던 프로젝트 — 5주차 "캐싱 전략"

10주차 전부 좋았지만 굳이 하나만 꼽는다면 5주차 캐싱 프로젝트다.

"캐시 = 조회 빨라지는 것" 이게 내가 알던 전부였다

실무에서 캐싱을 직접 다뤄본 적은 없었다. 대신 혼자 관심이 생겨서 책과 블로그로 공부한 적은 있었다. 그때 내가 정리한 캐싱은 이랬다.

"자주 조회되는 데이터를 메모리에 올려두면 조회 속도가 빨라진다."

딱 이 한 줄이 전부였다. Redis를 붙이고, @Cacheable을 달고, TTL을 잡으면 끝. 캐싱이 "도구"라고 생각했다. 붙이면 빨라지고, 그게 전부인.

5주차에서 마주친 "처음 보는 것들"

그런데 5주차 과제를 받고 캐싱을 제대로 다뤄보니, 내가 공부했던 건 전체 그림의 10%도 안 됐다. 한 주차 동안 처음 듣는 개념이 쏟아졌다.

Cache Stampede — "TTL이 만료되는 순간 수백 개의 요청이 동시에 DB로 몰리는 현상"이 있다는 걸 이번에 처음 알았다. 캐시가 있을 땐 초당 1,000건을 처리하던 서비스가, 캐시가 만료되는 그 순간 DB로 1,000개 쿼리가 쏟아지면서 장애로 이어질 수 있다는 것. 캐시의 존재 이유가 오히려 장애 원인이 되는 역설이었다.

TTL Jitter — "만료 시점을 랜덤하게 흩뜨린다"는 개념. 캐시 여러 개를 한번에 저장하면 TTL이 똑같이 만료돼서 한꺼번에 터진다. 그래서 ±10% 정도 랜덤값을 섞어서 만료 시점을 분산시킨다. 평범하게 동작하는 시스템 뒤에 이런 디테일이 있었구나 싶었다.

Cold Start — 서버 배포 직후 캐시가 비어있는 상태. 이 시점에 트래픽이 몰리면 1,000개 상품이 동시에 DB로부터 캐싱되고, 5분 뒤에 그 1,000개가 한꺼번에 만료된다. 내가 몰랐던 시나리오였다. 혼자 공부할 땐 "캐시가 있으면 빠르다"까지만 생각했지, "캐시가 비어있는 순간"을 상상해본 적이 없었다.

Mutex Lock + 분산 락 — Cache Stampede를 막기 위해 "하나의 요청만 DB에 가도록" 잠그는 기법. 단일 인스턴스면 ReentrantLock, 다중 인스턴스면 Redis SETNX나 Redisson RLock을 쓴다.

캐시 저장소 장애 상황 — Redis가 죽으면? 지금까지 나는 "Redis는 그냥 동작하는 것"으로 취급했었다. 그런데 실제로 운영에서는 Redis가 죽을 수 있고, 그때 서비스 전체가 같이 죽지 않도록 Fallback 전략을 미리 세워둬야 한다는 걸 배웠다.

Race Condition — 트랜잭션 내부에서 캐시를 삭제하면 A가 커밋하기 전에 B가 예전 데이터를 다시 캐싱하는 문제가 생길 수 있다. 이걸 막으려고 Spring의 @TransactionalEventListener(AFTER_COMMIT)을 써야 한다는 것. 캐시에 Race Condition이 있다니, 상상도 못 했다.

KEYS vs SCANKEYS products:*를 쓰면 Redis 싱글 스레드가 블로킹되면서 서비스 전체가 멈춘다. SCAN은 커서 방식으로 나눠서 스캔해서 블로킹이 없다. 명령어 하나 잘못 쓰면 전체 서비스가 멈출 수 있다는 걸 이번에 처음 알았다.

그래서 뭐가 그렇게 좋았냐면

"캐싱 = 조회 빨라지는 것" 한 줄로 끝났던 내 이해가 5주차 한 주만에 수십 배로 확장됐다.

혼자 공부했을 때의 캐싱은 "동작이 잘 될 때"만 상정했던 캐싱이었다. 5주차에서 배운 캐싱은 "깨질 때"를 먼저 고민하는 캐싱이었다.

  • TTL 만료 순간에 뭐가 벌어지는지
  • 캐시가 비어있을 때 뭐가 벌어지는지
  • 데이터 변경이랑 겹칠 때 뭐가 벌어지는지
  • Redis 자체가 죽었을 때 뭐가 벌어지는지

"실제 운영 환경에서 마주치는 시나리오들"이 한 과제에 전부 들어있었다. 책만 봐서는 절대 못 배우는 것들이었다. 실무에서 사고가 터져봐야 알거나, 이런 과제로 일부러 굴려봐야 알 수 있는 것들.

"캐싱 전략의 핵심은 '무엇을 캐싱할 것인가'보다 '캐시가 깨질 때 어떻게 대응할 것인가'에 있다."

5주차가 끝나고 나서야 이 문장이 진짜로 이해됐다.


4. 강의와 멘토링, 뭐가 좋았나

멘토링은 "답을 주지 않는" 시간이었다

이게 Loop:PAK의 핵심이다. 빅테크에서 실무를 하는 멘토들이 붙는데, 이분들이 절대 "이게 정답이에요"라고 말하지 않는다. 처음엔 답답했는데, 시간이 지나면서 그게 가장 값진 태도라는 걸 알게 됐다.

답을 주지 않는 대신 이런 질문을 돌려준다.

  • "왜 그 선택을 했어요?"
  • "다른 방식은 왜 안 된다고 판단했어요?"
  • "이 선택의 비용은 뭐라고 생각해요?"
  • "이 가정이 틀어지면 어떻게 될까요?"

이 질문들이 내 판단의 빈틈을 드러나게 한다. 내가 "이렇게 하는 게 맞죠?" 하고 물으러 갔다가, "아, 내가 이 관점은 생각도 안 했구나" 하고 돌아오는 일이 10주 내내 반복됐다.

"혼자서는 엄두 안 나는 것들"을 찍어낼 수 있다

각 주차 주제들이 평소에 "언젠가 해봐야지" 하면서 미뤄왔던 것들이다.

  • Spring Batch → 맨날 해봐야지 했던 것
  • 서킷 브레이커 → 실무에 도입하고 싶었지만 엄두가 안 났던 것
  • Kafka Outbox Pattern → 책만 여러 번 읽었던 것
  • Redis Lua Script → 이름도 처음 들어본 것

혼자 해도 되긴 한다. 근데 혼자 하면 "내가 제대로 하고 있는 건가"라는 불안이 계속 따라붙는다. 멘토가 옆에 있으면 그 불안 없이 밀고 나갈 수 있다. 그리고 기한이 정해진 과제라는 강제력이 "나중에 해야지" 목록을 10주 안에 찍어내게 만든다.


마무리 — 어떤 분께 추천하나

요즘은 대부분의 코드를 AI가 써준다. 그래서 "코드를 많이 쳐보는 것"은 더 이상 이 과정의 핵심이 아니다. Loop:PAK이 값진 이유는 다른 데 있다.

과제의 "고려사항"에 실제 운영에서 터지는 문제들이 녹아 있다.

Cache Stampede, Cold Start, 캐시 저장소 장애, Race Condition, KEYS 블로킹, 배치 멱등성, 서킷 브레이커 임계값… 이런 것들은 책으로 공부한다고 와닿지 않는다. 실무에서 직접 사고가 나봐야 몸에 박힌다. 그런데 현업 환경에 따라서는 그런 사고가 날 만한 규모의 트래픽이나 요구사항을 만나기 어렵다. 안정적인 레거시만 유지보수하거나, 트래픽이 작거나, 기술 스택이 고정되어 있으면 "시장에서 요구하는 다양한 기술"을 실전에서 접할 기회 자체가 없다.

그래서 이런 분들께 추천한다.

  • 실무 환경의 제약으로 시장에서 요구하는 기술을 실전에서 다뤄볼 기회가 없었던 분
  • 개인적으로는 많이 공부했는데, 운영에서 터지는 문제들을 경험해본 적이 없어서 지식이 "이론"에만 머물러 있는 분
  • 캐싱, 대기열, 배치, 분산 락, 서킷 브레이커 같은 주제를 "언젠가 해봐야지"로 미뤄온 분
  • 자기 판단에 확신과 설명력을 갖고 싶은 분

나는 개인적으로 공부를 꽤 많이 한 편이라고 생각했다. 그런데도 실제 운영에서 발생할 수 있는 문제들이 과제의 고려사항으로 들어와 있으니까, 10주 동안 "간접 실무 경험"을 한 느낌이었다. 사고가 날 만한 상황을 일부러 만들어서 굴려보게 하는 과제는 혼자서는 설계하기 어렵다.


10주 동안 기술적으로도 많이 배웠지만, 가장 크게 남은 건 세계관의 변화다.

"개발에 정답이 있다"는 착각이 깨진 자리에, "개발은 트레이드오프와 선택의 연속이다"라는 문장이 들어왔다. 이 문장을 받아들이고 나니, 기술 선택을 할 때의 불안이 사라졌다. "더 나은 답이 있는데 내가 모르는 건가"를 걱정하는 대신, "이 선택의 비용을 내가 감수할 수 있는가"를 묻게 됐다.

그리고 이 태도는 책으로는 못 배우는 것이었다. 10주 동안 그분들 옆에서 질문을 받으면서 조금씩 몸에 밴 것 같다.

그거 하나만으로도 충분히 값진 10주였다.


할인 코드

수강을 고민 중이시라면 아래 코드를 사용해주세요.

CJFZQ

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2026/05   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31
글 보관함