육각형 개발자

 

p.33
여러 기능이 혼재되어 있고 여러 팀이 모놀리식 시스템 코드를 동시에 수정한다.
개발 중인 코드와 운영에 반영할 코드가 혼재되면서 운영에 적용되면 안 되는 코드가 배포된 적이 있다.
고객 이벤트 기능에 이상이 생기면서 간헐적으로 전체 시스템의 응답 시간이 일정하지 않다.
모놀리식 시스템이 커지면서 배포 시간이 점점 증가한다.
당장 서비스를 운영하는 데 큰 문제는 없다. 하지만 위험 신호가 관찰되고 있다. 이러한 위험 신호를 그대로 방치하면 머지않은 미래에 큰 장애가 발생할 가능성이 높다. 이렇게 가까운 미래에 해결해야 할 문제가 생겼을 때도 필요한 구현 기술을 학습해야 한다.

장애가 발생하면 post-mortem 을 작성해야 하는 것 처럼 이상 신호가 발생되면 pre-mortem 을 작성해서 관리되어야 할 필요성이 있다.

이는 잠재적인 장애 발생 요소가 될 수 있기에 우선 순위를 높여서 처리되어야 한다. 간혹, post-mortem 만 작성하고 이후 처리가 지지부진한 경우가 있다.

서비스의 성장을 위해서 신규 서비스, 서비스 고도화 등의 개발도 중요하지만 더 중요한 것은 현재 시스템의 안정적인 운영이다. 단 한 번의 장애로 인해 고객 신뢰가 무너진다면, 신규 개발이나 고도화보다 훨씬 더 큰 손실로 이어질 수 있다.

 

p.34
무엇보다 문제를 해결하기 위한 기술을 선택할 때는 기술의 유명세에 휘둘리지 말아야 한다.
예를 들어 단지 유행하는 기술이라고 해서 분리할 서비스 간 통신을 구현하는 데 카프카를 사용하고, 쿠버네티스로 클러스터를 구축하여 서비스를 구동해서는 안 된다는 것이다. 자칫하면 서비스를 분리하고자 했던 목적과 다르게 새로운 기술만 적용한 상황이 된다. 유행하는 기술을 적용해서 복잡함은 증가했는데 문제의 본질은 해결하지 못한 것이다.

소프트웨어 엔지니어링은 회사의 재정 상태, 서비스를 이용하는 고객 수, 소프트웨어를 함께 개발하는 인력, 기반 인프라 시스템 구축 현황, 기술 숙련도 등 다각적으로 검토된 이후에 결정되어야 한다.

최근 선도되는 기술이라는 이유로 MSA, 비동기 메세지 큐, gRPC 를 무작정 도입하면 엄청난 유지보수 비용이 뒤따르게 된다.

 

p.37
예전에는 내가 사용하는 기술의 내부 동작 원리에 대해서도 미리 알아야 한다고 생각했지만 지금은 그렇지 않다. 스프링과 하이버네이트를 사용한다고 해서 내부 구현 방식까지 이해해야 실력있는 개발자라고 생각하지 않는다. 어떤 기술을 깊게 이해해야 하는 순간이 있고 이때 시간을 더 들여 깊은 지식을 학습하고 연습하면 된다.

특히 장애를 해결하는 과정 속에서 대부분 동작 원리를 깊이 이해하려고 노력했다.

 

p.47
어떤 조직에 들어가게 되면 동료와 리더는 처음부터 날 믿어주지 않는다. 오히려 오랜 시간 의심의 눈초리로 나를 볼 때도 있다. 내 경험에 따르면 동료에게 신뢰를 얻기까지 최소 3개월에서 1년 정도 걸렸다.

사람은 본능적으로 낯선 것에 대한 경계를 한다.

새로운 사람은 당연히 낯선 것이기 때문에 처음부터 신뢰를 주는 것은 어렵다.

신뢰를 쌓기 위해서는 우선 나의 마음가짐이 가장 중요하다.

새로운 곳에서 어떤 마음가짐으로 일을 하느냐에 따라서 나의 행동이 달라진다.

 

