LabHub
배우기 러닝패스 코스

필드 번호를 바꿨더니 옛 클라이언트가 조용히 틀린 값을 읽었다 · 바이트 한 줄이 필드 번호를 품고 있다 · 퀴즈

퀴즈: 바이트에는 이름이 없다

LabHub 에서 이어서 보기

문항 6개. 정답과 해설은 풀어 본 뒤에 보여 드립니다.

  1. int32 필드 1 에 150 을 넣으면 `08 96 01` 세 바이트가 된다. 첫 바이트 `08` 이 뜻하는 것은?

    1. 필드 번호 1, 와이어 타입 0(VARINT) 인 태그
    2. 메시지의 전체 길이가 8 바이트라는 표시
    3. 필드 이름 a 의 해시를 한 바이트로 줄인 값
    4. 값 150 의 상위 바이트를 먼저 쓴 것
  2. 옛 파서가 새로 추가된 필드 번호를 만나도 오류 없이 건너뛸 수 있는 근거는?

    1. 메시지 앞에 필드 개수와 각 길이 표가 있어서
    2. 새 필드는 항상 메시지 맨 뒤에 붙도록 규칙이 정해져 있어서
    3. 태그의 와이어 타입이 값의 길이를 알려 주기 때문에
    4. 파서가 .proto 파일을 런타임에 다시 내려받기 때문에
  3. `string b = 2` 에 "testing" 을 넣으면 `12 07 74 65 …` 로 시작한다. 여기서 `07` 은?

    1. 필드 2 가 일곱 번째로 직렬화됐다는 순서 번호
    2. 문자열 페이로드의 바이트 수를 담은 길이 varint
    3. UTF-8 인코딩 방식을 가리키는 코드 7
    4. 다음 필드까지 건너뛸 태그의 개수
  4. `int32` 필드에 -1 을 넣으면 10 바이트가 되고 `sint32` 는 1 바이트가 된다. 그 차이를 만드는 것은?

    1. sint32 는 부호 비트를 태그의 와이어 타입 자리에 옮겨 담기 때문에
    2. int32 는 값과 무관하게 항상 고정 10 바이트로 정해져 있기 때문에
    3. sint32 는 값을 절반으로 나눠 저장해 바이트가 줄어들기 때문에
    4. int32 는 64비트 2의 보수를, sint32 는 ZigZag 값을 varint 로 보내기 때문에
  5. `repeated int32 e = 5` 에 1, 2, 3 을 넣으면 `2a 03 01 02 03` 이 된다. 이 인코딩의 이름과 성질은?

    1. packed — 태그 하나짜리 LEN 레코드 안에 값이 이어 붙는다
    2. grouped — SGROUP 과 EGROUP 태그로 값을 감싼다
    3. indexed — 각 값 앞에 위치 번호가 붙는다
    4. expanded — 원소마다 태그 `28` 이 반복된다
  6. 같은 메시지 객체를 두 번 직렬화한 바이트를 비교해 변경 여부를 판단하는 코드가 위험한 이유는?

    1. 직렬화할 때마다 타임스탬프 필드가 자동으로 붙기 때문에
    2. 직렬화 순서와 바이트 출력이 안정적이라는 보장이 없기 때문에
    3. 두 번째 직렬화부터는 알 수 없는 필드가 버려지기 때문에
    4. 메시지가 2 GiB 를 넘으면 앞부분만 잘려 나가기 때문에