Git 시니어 기술면접
새 면접Q. Git의 객체 모델은 blob, tree, commit, tag 네 가지 타입으로 구성됩니다. 각 객체 타입의 역할과 상호 참조 관계를 설명하고, 하나의 커밋이 생성될 때 실제로 파일 시스템에 어떤 순서로 어떤 객체들이 생성되는지 구체적으로 설명해주세요. 또한 대규모 프로젝트에서 이러한 객체 생성 방식이 성능에 미치는 영향과 최적화 방안을 제시해주세요.
blob 객체는 파일 내용 자체를 저장하고, tree 객체는 디렉토리 구조와 blob/subtree에 대한 포인터를 저장하며, commit 객체는 최상위 tree, 부모 커밋, 메타데이터를 저장합니다. 커밋 생성 시 먼저 변경된 파일들의 blob이 생성되고, 하위 디렉토리부터 상위로 올라가며 tree 객체들이 생성된 후, 마지막으로 commit 객체가 생성됩니다. 대규모 프로젝트에서는 변경되지 않은 객체는 재사용되므로 중복 저장이 방지되며, pack file을 통해 delta compression으로 저장 공간을 최적화하고, index 파일을 활용하여 staging 시 불필요한 객체 생성을 방지합니다.
- • blob(파일 내용), tree(디렉토리 구조), commit(스냅샷+메타데이터), tag(레퍼런스) 객체의 계층적 참조 구조
- • 커밋 생성 시 blob → tree(bottom-up) → commit 순서로 객체가 생성되며, 변경되지 않은 객체는 재사용
- • pack file의 delta compression과 index 파일을 통한 성능 최적화
Git이 SHA-1에서 SHA-256으로 마이그레이션하는 과정에서 기존 객체 데이터베이스와의 호환성을 어떻게 유지할 수 있을까요?
Q. 1000명 이상의 개발자가 협업하는 대규모 프로젝트에서 Git 브랜치 전략을 설계해야 합니다. Git-flow, GitHub-flow, Trunk-based development의 장단점을 비교하고, CI/CD 파이프라인, 릴리즈 주기, 핫픽스 배포 시나리오를 고려하여 최적의 브랜치 전략을 제안해주세요. 또한 병목 지점과 해결 방안도 함께 설명해주세요.
Git-flow는 명확한 릴리즈 관리가 가능하지만 브랜치가 복잡하고 병합 오버헤드가 크며, GitHub-flow는 단순하지만 릴리즈 타이밍 제어가 어렵고, Trunk-based development는 CI/CD에 최적이지만 feature flag 관리가 필요합니다. 대규모 프로젝트에서는 short-lived feature branch + trunk-based 하이브리드 방식을 권장하며, main 브랜치는 항상 배포 가능 상태를 유지하고 feature flag로 릴리즈를 제어합니다. 병목 지점은 main 브랜치로의 병합 대기 시간인데, 이는 자동화된 테스트, 병렬 CI 파이프라인, merge queue 시스템으로 해결할 수 있습니다.
- • Git-flow(복잡/명확), GitHub-flow(단순/유연), Trunk-based(고속 배포)의 트레이드오프 이해
- • 대규모 팀에서는 short-lived branch + feature flag 조합이 효과적
- • merge queue와 자동화된 테스트로 병합 병목 해결
feature flag를 사용할 때 기술 부채가 누적되는 것을 방지하기 위한 관리 전략은 무엇인가요?
Q. 팀 전체에 일관된 커밋 컨벤션, 코드 품질 검사, 보안 스캔을 강제하기 위해 Git hooks를 활용하려고 합니다. client-side hooks와 server-side hooks의 차이점을 설명하고, 각각의 한계점과 우회 가능성을 고려하여 어떻게 조합해야 효과적인지 설계해주세요. 또한 hooks를 팀원들에게 배포하고 동기화하는 방법도 제안해주세요.
client-side hooks(pre-commit, commit-msg 등)는 로컬에서 빠른 피드백을 제공하지만 --no-verify로 우회 가능하고, server-side hooks(pre-receive, update)는 강제성이 있지만 네트워크 왕복으로 피드백이 느립니다. 효과적인 전략은 client-side에서 빠른 검사(포맷팅, 린팅)를 수행하고, server-side에서 필수 정책(커밋 서명, 브랜치 보호)을 강제하는 이중 검증 구조입니다. hooks 배포는 저장소 내 .githooks 디렉토리에 스크립트를 관리하고 git config core.hooksPath로 경로를 설정하거나, husky 같은 도구로 package.json에서 자동 설치하는 방식을 사용합니다.
- • client-side hooks는 빠르지만 우회 가능, server-side hooks는 강제성 있지만 느림
- • 이중 검증 구조: client에서 개발자 경험 향상, server에서 정책 강제
- • core.hooksPath 설정이나 husky로 hooks를 버전 관리하여 팀 전체 동기화
server-side hook에서 오래 걸리는 검사(예: 전체 테스트 스위트)를 수행하면 push가 타임아웃될 수 있는데, 이를 어떻게 해결할 수 있을까요?
Q. 수백 GB 크기의 바이너리 파일들을 포함하는 게임 개발 프로젝트에서 Git 저장소 성능 문제가 발생했습니다. Git LFS(Large File Storage)의 동작 원리를 설명하고, pointer file과 실제 객체 저장소 간의 관계, smudge/clean filter의 역할을 구체적으로 설명해주세요. 또한 Git LFS를 도입할 때 기존 히스토리를 마이그레이션하는 전략과 주의사항도 포함해주세요.
Git LFS는 대용량 파일을 별도 저장소에 저장하고 Git에는 작은 pointer file(텍스트)만 커밋합니다. clean filter는 add/commit 시 실제 파일을 LFS 저장소로 업로드하고 pointer로 치환하며, smudge filter는 checkout 시 pointer를 읽어 실제 파일을 다운로드합니다. 기존 히스토리 마이그레이션은 git lfs migrate를 사용하여 과거 커밋을 재작성하되, 이는 SHA가 변경되므로 팀 전체가 force-push 후 re-clone해야 합니다. 주의사항으로는 LFS 저장소 용량 관리, 네트워크 대역폭 비용, CI/CD 환경에서의 LFS 인증 설정이 필요합니다.
- • pointer file(메타데이터)과 실제 객체의 분리 저장, clean/smudge filter를 통한 투명한 변환
- • git lfs migrate로 히스토리 재작성 가능하지만 SHA 변경으로 팀 전체 재동기화 필요
- • LFS 저장소 용량, 네트워크 비용, CI/CD 인증 등 운영 고려사항
Git LFS 대신 Git submodules나 monorepo 구조로 바이너리 파일을 관리하는 것과 비교했을 때 어떤 트레이드오프가 있을까요?
Q. 엔터프라이즈 환경에서 Git 저장소의 보안을 강화해야 합니다. commit signing(GPG/SSH)의 동작 원리와 장점을 설명하고, signed commit을 필수로 강제하는 정책을 구현할 때 고려해야 할 사항들을 설명해주세요. 또한 브랜치별 접근 제어(protected branches, CODEOWNERS)를 설계할 때 권한 모델과 워크플로우를 어떻게 구성해야 하는지 제안해주세요.
commit signing은 개발자의 private key로 커밋 객체에 서명하고, public key로 검증하여 커밋 작성자의 신원을 보장합니다. 이는 이메일 스푸핑을 방지하고 공급망 공격을 완화하지만, 키 관리 복잡도와 CI/CD 환경에서의 자동화가 과제입니다. signed commit 강제 시 server-side hook으로 미서명 커밋을 거부하고, 팀원들의 public key를 중앙 관리하며, CI 봇 계정의 서명 전략도 수립해야 합니다. 브랜치 보호는 main/release 브랜치에 direct push 금지, required reviews 설정, CODEOWNERS로 특정 경로의 변경은 해당 팀 승인 필수로 구성하며, 권한은 역할 기반(RBAC)으로 관리합니다.
- • GPG/SSH 서명으로 커밋 작성자 신원 보장 및 공급망 공격 방지
- • server-side hook으로 서명 강제, 키 관리 자동화, CI 봇 서명 전략 필요
- • protected branches + required reviews + CODEOWNERS로 다층 접근 제어 구현
개발자의 GPG 키가 유출되었을 때 이미 서명된 과거 커밋들의 신뢰성을 어떻게 처리해야 할까요?
아직 댓글이 없습니다. 첫 번째 댓글을 남겨보세요!