막막한 코드 리뷰는 그만: Claude가 어떻게 나의 비공식 시니어 개발자가 되었나
요약
Claude를 활용하여 단순 구문 체크를 넘어 로직, 아키텍처, 성능 문제를 파악하는 심층적인 코드 리뷰 워크플로우를 소개합니다. 구체적인 질문을 통해 확장성, 보안, 에러 핸들링 등 시니어 개발자 수준의 피드백을 얻는 실용적인 방법을 다룹니다.
핵심 포인트
- 단순 구문 오류가 아닌 로직 및 아키텍처 이슈 파악 가능
- 확장성, 보안, 에러 핸들링 등 구체적인 질문을 통한 심층 리뷰
- 캐싱 이슈나 메모리 누수 같은 복잡한 성능 문제 탐지
- 지능적인 러버 덕(Rubber Duck) 패턴으로 개발 생산성 향상
코드를 배포하고 3일 뒤에 "저기, X 부분은 고려해 보셨나요?"라는 Slack 메시지를 보며 멍하니 바라보던 그 기분을 아시나요? 네, 저도 그런 삶을 살았습니다. 하지만 이제는 아닙니다.
핵심은 이겁니다. 코드 리뷰 도구들은 구문 (syntax) 문제를 보여줍니다. 하지만 Claude는 로직 (logic) 문제, 아키텍처 (Architecture) 이슈, 성능상의 함정 (Performance gotchas)을 보여줍니다. 새벽 2시에 "아, 맞다, 이건 생각 못 했네"라고 말하게 만드는 바로 그런 문제들 말이죠.
전통적인 코드 리뷰의 문제점
팀원들은 최선을 다하고 있습니다. PR 코멘트들도 도움이 됩니다. 하지만 솔직해집시다. 누군가 당신의 코드를 리뷰할 때쯤이면, 그들은 이미 다른 여섯 가지 일로부터 컨텍스트 스위칭 (context-switching)을 하고 있는 상태입니다. 결국 당신은 표면적인 피드백만 받게 됩니다. 오타, 명명 규칙 (naming conventions), 운이 좋다면 "여기서는 Array 대신 Set을 사용하는 걸 고려해 보세요" 정도의 코멘트 말이죠.
더 깊은 문제들은 어떨까요? 운영 환경 (prod)에서 당신을 괴롭히는 문제들은요? 그런 것들은 눈에 보이게 망가진 것이 아니라 그저... 취약할 (fragile) 뿐이기 때문에 그냥 지나쳐 버립니다.
내가 실제로 Claude를 사용하는 방법
나는 Claude를 모든 아키텍처 서적을 읽었고 결코 기분이 나쁜 날이 없는 시니어 개발자처럼 대합니다. 나의 실제 워크플로우 (workflow)는 다음과 같습니다:
1단계: 코드 붙여넣기. 그냥 쏟아부으세요. 저는 보통 함수와 맥락을 파악할 수 있는 앞뒤 10줄 정도를 포함합니다.
async function getUserPosts(userId, limit = 10) {
const posts = await db.query('SELECT * FROM posts WHERE user_id = $1 LIMIT $2', [userId, limit]);
return posts;
...
2단계: 구체적인 질문하기. 그냥 "이것 좀 리뷰해 줘"라고 하지 마세요. 당신이 신경 쓰는 부분을 말하세요.
- "사용자가 10만 명에 도달해도 이 코드가 확장성 (scale)을 유지할까요?"
- "어떤 보안 이슈 (security issues)가 보이나요?"
- "내 에러 핸들링 (error handling)이 견고한가요?"
- "이 코드가 운영 환경에서 깨질 수 있는 세 가지 방법을 알려주세요."
3단계: 응답을 마치 진리처럼 읽기. Claude가 항상 옳기 때문이 아닙니다(항상 그렇지는 않습니다). 하지만 Claude는 대체로 옳으며, Claude가 제공하는 멘탈 모델 (mental model)은 매우 가치 있기 때문입니다.
실제 사례: 저는 제가 견고하다고 생각했던 캐싱 (caching) 함수를 붙여넣었습니다. Claude는 이렇게 말했습니다: "캐시가 비어 있는 동안 두 개의 요청이 동시에 들어오면 어떻게 될까요? 첫 번째 요청을 기다리는 대신 두 개의 동일한 DB 쿼리를 생성하게 될 것입니다."
정말 충격적이었습니다. 정확히 그 패턴을 세 번이나 배포했었거든요. 리뷰 과정에서도 전혀 잡아내지 못했습니다.
실제로 효과가 있는 실용적인 패턴들
"러버 덕 (Rubber Duck), 하지만 더 똑똑한" 패턴:
이 API 엔드포인트를 최적화하려고 합니다. 초당 500개의 요청을 처리하고 있는데 메모리가 계속 상승하고 있습니다. 제가 하고 있는 작업은 다음과 같습니다:
[paste code]
어디서 누수(leak)가 발생하고 있을까요?
Claude는 보통 APM (Application Performance Monitoring) 도구가 감지하기도 전에 N+1 쿼리, 클로저 누수 (closure leaks), 또는 해결되지 않은 프로미스 (unresolved promises)를 찾아냅니다.
"무엇이 잘못될 수 있는가" 패턴:
이 함수는 결제 양식의 사용자 입력을 검증합니다. 최악의 시나리오를 가정해 보세요. 공격 벡터 (exploit vector)는 무엇일까요?
[paste code]
새벽 2시의 장애 상황으로 이어질 수 있었던 SQL 인젝션 (SQL injection) 위험, 인증 우회 (auth bypasses), 또는 레이스 컨디션 (race conditions)을 잡아낼 수 있습니다.
"내가 너무 과하게 생각하는 건가" 패턴:
메시지 큐 (message queue)를 사용하도록 이 서비스 전체를 리팩터링 (refactor)하려 합니다. 이게 정말 필요한 일일까요, 아니면 제가 잘못된 문제를 풀고 있는 걸까요?
[paste code + context]
Claude는 당신이 성급하게 최적화를 하고 있는 것인지, 아니면 큰 문제를 피하려는 것인지 알려줄 것입니다.
왜 이것이 다른 접근 방식보다 나은가
린터 (Linters) 대비: 린터는 스타일을 잡아냅니다. Claude는 의도 (intent)를 잡아냅니다.
정적 분석 (Static analysis) 대비: SonarQube와 같은 도구는 문제를 표시합니다. Claude는 그것이 왜 문제인지, 그리고 어떻게 수정해야 하는지를 설명합니다.
사람 대비: 사람은 더 느리고, 더 피곤하며, 컨텍스트 스위칭 (context-switching)을 합니다. Claude는 새벽 3시에도 당신의 코드를 세상에서 가장 중요한 일인 양 읽어 내려갑니다.
아무것도 하지 않는 것 대비: 네, 이건 말할 필요도 없죠.
주의할 점
Claude가 완벽한 것은 아닙니다. 때로는 답변 형태를 띤 환각 (hallucinations)을 제공하기도 하고, 때로는 컨텍스트 (context)를 놓치기도 합니다. 대응 방법은 다음과 같습니다:
- 법이 아닌 제안으로 취급하세요. 무언가 이상하다는 느낌이 들면 깊이 파고드세요.
- 후속 질문을 하세요. "왜 그것이 문제가 되나요? 예시를 보여주세요."
- 조언을 테스트하세요. 리팩터링된 코드를 실행해 보세요. 실제로 더 빠른지 확인하세요.
- 실제 지표와 비교하세요. Claude가 무언가가 병목 현상 (bottleneck)이라고 말하는데 프로파일러 (profiler)가 그렇지 않다고 한다면, 프로파일러를 믿으세요.
진짜 이점
이렇게 3개월 동안 진행하고 나니, 이상한 일이 일어났습니다. 마치 Claude가 내 어깨 너머로 지켜보고 있는 것처럼 _생각_하기 시작한 것입니다. 코드를 붙여넣기 전에 스스로 문제를 발견하게 되었습니다. 아키텍처 (Architecture) 결정이 더 나아졌습니다. 똑같은 유형의 버그를 배포하는 일도 멈추게 되었습니다.
그것이 진짜 승리입니다. Claude가 당신의 코드를 리뷰해준다는 것이 아니라, 대화를 통해 더 나은 관행 (best practices)을 내면화하게 된다는 점입니다.
내일 바로 시도해 보세요
최근에 배포한 함수 중 두 번 이상 고민했던 것을 하나 골라보세요. 그것을 Claude에게 붙여넣으며 "이 코드의 문제점이 뭐야?"라고 물어보고 어떤 결과가 돌아오는지 확인해 보세요.
아마도 다음과 같은 일이 일어날 것입니다: 무언가를 배우게 될 것입니다. 그리고 그 배움은 다음 함수를 작성할 때 사용하게 될 것입니다.
그것이 더 나은 코드를 만드는 방법입니다. 한 번의 리뷰를 통해 하나씩 쌓아가는 것이죠.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기