p.50
현재 동작하고 있는 서비스나 시스템에 새 기술을 도입할 때는 점진적으로 적용해야 한다. 한 번에 다 바꾸겠다는 생각은 위험하다. 특별한 이유가 없는 한 중요하지 않는 기능과 시스템에 먼저 적용해서 안정성을 검증해야 한다. 비핵심 영역에서 먼저 검증한 뒤에 핵심 영역에 적용해도 늦지 않다. 한 번에 많은 기술을 도입하거나 서비스를 급격하게 변경하면 안 된다. 크게 일은 벌여놨는데 성과를 내지 못하면 그동안 쌓은 신뢰를 한순간에 잃게 된다.

우리가 어떤 큰 목표를 이루려고 할 때에도 이와 비슷하다. 큰 목표를 달성하기 위해서는 세부 목표들을 계획하고, 하루 하루 실행해 나가야 한다.

작은 단위로 쪼개고, 달성하고, 검증하는 라이프 사이클을 가져가야 좀 더 목표에 다가설 수 있다.

 

p.58
첫 번째 메이저 버전 출시 때는 코드 줄 당 개발 비용이 10정도 들었고, 세 번째 메이저 버전 출시 때는 약 50 정도의 개발 비용이 들었다.

아무리 체계가 잘 잡혀 있는 프로젝트라 할지라도 서비스의 규모가 커지고, 투입되는 인력들이 많아질수록 서비스 유지보수 비용은 점점 늘어날 수밖에 없다.

코드의 복잡도는 점점 높아지고, 기술 부채 또한 축적된다.

조직 규모가 커지면서 커뮤니케이션 비용도 상승하게 된다.

초기에 아키텍처 설계, 기술 부채 관리, 소프트웨어 품질 관리를 위해 투자해야 하는 이유이다. 하지만 현실은 기업의 생존이 우선이기에 유지보수 비용을 절감하기 위한 투자 비용에 신경 쓰지 못한다.

 

p.68
위험을 피하려 문제가 있던 코드를 건들지 않는 대가는 유지보수 비용을 배 이상 높이는 결과로 돌아왔다. 약간의 위험을 감수하더라도 if-else 블록을 만들지 말고 코드를 정리해야 했는데 그러지 못했고 두고두고 유지보수하는 데 큰 부담으로 작용했다. 잘 돌아가는 코드라 해도 세상에 맞춰 변화할 수 있도록 더 나은 코드, 더 나은 구조로 변경할 수 있는 용기가 우리에게 필요하다.

코드는 사람이 만들고, 사람은 가시밭길을 피해가려고 하는 경향이 많다.

소프트웨어 품질을 높이기 위해 사람에게 의존하기 보다는 견고한 아키텍처, 정적 분석, 테스트 자동화, 코드 리뷰 등으로 이를 보완해 나가야 한다.

 

p.75
문제 발생 시점이나 동시성 문제 원인을 찾을 때 시퀀스 다이어그램을 주로 사용한다.

동시성 문제는 대부분 상용 배포 전에 잘 찾지 못하고, 서비스를 운영하는 상황에서 종종 발생한다.

동시성 문제에 대해서 어떻게 하면 잘 발견 할 수 있을까를 고민해 왔었는데, 시퀀스 다이어그램을 볼 때 마다 동시성 이슈를 생각하면 되겠구나.

시퀀스 다이어그램을 보면 트리거처럼 떠올리자. (동시성 문제가 없는지 검토해 보기)

 

p.112
왜 응집도를 높여야 할까?
응집도는 결국 수정 비용과 관련이 있다. 응집도가 높으면 관련 코드가 한곳에 모여 있게 되고 관련되지 않은 코드는 포함하지 않는다.
역할에 따라 클래스가 분리되면서 자연스럽게 클래스 길이가 줄고, 메서드 단위로 작성되기 때문에 가독성이 좋아진다. 따라서 코드 분석 시간을 줄여준다.

 

p.124
결합도를 낮추기 위해 추상화 타입을 중간에 위치시키거나 이벤트를 사용하면 두 코드를 직접 연결하지 않고 간접적으로 연결하게 된다. 두 코드가 간접적으로 연결되어 있기 때문에 연결된 코드에 비해 코드를 분석하는 데 더 많은 노력이 들어간다.

추상화 타입, 이벤트 사용이 코드 분석을 어렵게 만들 수 있지만 소프트웨어 유지보수 측면에서 이점을 주기도 한다. 서로간의 결합도를 낮춰서 변경의 영향을 최소화 할 수 있고, 확장성과 유연성을 제공한다.

 

