Git 시니어 CS 기초 기술면접

Git 시니어 (7년+) CS 기초 5문항 조회수 92 · 2026-06-25 (목) 03:11:11
1 자료구조
Hard

Q. Git의 인덱스(staging area)는 내부적으로 어떤 자료구조로 구현되어 있으며, 이 자료구조를 선택한 이유는 무엇인가요? 수천 개의 파일이 있는 프로젝트에서 git add와 git status 명령의 성능을 최적화하기 위해 인덱스가 어떻게 설계되었는지, 그리고 파일 변경 감지를 빠르게 하기 위한 메커니즘을 설명해주세요.

A. 모범답안

Git의 인덱스는 정렬된 바이너리 파일 형태의 플랫 파일 구조로 구현되어 있으며, 각 엔트리는 경로명으로 정렬되어 이진 탐색을 가능하게 합니다. 파일의 stat 정보(mtime, ctime, inode 등)를 함께 저장하여 파일 시스템의 메타데이터만 비교해도 변경 여부를 빠르게 판단할 수 있습니다. 또한 인덱스 확장(index extension) 메커니즘을 통해 캐시 트리나 untracked cache 같은 추가 최적화 정보를 저장합니다. 대규모 프로젝트에서는 fsmonitor 확장을 활용해 파일 시스템 이벤트를 구독하여 변경된 파일만 스캔함으로써 git status의 성능을 획기적으로 개선할 수 있습니다.

핵심 포인트
  • • 인덱스는 경로명으로 정렬된 바이너리 플랫 파일로 O(log n) 이진 탐색 지원
  • • stat 정보(mtime, inode 등)를 저장하여 파일 내용을 읽지 않고도 변경 감지 가능
  • • 캐시 트리, untracked cache, fsmonitor 등의 확장으로 대규모 프로젝트 성능 최적화
  • • 인덱스 엔트리는 SHA-1 해시, 파일 모드, 경로 등을 포함하는 고정 크기 헤더 구조
Follow-up 질문

인덱스의 캐시 트리(cache tree) 확장은 어떤 원리로 커밋 생성 속도를 향상시키나요? tree 객체를 재사용하는 메커니즘을 설명해주세요.

2 네트워크
Hard

Q. Git의 전송 프로토콜에서 사용하는 packfile 전송 최적화 기법을 설명해주세요. 특히 클라이언트와 서버 간에 공통 커밋을 찾는 negotiation 과정, delta compression을 활용한 데이터 압축, 그리고 thin pack과 thick pack의 차이점과 사용 시나리오를 포함해서 답변해주세요. 느린 네트워크 환경에서 대용량 저장소를 clone할 때 이러한 최적화가 어떻게 작동하는지도 설명해주세요.

A. 모범답안

Git의 negotiation 과정은 클라이언트가 가진 커밋 SHA를 서버에 전송하고, 서버는 이를 기반으로 클라이언트에 없는 객체만 전송하기 위해 양방향 통신을 수행합니다. Packfile은 delta compression을 사용해 객체 간 차이만 저장하여 전송량을 크게 줄이며, base 객체와 delta chain을 구성합니다. Thin pack은 클라이언트가 이미 가진 객체를 base로 참조하여 네트워크 전송을 최소화하지만 받는 쪽에서 thick pack으로 변환해야 하며, thick pack은 모든 base 객체를 포함하여 자체 완결적입니다. 느린 네트워크에서는 multi-ack 프로토콜로 여러 공통 커밋을 동시에 확인하고, depth 제한이나 filter를 통해 전송량을 더욱 줄일 수 있습니다.

핵심 포인트
  • • Negotiation 과정에서 클라이언트의 have/want 교환으로 필요한 객체만 식별
  • • Delta compression으로 객체 간 차이만 전송하여 네트워크 사용량 최소화
  • • Thin pack은 수신자가 가진 객체를 base로 사용, thick pack은 모든 객체 포함
  • • Multi-ack, sideband, capabilities 등의 프로토콜 확장으로 효율성 향상
Follow-up 질문

Git의 bitmap index는 어떻게 reachability 계산을 가속화하며, 대규모 저장소에서 clone과 fetch 성능에 어떤 영향을 미치나요?

3 알고리즘
Hard

Q. Git의 blame 기능은 각 코드 라인의 최종 수정자를 추적합니다. 파일의 히스토리를 역순으로 탐색하면서 각 라인의 출처를 효율적으로 추적하는 알고리즘을 설계해야 한다면 어떤 접근 방식을 사용하시겠습니까? 특히 파일 이름 변경(rename detection), 라인 이동(code movement), 그리고 대규모 히스토리에서의 성능 최적화를 고려하여 설명해주세요.

A. 모범답안

Blame 알고리즘은 현재 파일에서 시작해 커밋 히스토리를 역순으로 탐색하며, 각 커밋의 diff를 분석하여 라인의 출처를 추적합니다. 각 라인에 대해 아직 출처가 확인되지 않은 라인들만 이전 커밋과 비교하며, 라인 번호 매핑 테이블을 유지하여 diff의 hunk 정보로 라인 이동을 추적합니다. Rename detection은 similarity index를 계산하여 파일 이름이 바뀌어도 히스토리를 연결하며, code movement 추적은 -M 옵션으로 같은 커밋 내 다른 파일로의 이동을, -C 옵션으로 다른 커밋의 파일에서의 복사를 감지합니다. 성능 최적화를 위해 모든 라인의 출처가 확인되면 조기 종료하고, 병렬 처리나 캐싱을 활용하며, 불필요한 경로의 히스토리는 탐색하지 않습니다.

