Git 미드레벨 CS 기초 기술면접
새 면접Q. Git은 내부적으로 커밋 히스토리를 저장할 때 어떤 자료구조를 사용하나요? 이 자료구조의 특성이 Git의 브랜치 생성, 병합, 히스토리 탐색 성능에 어떤 영향을 미치는지 설명해주세요.
Git은 커밋 히스토리를 방향성 비순환 그래프(DAG, Directed Acyclic Graph) 구조로 저장합니다. 각 커밋 객체는 부모 커밋에 대한 포인터를 가지며, 머지 커밋의 경우 여러 부모를 가질 수 있습니다. 이 구조 덕분에 브랜치는 단순히 특정 커밋을 가리키는 포인터일 뿐이므로 생성 비용이 매우 낮고(O(1)), 공통 조상을 찾는 작업도 그래프 탐색 알고리즘으로 효율적으로 수행됩니다. 또한 DAG 특성상 순환 참조가 없어 히스토리 탐색 시 무한 루프 문제가 발생하지 않습니다.
- • DAG(Directed Acyclic Graph) 구조 사용
- • 각 커밋은 부모 커밋에 대한 포인터 보유, 머지 커밋은 다중 부모 가능
- • 브랜치는 커밋을 가리키는 포인터로 O(1) 생성 비용
- • 공통 조상 찾기, 히스토리 탐색 등 그래프 알고리즘으로 효율적 처리
Git에서 두 브랜치의 공통 조상(merge-base)을 찾을 때 사용하는 알고리즘은 무엇이며, 시간 복잡도는 어떻게 되나요?
Q. Git이 객체를 식별하기 위해 SHA-1 해시를 사용하는 이유와 장점을 설명하고, SHA-1의 충돌 취약점이 발견된 상황에서 Git이 어떻게 대응하고 있는지 설명해주세요.
Git은 SHA-1 해시를 사용하여 모든 객체(blob, tree, commit, tag)를 식별하며, 이는 내용 기반 주소 지정(content-addressable storage)을 가능하게 합니다. 동일한 내용은 항상 동일한 해시를 생성하므로 중복 저장을 방지하고, 데이터 무결성을 검증할 수 있습니다. SHA-1 충돌 공격(SHAttered)이 발견된 이후, Git은 충돌 감지 메커니즘을 추가했으며, SHA-256으로의 마이그레이션을 진행 중입니다(Git 2.29부터 실험적 지원). 또한 Git은 파일 크기 등 추가 메타데이터를 함께 검증하여 실제 충돌 공격의 영향을 최소화하고 있습니다.
- • SHA-1 해시로 객체 식별 및 내용 기반 주소 지정
- • 동일 내용의 중복 저장 방지 및 데이터 무결성 검증
- • SHA-1 충돌 감지 메커니즘 추가 및 SHA-256 마이그레이션 진행
- • 파일 크기 등 추가 검증으로 충돌 공격 영향 최소화
SHA-256으로 마이그레이션할 때 기존 SHA-1 기반 저장소와의 호환성은 어떻게 유지되나요?
Q. Git의 네트워크 프로토콜 중 Smart HTTP, Git Protocol, SSH의 차이점과 각각의 장단점을 설명하고, 기업 환경에서 프로토콜을 선택할 때 고려해야 할 보안, 성능, 방화벽 이슈를 설명해주세요.
Smart HTTP는 HTTP/HTTPS를 사용하여 방화벽 친화적이고 인증 통합이 쉬우며, 포트 443/80만 열면 되므로 기업 환경에서 가장 널리 사용됩니다. Git Protocol(git://)은 가장 빠르지만 인증 기능이 없어 읽기 전용으로만 사용되며, 포트 9418을 별도로 열어야 합니다. SSH는 강력한 인증과 암호화를 제공하지만 초기 연결 오버헤드가 있고, 키 관리가 필요합니다. 기업 환경에서는 일반적으로 Smart HTTP over HTTPS를 선택하여 TLS 암호화와 기존 인증 시스템(LDAP, OAuth)을 통합하고, 방화벽 정책을 단순화하는 것이 권장됩니다.
- • Smart HTTP: 방화벽 친화적, 인증 통합 용이, 표준 포트 사용
- • Git Protocol: 가장 빠르나 인증 없음, 별도 포트 필요
- • SSH: 강력한 보안, 키 기반 인증, 초기 연결 오버헤드
- • 기업 환경에서는 HTTPS + 기존 인증 시스템 통합이 일반적
Git의 pack protocol이 네트워크 전송을 최적화하는 원리와, negotiation 단계에서 어떻게 필요한 객체만 선별적으로 전송하는지 설명해주세요.
Q. Git의 객체 저장 방식에서 loose objects와 packfile의 차이를 설명하고, git gc(garbage collection)가 수행하는 작업과 이것이 디스크 공간 및 성능에 미치는 영향을 설명해주세요.
Loose objects는 개별 객체를 zlib으로 압축하여 .git/objects 디렉토리에 저장하는 방식으로, 빠른 쓰기가 가능하지만 저장 공간 효율이 낮고 파일 수가 많아집니다. Packfile은 여러 객체를 하나의 파일로 묶고 델타 압축을 적용하여 저장 공간을 크게 절약합니다. git gc는 loose objects를 packfile로 변환하고, 도달 불가능한 객체를 정리하며, 여러 packfile을 하나로 합치는 작업을 수행합니다. 이를 통해 디스크 사용량을 90% 이상 줄이고, 객체 조회 성능도 향상시킵니다. gc는 자동으로 실행되지만, 대규모 작업 후 수동 실행이 권장됩니다.
- • Loose objects: 개별 압축, 빠른 쓰기, 낮은 공간 효율
- • Packfile: 델타 압축, 높은 공간 효율, 여러 객체 묶음
- • git gc: loose to pack 변환, 미사용 객체 정리, packfile 통합
- • 디스크 사용량 90% 이상 절감 및 성능 향상
델타 압축(delta compression)이 동작하는 원리와, Git이 base 객체를 선택하는 휴리스틱 알고리즘을 설명해주세요.
Q. 여러 개발자가 동시에 같은 Git 저장소에 push할 때 발생할 수 있는 race condition과 Git이 이를 방지하기 위해 사용하는 메커니즘을 설명해주세요. 또한 분산 환경에서 일관성을 보장하는 방법도 함께 설명해주세요.
Git은 push 시 fast-forward 여부를 체크하여 동시성 문제를 방지합니다. 서버는 refs 업데이트 시 원자적(atomic) 파일 시스템 연산을 사용하며, 클라이언트가 제시한 old SHA가 현재 ref 값과 일치할 때만 업데이트를 허용합니다. 동시 push 시 먼저 도착한 요청만 성공하고 나머지는 rejected되어 pull 후 재시도해야 합니다. 분산 환경에서는 각 저장소가 독립적으로 동작하며, 최종 일관성(eventual consistency)을 따릅니다. 중앙 서버를 single source of truth로 사용하고, push 시점에 충돌을 감지하여 해결하는 낙관적 잠금(optimistic locking) 방식으로 일관성을 보장합니다.
- • fast-forward 체크 및 원자적 refs 업데이트로 race condition 방지
- • old SHA 검증으로 동시 push 시 하나만 성공, 나머지 rejected
- • 분산 환경에서 최종 일관성(eventual consistency) 모델 사용
- • 낙관적 잠금 방식으로 push 시점 충돌 감지 및 해결
GitHub나 GitLab 같은 중앙 서버에서 동시 push를 처리할 때 사용하는 lock-free 알고리즘이나 데이터베이스 트랜잭션 전략은 무엇인가요?
아직 댓글이 없습니다. 첫 번째 댓글을 남겨보세요!