p.133
레거시는 폄하 대상이 아니다.
가끔 레거시 코드를 무시하는 개발자를 만날 때가 있다. 회사 코드가 최악이라거나 다시 만들면 그거보다 더 잘 만들 수 있다는 식으로 말이다.
복잡하고 수정하기 힘든 레거시를 코드를 만나면 당연히 투덜댈 수 있다. 하지만 레거시는 폄하 대상이 아니다. 레거시가 있었기에 서비스가 굴러가고 수익이 난 것이다. 그리고 모든 코드에는 나름의 사정이 있다. 그러니 레거시를 만나면 다음처럼 생각해보자.
"개선할 거리가 있다. 해보자!"

내가 딱 주니어/중니어 시절 이런 불평불만을 했었다.

나의 불평불만은 레거시 코드를 무조건 새로 만들어야 한다는 원칙으로까지 이어졌다.

어느 순간 나는 지쳐버렸다.

레거시는 영원히 사라지지 않는다는 것을 깨달았기 때문이다.

불평하고, 바꾸려고 하기 보다는 현재의 코드에서 개선할 수 있는 방법에 대해 고민을 하니 다양한 개선 방향들을 수립 할 수 있었다. (레거시 코드 일부 수정, 레거시 분리하여 신규 서버 구축 등)

 

p.164
개인적인 경험으로 볼 때 테스트 커버리지는 70~80% 수준이면 적당하다. 테스트 커버리지가 높을수록 좋지만 90% 이상을 목표로 하면 만들지 않아도 될 테스트 코드를 작성하는 일이 벌어지기 때문이다. 테스트 커버리지를 높이기 위해 가치 없는 코드를 만드느라 시간 낭비하지 말자.

 

p.169
개인적으로 TDD를 선호하는 또 다른 이유는 TDD가 기능을 설계하는 데 도움을 주기 때문이다. 테스트를 먼저 만들려면 테스트할 대상의 기능을 실행할 수 있어야 한다.
클래스 이름, 메서드 이름, 메서드 파라미터 타입, 리턴 타입, 익셉션 타입, 의존 대상/역할

 

p.176
모든 코드를 TDD로 진행할 필요는 없다고 생각한다. 개발을 먼저 하고 테스트 코드를 작성해도 괜찮다. 테스트를 먼저 말들던, 나중에 말들던 중요한 것은 테스트 가능성을 높이는 데 있다.
코드를 만들 때 테스트 가능성을 염두에 두면 개발 생산성과 설계 품질을 높일 수 있다.

 

p.189
개발 경력이 많지 않은 개발자는 기능 구현에 몰두하느라 보안과 관련된 품질 속성의 중요성을 인지하지 못할 때도 많다.
결제를 진행하는 과정에서 금액을 재확인하는 절차가 없어서 0원으로 결제된 부정 거래 건
요청 파라미터를 변조해서 남의 정보에 접근할 수 있는 개인 정보 유출 건

보안 관련된 부분들 또한 시퀀스 다이어그램에 포함시키는 습관을 가지면 좋을 듯 하다.

데이터 흐름, 데이터 검증 이 두 가지가 적절하게 시퀀스 다이어그램에 표현된다면 동시성 이슈와 보완 측면에 대해서 검토해 볼 수 있겠다.

 

p.198
규모가 작으면 한 번에 새로 만드는 것도 괜찮지만 보다 현실적인 방법은 점진적으로 구조를 변경하는 것이다. 대표적으로 일부 기능을 서비스로 분리하는 방식을 들 수 있다.

뭐든 한 번에 몰아서 하는 방식 보다는 단계적으로 진행하는 방식이 더 좋다.

한 번에 하게 되었을 때 실패하게 되면 거기서 끝이지만 점진적인 방식으로 했을 때 발생되는 실패는 반면교사로써 활용되어지고, 감당 가능한 리스크일 가능성이 높기 때문이다.

한 번에 했는데 망하면 끝이다.

 