핵심 포인트
  • • 역방향 히스토리 탐색으로 각 라인의 마지막 수정 커밋 추적
  • • Diff hunk 정보를 사용한 라인 번호 매핑 테이블 유지
  • • Similarity index 기반 rename detection과 code movement 추적
  • • 모든 라인 출처 확인 시 조기 종료 및 경로 가지치기로 성능 최적화
Follow-up 질문

Git의 pickaxe 검색(-S 옵션)은 특정 문자열이 추가되거나 삭제된 커밋을 찾습니다. 이를 효율적으로 구현하려면 어떤 인덱싱 전략이 필요할까요?

4 운영체제
Medium

Q. Git은 동시에 여러 프로세스가 같은 저장소에 접근할 때 데이터 일관성을 보장해야 합니다. Git이 사용하는 파일 시스템 기반의 락 메커니즘을 설명하고, index.lock, refs/heads/branch.lock 같은 락 파일의 역할을 설명해주세요. 또한 NFS 같은 분산 파일 시스템에서 atomic operation을 보장하기 위해 Git이 어떤 전략을 사용하는지, 그리고 락 획득 실패나 stale lock 상황을 어떻게 처리하는지 설명해주세요.

A. 모범답안

Git은 O_EXCL 플래그와 함께 파일을 생성하는 방식으로 락을 구현하며, 이는 대부분의 파일 시스템에서 atomic operation으로 보장됩니다. index.lock은 staging area 수정 시, refs/heads/branch.lock은 브랜치 참조 업데이트 시 생성되며, 작업 완료 후 rename을 통해 원자적으로 실제 파일로 교체합니다. NFS 환경에서는 O_EXCL의 원자성이 보장되지 않을 수 있어, Git은 추가로 파일 내용에 호스트 정보를 기록하고 재확인하는 방식을 사용합니다. Stale lock은 프로세스 ID를 확인하거나 타임스탬프를 검사하여 감지하며, 사용자가 수동으로 .lock 파일을 삭제하거나 일정 시간 후 자동으로 처리할 수 있습니다.

핵심 포인트
  • • O_EXCL 플래그를 사용한 파일 생성으로 atomic lock 구현
  • • 작업 완료 후 rename 시스템 콜로 원자적 파일 교체
  • • NFS 환경에서 추가 검증 로직으로 원자성 보장
  • • 프로세스 ID와 타임스탬프 기반 stale lock 감지 및 처리
Follow-up 질문

Git의 reference transaction 메커니즘은 여러 ref 업데이트를 원자적으로 수행합니다. 이것이 어떻게 구현되며, 트랜잭션 실패 시 롤백은 어떻게 이루어지나요?

5 데이터베이스
Medium

Q. Git의 객체 저장소를 관계형 데이터베이스 관점에서 분석한다면, 정규화 수준은 어느 정도이며 이것이 적절한 선택인 이유는 무엇인가요? Content-addressable storage 방식과 전통적인 RDBMS의 primary key 기반 접근의 차이점을 설명하고, Git이 이 방식을 선택함으로써 얻는 이점(deduplication, integrity, distributed operation)과 트레이드오프를 논하세요.

A. 모범답안

Git의 객체 저장소는 높은 수준의 정규화를 가지며, 각 객체는 내용 기반 해시를 키로 하는 불변 엔티티입니다. Content-addressable 방식은 같은 내용이 자동으로 하나의 객체로 저장되어 deduplication이 자연스럽게 이루어지며, 해시를 통해 데이터 무결성을 검증할 수 있습니다. 전통적인 RDBMS의 auto-increment primary key와 달리, 내용 기반 해시는 분산 환경에서 중앙 조정 없이도 전역적으로 유일한 식별자를 생성할 수 있어 병합이 용이합니다. 트레이드오프로는 내용 변경 시 새 객체를 생성해야 하므로 update가 비효율적이고, 해시 기반 조회만 가능하여 범위 검색이나 복잡한 쿼리가 어렵다는 점이 있지만, Git의 사용 패턴(append-only, immutable history)에는 최적화된 선택입니다.

핵심 포인트
  • • 내용 기반 해시로 자동 deduplication 및 데이터 무결성 보장
  • • 분산 환경에서 중앙 조정 없이 전역 유일 식별자 생성 가능
  • • 불변 객체 모델로 append-only 패턴에 최적화
  • • Update 비효율성과 제한적 쿼리 능력이 트레이드오프
Follow-up 질문

Git의 packed-refs 파일은 수많은 브랜치와 태그 참조를 하나의 파일로 통합합니다. 이것을 데이터베이스 인덱싱 관점에서 분석하면 어떤 최적화 기법에 해당하나요?

댓글 0

로그인 후 댓글을 작성할 수 있습니다.

아직 댓글이 없습니다. 첫 번째 댓글을 남겨보세요!