4. string 불변성(immutability)과 인터닝(interning)

난이도 중 해설 보기 →

결함을 모두 찾고 원인·수정안·더 나은 설계를 제시하라. 마커 (A)(B) 는 주목 위치 힌트다.

결함 코드 · C#
// ============================================================================
// [언어 내부동작 문제] C# - string 불변성(immutability)과 인터닝(interning)
// ----------------------------------------------------------------------------
// 주제: string 이 불변 참조 타입이라는 점, 리터럴 인터닝(intern pool), ReferenceEquals
//       vs ==, 그리고 반복 문자열 연결이 만드는 할당(왜 StringBuilder 인가).
//
// 아래는 길드명/로그 문자열을 다루는 코드다. 같은 내용의 문자열이라도 "같은 객체"인지가
// 어떻게 갈리는지, 반복 연결이 무엇을 할당하는지 묻는다.
//
// 과제(코드를 고치는 문제가 아니라, 출력과 내부 동작을 예측·설명하는 문제):
//   1) (1)~(5) 각 줄의 출력(True/False)을 예측하고, 그 이유를 인터닝/불변성/== 오버로드로
//      설명하라. (리터럴, 컴파일타임 상수 폴딩, 런타임 연결의 차이를 구분할 것)
//   2) BuildLog 의 (6) 반복 += 가 매 반복마다 무엇을 할당하는지, 전체 비용이 왜 입력 길이의
//      제곱에 가까워지는지 설명하고, StringBuilder 가 이를 어떻게 바꾸는지 설명하라.
//   3) string 불변성이 주는 이점(스레드 안전 공유, 딕셔너리 키 안정성, 인터닝 가능)과 대가를
//      설명하라.
//   (먼저 직접 예측을 적은 뒤 answer.md 와 대조할 것)
// ============================================================================

using System;
using System.Text;

public class StringInternals
{
    public void Demo()
    {
        string a = "guild_master";
        string b = "guild_master";
        string c = "guild_" + "master";    // 컴파일타임 상수
        string prefix = "guild_";
        string d = prefix + "master";      // 런타임 연결

        Console.WriteLine(ReferenceEquals(a, b));                  // (1)
        Console.WriteLine(ReferenceEquals(a, c));                  // (2)
        Console.WriteLine(ReferenceEquals(a, d));                  // (3)
        Console.WriteLine(a == d);                                 // (4)
        Console.WriteLine(ReferenceEquals(a, string.Intern(d)));   // (5)
    }

    // 토큰들을 쉼표로 이어 로그 한 줄을 만든다
    public string BuildLog(string[] tokens)
    {
        string result = "";
        for (int i = 0; i < tokens.Length; i++)
            result += tokens[i] + ",";     // (6) 반복 연결
        return result;
    }
}
내 리뷰 · C#
내 답안 · 자동 저장

작성 후 위 해설 보기에서 모범 해설과 대조하세요.