p.201
개발자는 우발적 복잡성에 빠지지 않도록 경계해야 한다. 물론 흥미로운 기술을 만나면 사용해 보고 싶고, 유명한 회사에서 썼다는 기술도 써 보고 싶기 마련이다. 심할 때는 어떤 기술을 쓰지 못하게 막는 상사한테 화가 날 때도 있다. 하지만 그럴수록 우발적 복잡성의 유혹에 빠지지는 않았는지 곱씹어보자. 당장 마주한 문제 또는 곧 닥칠 문제를 해결하기 위해 어쩔 수 없이 복잡성이 동반되어야 한다면 지속해서 설득하는 시간을 가져야 한다.
같은 문제를 해결하려 한다면 복잡한 구조보다 단순한 구조가 더 좋다는 사실을 항상 명심하자.

Simple is best.

 

p.210
일의 규모가 커지면 복잡한 상황이 자주 발생하고 상상하지 못했던 요구가 발견되면서 예상보다 개발 시간이 더 오래 걸릴 때가 많다. 그래서 추정할 때는 자신 있다고 너무 빡빡한 추정치를 사용하기보다는 약간의 여유 시간을 포함해서 추정해야 한다. 그래야 추가로 발생할 업무나 변경에 따른 재작업 시간을 확보할 수 있다.

 

p.216
비개발자는 본인이 이해하는 수준에서 요구 사항을 말한다. 이런 요구 사항은 현재 시스템의 한계로 구현이 어려울 수 있다. 또는 반대로 요구 사항이 논리적으로 이해 안 될 때도 있다. 이럴 때 개발자는 그저 해달라는 대로 해주면 안 된다.
왜 그런 요구를 했는지 이유를 들어봐야 한다. 특정 기능을 요구한 이유를 듣다 보면 더 나은 방식이나 다른 대안이 떠오르기도 한다.

이러한 커뮤니케이션 스킬 또한 육각형 개발자가 되어야 하는 이유이다.

소통 능력이 부족하면 협업 능력이 떨어지기 때문이다.

 

p.227
코드 중복이 세 번 이상 발생하면 중복을 제거하라는 말이 있는데 일반 작업에도 이 원칙은 적용된다. 주기적으로 반복해서 해야 하는 수작업이 있다면 자동화해야 한다. 운영자가 사용하는 서비스에 관련 기능을 추가하거나 별도 프로그램을 만들어서 개발자 개입 없이 필요한 사람이 직접 처리할 수 있도록 해야 한다.
우리가 하는 일은 결국 사람이 수작업으로 할 일을 시스템화하는 것이다. 이런 일을 하는 우리가 정작 반복되는 수작업을 자동화하지 않는다면 스스로 생산성을 낮추는 행위를 하는 것이다. 반복해서 발생하는 수작업이 있다면 자동화 기능을 만들어서 업무 생산성을 높이자.

 

p.228
데이터 이전 기능 만들기
이 업무를 잠깐 내가 맡아야 할 때가 있었다. 처리 과정을 지켜본 뒤에 시간을 내서 관리툴에 콘텐츠 이관 기능을 추가했다. 개발하는 데 하루 정도 시간을 썼다. 수동으로 하면 20분이면 끝날 업무이기에 굳이 추가 기능을 만들 필요가 있냐는 반응도 있었다.
하지만 여기에는 숨겨진 시간이 많다. 콘텐츠 제작 조직에서 데이터베이스 담당자에게 무언가를 요청하는 시간, 담당자가 실제로 작업을 시작하기까지의 시간, 담당자가 중간에 다른 일이 생겼을 때 그만큼 지연되는 시간, 담당자가 다 됐다고 메일을 작성하는 시간, 요청자가 다 됐다는 메일을 확인하기까지의 시간이 누락되어 있는 것이다. 이런 시간이 몇 차례만 누적되면 금방 개발 시간을 초과한다.
당장은 수작업이 편하고 빨리 긑낼 방법처럼 여겨지지만, 중장기적으로 봤을 때 낭비되는 시간이 계속 누적된다. 따라서 반복되는 수작업이 있다면 기능으로 개발해보자.

작업 자체보다 숨겨진 요청/대기/확인 과정이 더 큰 비용을 만든다.

 

p.236
한 번에 완벽한 목차를 구성할 수는 없다. 목차와 내용 흐름을 검토하고 정련하는 과정을 몇 차례 반복해야 한다. 목차와 내용 흐름 초안이 나오면 그때부터 글을 쓰기 시작하자.

 

