클린코드/리팩토링 주니어 기술면접
새 면접Q. 클린코드에서 함수(메서드)의 이름을 지을 때 지켜야 할 원칙은 무엇인가요? 좋은 함수명의 특징을 설명해주세요.
함수명이 무엇을 하는지, 어떻게 읽히는지, 그리고 부수효과에 대해 생각해보세요.
좋은 함수명은 첫째, 함수가 수행하는 동작을 명확하게 표현해야 합니다. 둘째, 동사로 시작하여 무엇을 하는지 직관적으로 알 수 있어야 합니다. 셋째, 함수의 의도와 목적을 드러내며 주석 없이도 이해할 수 있어야 합니다. 넷째, 부수효과가 있다면 함수명에 포함시켜 예상치 못한 동작을 방지해야 합니다. 마지막으로 일관된 네이밍 컨벤션을 따라 팀 전체가 같은 방식으로 이해할 수 있어야 합니다.
- • 동작을 명확하게 표현
- • 동사로 시작
- • 의도를 드러내는 이름
- • 부수효과 명시
코드 리뷰 시 함수명만 보고도 기능을 파악할 수 있어 유지보수 시간을 크게 단축시킵니다.
그렇다면 getUserData와 fetchUserData 중 어떤 이름이 더 적절할까요? 그 이유는 무엇인가요?
Q. 함수가 너무 길어졌을 때 적용할 수 있는 리팩토링 기법에는 어떤 것들이 있나요? 최소 3가지 이상 설명해주세요.
긴 함수를 여러 개의 작은 단위로 나누는 방법들을 생각해보세요.
첫 번째는 함수 추출(Extract Method)로, 의미 있는 코드 블록을 별도의 함수로 분리하는 방법입니다. 두 번째는 임시 변수를 쿼리 함수로 바꾸기로, 복잡한 계산 로직을 별도 함수로 추출합니다. 세 번째는 조건문 분해하기로, 복잡한 if-else 구조를 각각의 함수로 분리하여 가독성을 높입니다. 네 번째는 매개변수 객체 만들기로, 여러 개의 매개변수를 하나의 객체로 묶어 함수 시그니처를 단순화합니다. 이러한 기법들을 통해 함수는 한 가지 일만 수행하는 단일 책임 원칙을 따르게 됩니다.
- • 함수 추출
- • 임시 변수를 쿼리 함수로
- • 조건문 분해
- • 단일 책임 원칙
레거시 코드를 유지보수할 때 200줄 이상의 긴 함수를 작은 단위로 분리하여 버그 수정 시간을 단축시킵니다.
함수를 추출할 때 적절한 함수의 길이는 어느 정도라고 생각하나요?
Q. 매직 넘버(Magic Number)란 무엇이며, 왜 문제가 되나요? 이를 해결하는 방법을 설명해주세요.
코드에 직접 작성된 숫자가 어떤 의미인지 알기 어려운 경우를 생각해보세요.
매직 넘버란 코드에 직접 하드코딩된 숫자 리터럴로, 그 의미를 코드만으로는 파악하기 어려운 것을 말합니다. 문제점은 첫째, 숫자만 보고는 그것이 무엇을 의미하는지 알 수 없어 가독성이 떨어집니다. 둘째, 같은 값이 여러 곳에 중복되어 있을 때 수정이 어렵고 실수가 발생할 수 있습니다. 해결 방법은 의미 있는 이름을 가진 상수로 추출하는 것입니다. 예를 들어 86400이라는 숫자 대신 SECONDS_PER_DAY와 같은 상수를 사용하면 코드의 의도가 명확해집니다. 이를 통해 유지보수성과 가독성이 크게 향상됩니다.
- • 하드코딩된 숫자 리터럴
- • 가독성 저하
- • 의미 있는 상수로 추출
- • 유지보수성 향상
결제 시스템에서 수수료율이나 제한 금액 같은 값을 상수로 관리하여 정책 변경 시 한 곳만 수정하면 됩니다.
0이나 1 같은 숫자도 항상 상수로 추출해야 할까요?
Q. 단일 책임 원칙(SRP, Single Responsibility Principle)이 무엇인지 설명하고, 이를 위반했을 때 발생할 수 있는 문제점을 말해주세요.
클래스나 함수가 변경되어야 하는 이유가 몇 개인지 생각해보세요.
단일 책임 원칙은 하나의 클래스나 함수는 단 하나의 책임만 가져야 하며, 변경의 이유도 하나여야 한다는 원칙입니다. 즉, 하나의 모듈은 하나의 액터(사용자 그룹)에 대해서만 책임을 져야 합니다. 이를 위반하면 첫째, 한 기능의 변경이 다른 기능에 영향을 미쳐 예상치 못한 버그가 발생할 수 있습니다. 둘째, 코드의 결합도가 높아져 테스트가 어려워집니다. 셋째, 여러 책임이 얽혀있어 코드 이해와 유지보수가 복잡해집니다. 예를 들어 사용자 인증과 데이터베이스 저장을 한 클래스에서 처리하면, 인증 로직 변경 시 DB 코드까지 영향받을 수 있습니다.
- • 하나의 책임
- • 하나의 변경 이유
- • 낮은 결합도
- • 테스트 용이성
유저 서비스 클래스에서 인증, 권한, 알림, 로깅을 모두 처리하면 하나의 변경이 전체 시스템에 영향을 미칩니다.
실제 프로젝트에서 클래스가 여러 책임을 가지고 있는지 어떻게 판단할 수 있을까요?
Q. 레거시 코드를 리팩토링할 때 테스트 코드가 없는 상황이라면, 어떤 순서와 전략으로 안전하게 리팩토링을 진행해야 할까요?
먼저 안전망을 만들고, 작은 단위로 점진적으로 개선하는 방법을 생각해보세요.
첫 번째 단계는 현재 동작을 보존하기 위해 특성 테스트(Characterization Test)를 작성하는 것입니다. 이는 현재 코드가 어떻게 동작하는지 문서화하고 검증하는 역할을 합니다. 두 번째는 테스트 가능한 구조로 만들기 위해 의존성을 분리하고 seam을 만드는 작업입니다. 세 번째는 작은 단위로 리팩토링을 진행하되, 각 변경 후 즉시 테스트를 실행하여 동작이 변하지 않았는지 확인합니다. 네 번째는 커버리지를 점진적으로 높여가며 더 안전한 리팩토링 환경을 구축합니다. 중요한 것은 한 번에 많은 것을 바꾸지 않고, 동작 변경과 구조 개선을 분리하여 진행하는 것입니다. 또한 버전 관리 시스템을 활용해 언제든 되돌릴 수 있도록 자주 커밋해야 합니다.
- • 특성 테스트 작성
- • 의존성 분리
- • 작은 단위 변경
- • 동작 보존 우선
- • 점진적 개선
5년 된 결제 모듈을 개선할 때 테스트 없이 바로 수정하면 실제 결제 오류로 이어질 수 있어 특성 테스트부터 작성합니다.
리팩토링 중 예상치 못한 버그가 발견되었다면 어떻게 대응해야 할까요?
아직 댓글이 없습니다. 첫 번째 댓글을 남겨보세요!