p.243
시간을 내서 글쓰기 연습하기
출퇴근 이동 시간 : 글의 주제나 내용 흐름 등을 정리한다.
저녁 : 자기 전에 20분~1시간 정도 시간을 내서 글을 쓴다. 이 책도 주로 저녁 시간에 집필했다.
점심시간 : 점심을 먹고 나서 남는 시간을 활용해서 글을 쓴다.
1주일에 한두 번이라도 글 쓰는 시간을 가져보자. 일단 쓰는 게 중요하다. 자꾸 써야 실력이 는다.
일기 : 그날 있었던 일 중에서 기억나는 일을 기록한다.

출퇴근 이동 시간에 글의 주제나 목차 등을 정리하는 건 아주 좋은 방식인 것 같다.

회사 일이 바뻐서 글 쓸 시간이 없었는데 출퇴근 이동 시간에 어떤 글을 쓰면 좋을지를 생각해 보는 시간을 가지고, 주제가 정해졌을 때 목차를 생각해 볼 수 있는 시간적 여유를 충분히 가질 수 있는 공간은 지하철이 딱 좋은 느낌이다.

저자와 같이 점심시간 또는 자기 전에 글을 쓰는 연습을 해봐야 겠다. 자기 전에 글쓰기는 해보지 않아서 잘 될지는 모르겠지만 습관으로 잡히면 글을 꾸준히 작성 할 수 있을 것 같은 확신이 든다.

 

p.261
자율성
일을 맡겨 놓고 작은 것까지 하나하나 지시하는 마이크로 매니저는 직원의 자율성을 뺏는다. 자율성이 없는 직원은 주도성을 잃는다. 어차피 상급자가 시키는 대로 해야 하기 때문이다. 괜히 내 생각대로 했다가 욕을 먹느니 수동적으로 시킨 일만 하는 게 낫다고 생각하게 된다.
직원에게 동기 부여를 해주고 주도적으로 참여하도록 유도하고 싶다면 자율성을 최대한 보장해줘야 한다. 간섭할수록 주도성은 떨어진다. 일단 맡겼다면 간섭을 최소화하고 기다리자.
자율성 보장이 모든 것을 마음대로 하게 두는 것을 의미하는 게 아니다. 자율성에도 어느 정도의 통제가 필요하다. 여기서 말하는 통제는 하나하나 작은 것까지 지시하는 관리가 아니다. 진척 상황을 확인하고 위험 요소를 검토한 다음 샛길로 빠지지 않게 막아주는 역할을 의미한다. 자유에 책임이 따르는 것처럼 자율성 보장에도 관리가 필요하다.

마이크로매니징은 생산성 저하를 야기한다.

 

적용할 점

  • 장애 발생 후 post-mortem 회고, 이상 신호 발생하면 pre-mortem 회고
  • 유행하는 기술 무작정 적용하지 않기
  • 새로운 직장에서 신뢰를 쌓기 전에 가장 중요한 건 나의 '마음가짐'
  • 한 번에 몰아서 하는 방식보다는 단계적으로 진행 (새 기술 적용, MSA 단계적 전환)
  • 동시성 이슈 파악은 시퀀스 다이어그램을 활용
  • 보안에 관련된 데이터 검증도 시퀀스 다이어그램에 추가
  • 레거시는 영원히 사라지지 않는다. 레거시를 폄하하지 말자.
  • 작업 자체보다 숨겨진 비용을 들여다 보기
  • 출퇴근 이동 시간에 글의 주제나 목차 계획해 보기

 

One Message

각종 역량(기술, 소통, 업무 관리, 리더십, 태도)이 균형 잡힌 시니어 개발자가 되기

 

느낀점

1~3년차 주니어 시절
기술이 최고라고 믿었던 주니어
주니어 시절에는 기술을 많이 알면 알수록 그것이 곧 능력이라고 생각했습니다.
기술 만능주의 마인드는 새로운 기술을 배우고, 이를 실제 업무에 적용해 보고 싶다는 강한 열망으로 이어졌습니다.
유행하는 기술을 사용해야 경쟁력이 높아지고, 이직도 수월해질 거라고 믿었기 때문입니다.
지금 돌이켜보면 그 시절의 저는 기술에 지나치게 매몰되어 있었다고 느끼기도 합니다. 한편으로는 기술에 대한 욕심이 있었기에 단기간에 빠르게 성장할 수 있었고, 업무를 능숙하게 처리할 수 있었던 것도 사실입니다.

 

4~8년차 중니어 시절
기술이 중요하지만 협업 능력도 점점 중요하다고 느낀 중니어
업무 경험이 쌓이면서 기술뿐 아니라 동료들과의 협업이 얼마나 중요한지 깨닫기 시작했습니다.
과거에는 더 좋은 평가와 연봉, 인센티브를 받기 위해 기술만능주의에 빠졌었지만, 이제는 기술이 팀의 목표를 달성하기 위한 수단임을 이해하게 되었습니다.
주니어 시절에는 개발에만 집중하면 됐지만, 중니어 시절에는 협업 채널이 늘어나며 여러 부서와의 소통이 필수가 되었습니다.
그럼에도 여전히 기술만능주의적 생각이 남아 있었습니다. 잦은 회의와 소통이 오히려 개발을 방해한다고 생각하며, 그저 개발에만 몰두하고 싶었습니다.

 

8년차 이상 시니어 시절
기술, 협업, 사람을 이해하는 능력이 중요하다고 믿게 된 시기
소프트웨어는 사람이 만드는 것임을 실감하기 시작했습니다.
이제는 갈등 조율, 멘토링, 심리적 안전, 동기부여, 시스템 설계 부분에 더 많은 관심을 두게 되었습니다.
이 시기에는 기술보다 사람들과의 소통, 팀 생산성 향상, 자동화, 소프트웨어 품질 향상에 더 큰 비중을 두었습니다.
나무만 보던 시절에서 벗어나 점점 숲을 보는 시기가 된 것입니다.
새로운 기술을 익히려는 욕심보다는 문제 해결 능력과 팀의 생산성을 높이기 위한 고민이 중심이 되었습니다.
개발을 방해하는 요소를 줄이고, pre-mortem/post-mortem 대응 방안을 고민하며, 후배 개발자들이 성장하고 집중할 수 있도록 돕는 데 더 많은 시간과 에너지를 쏟게 되었습니다.

 

저의 개발 경력을 다시 되짚어보면 주니어 시절에는 기술이 최고라고 생각했고, 그때 읽었던 책과 강의도 대부분 기술 중심이였습니다.
중니어 시절에도 기술이 최고라고 생각하면서 "어라? 협업 능력 또한 굉장히 중요하구나!" 를 깨닫게 되었던 것 같습니다. 협업 능력이 중요하다는 사실을 알게 되면서 기술 70 협업 30 정도의 시간과 에너지를 분배하였습니다.
시니어 시절에는 기술보다는 사람에 포커스를 맞추고 소통, 협업, 개발 문화, 시스템 설계 중심으로 업무를 해오고 있습니다.

 

사람은 각 시기마다 받아들일 수 있는 그릇의 크기가 다르다고 생각합니다.
주니어나 중니어 시절에 누군가가 제게 “협업 능력도 중요하니 소프트 스킬을 키워봐!” 라고 조언했다면, 아마 그 말이 제 마음 깊숙이까지는 와닿지 않았을 것입니다.
몇 년간의 경험이 쌓이면서 비로소 지금 내가 무엇을 해야 하는지에 대한 가이드라인이 조금씩 그려지고 있는 것 같습니다.

사실 이런 경험은 대부분의 사람들이 삶을 살아가며 한 번쯤은 겪는 일일지도 모릅니다.
예를 들어, 가정을 이루면 "아, 이제 내가 가장이 되었으니 무언가 책임져야겠구나." 라고 느끼며 동기부여가 생기고,
아이가 태어나면 "아, 내가 이제 아빠가 되었구나." 라는 자각과 함께 또 다른 형태의 책임감과 동기부여가 생겨납니다.

 

이처럼 경험과 역할의 변화가 스스로의 성장과 인식을 이끄는 원동력이 되는 것 같습니다.

'독서' 카테고리의 다른 글

쿠버네티스 개발 전략  (7) 2025.08.11
조대협의 서버 사이드 대용량 아키텍처와 성능 튜닝  (11) 2025.08.09
퓨처셀프  (17) 2025.08.05
책을 통해 성장하는 법  (10) 2025.07.14
회복탄력성  (5) 2025.06.01
세컨드 브레인 부스트  (0) 2025.04.27
가장 중요한 생각만 남기는 기술  (2) 2025.04.20
피니시  (0) 2025.04.06