OOP Course
Сьогодні

Підрозділ 11.Q

Питання для самоконтролю

Питання для самоконтролю — Розділ 11. Робота з рядками 11.1. Рядки та клас String 1. Що означає незмінність immutability рядків у C ? Що насправді відбувається при виклику diagnosis.ToUpper — повертається зміне

Питання для самоконтролю — Розділ 11. Робота з рядками

11.1. Рядки та клас String

  1. Що означає незмінність (immutability) рядків у C#? Що насправді відбувається при виклику diagnosis.ToUpper() — повертається змінений оригінал чи новий об'єкт?

  2. Що виведе наступний код і чому?

    string a = "I10";
    string b = "I10";
    string c = new string(new char[] { 'I', '1', '0' });
    Console.WriteLine(a == b);
    Console.WriteLine(a == c);
    Console.WriteLine(ReferenceEquals(a, b));
    Console.WriteLine(ReferenceEquals(a, c));
  3. Що таке string interning і навіщо він потрібен? Чому рядки, створені через конкатенацію або new string(...), за замовчуванням не потрапляють у пул?

  4. Поясніть різницю між типами char і string на рівні пам'яті. Де зберігається char — в heap чи на стеку? А string?

  5. Чим string.IsNullOrWhiteSpace відрізняється від string.IsNullOrEmpty? Наведіть приклад рядка, для якого перший метод поверне true, а другий — false.

  6. Поясніть, чому s1 == s2 для рядків є порівнянням значень, а не посилань, хоча для більшості класів == порівнює посилання. Що для цього потрібно на рівні мови?

  7. Що поверне icd.Length для рядка "I10.9"? Чому для деяких Unicode-символів Length може бути більшим за кількість видимих символів?

  8. Для порівняння медичних кодів без урахування регістру який метод є кращим з точки зору продуктивності та коректності: code.ToLower() == "i10" чи string.Equals(code, "I10", StringComparison.OrdinalIgnoreCase)? Обґрунтуйте відповідь.


11.2. Операції з рядками

  1. Що поверне "I10.9".Substring(0, 3) і "I10.9"[^2..]? Запишіть еквівалентний синтаксис Range для обох варіантів.

  2. Що виведе наступний код? Знайдіть потенційну проблему та поясніть як її уникнути.

    string notes = "Прийом: 09:00. Виписка: 14:00. Повторний прийом: 17:00";
    int pos = notes.IndexOf("прийом");
    Console.WriteLine(pos);
    int pos2 = notes.IndexOf("прийом", 0, StringComparison.OrdinalIgnoreCase);
    Console.WriteLine(pos2);
  3. Поясніть роль параметра StringSplitOptions.RemoveEmptyEntries. Що поверне "a;;b".Split(';') без цього параметра і з ним?

  4. Поясніть оператор ^ (hat) та синтаксис Range (..) у C# 8+. Що означають icd[^1], icd[1..3], icd[^2..]?

  5. Чому ланцюгування Replace є можливим і зручним:

    string result = template
        .Replace("{NAME}", name)
        .Replace("{DATE}", date);

    Як це пов'язане з незмінністю рядків?

  6. Напишіть код, який із рядка " Петренко Іван Степанович \t" видаляє пробіли з обох кінців, перетворює на верхній регістр і замінює всі пробіли на дефіси.

  7. Порівняйте string.Compare(s1, s2) і s1.CompareTo(s2). Які значення вони повертають і коли? Чому перевага надається string.Compare при необхідності контролю над режимом порівняння?

  8. Поясніть, чому diagnosis.Contains("АРТЕРІАЛЬНА", StringComparison.OrdinalIgnoreCase) є кращим за diagnosis.ToLower().Contains("артеріальна") не лише з точки зору продуктивності, але й коректності.


11.3. Форматування та інтерполяція рядків

  1. Перелічіть три підходи до вставки значень у рядки в C#. Для якого сценарію кожен є найбільш доречним?

  2. Що виведе наступний код? Поясніть, що виводить кожен рядок.

    double bp = 140.567;
    int id = 42;
    Console.WriteLine($"{bp:F1}");
    Console.WriteLine($"{bp:F2}");
    Console.WriteLine($"{id:D6}");
    Console.WriteLine($"{0.847:P1}");
    Console.WriteLine($"{12345.6:N0}");
  3. Поясніть різницю між специфікаторами F, N і C. Де для кожного найкраще застосування в медичному контексті?

  4. Що таке вирівнювання у інтерполяції рядків? Поясніть синтаксис {value,8} і {name,-20}. В якому напрямку вирівнює кожна форма?

  5. Поясніть чому $"..." на рівні IL є еквівалентом string.Format(). В чому переваги $"..." перед string.Format для розробника?

  6. Що таке raw string literals (C# 11) і які проблеми вони вирішують? Наведіть приклад рядка з лапками всередині у старому і новому синтаксисі.

  7. Для чого потрібен параметр IFormatProvider (або CultureInfo) у string.Format? Чому при серіалізації числових даних у файли завжди слід передавати CultureInfo.InvariantCulture?

  8. Напишіть код, який форматує таблицю зі стовпцями "Пацієнт" (ширина 24, ліворуч), "Вік" (ширина 5, праворуч), "АТ" (ширина 8, одна десяткова, праворуч) для трьох пацієнтів.


11.4. Клас StringBuilder

  1. Чому конкатенація рядків у циклі через += має складність O(N²)? Поясніть причину через механізм незмінності рядків і підрахуйте загальну кількість операцій копіювання для N=100.

  2. Що виведе наступний код? Поясніть значення Length і Capacity після кожного кроку.

    var sb = new StringBuilder("Виписка:");
    Console.WriteLine($"L={sb.Length}, C={sb.Capacity}");
    sb.Append(" Петренко Іван Степанович");
    Console.WriteLine($"L={sb.Length}, C={sb.Capacity}");
    sb.Length = 8;
    Console.WriteLine(sb.ToString());
  3. Поясніть алгоритм подвоєння ємності StringBuilder. Чому загальна складність вставки N символів є O(N), а не O(N log N)?

  4. Чим Clear() відрізняється від new StringBuilder()? Коли Clear() є ефективнішим варіантом?

  5. Поясніть, що означає fluent API у контексті StringBuilder. Що повертає кожен метод (Append, AppendLine) і чому це уможливлює ланцюгування?

  6. Напишіть метод string BuildReport(Patient[] patients), який через StringBuilder формує багаторядковий текстовий звіт: заголовок, рядок для кожного пацієнта (ім'я, вік, МКХ), підсумковий рядок з кількістю пацієнтів.

  7. Порівняйте StringBuilder і string для наступних сценаріїв: (а) об'єднання 5 рядків поза циклом; (б) побудова рядка з 1000 фрагментів у циклі; (в) пошук підрядка у готовому тексті. Який варіант кращий у кожному випадку?

  8. Знайдіть проблему та поясніть як її виправити:

    var sb = new StringBuilder();
    for (int i = 0; i < 10_000; i++)
        sb = new StringBuilder(); // reset
        sb.Append($"Запис {i}\n");
    Console.WriteLine(sb.ToString());

11.5. Регулярні вирази

  1. Яку задачу вирішують регулярні вирази, яку не вирішують стандартні методи класу String (Contains, IndexOf, Split)? Наведіть конкретний приклад патерну, який неможливо виразити через ці методи.

  2. Що виведе наступний код і чому?

    var re = new Regex(@"^[A-Z]\d{2}(\.?\d)?$");
    string[] codes = { "I10.9", "J45.0", "999", "i10", "K25", "AB12.3" };
    foreach (var c in codes)
        Console.WriteLine($"{c}: {re.IsMatch(c)}");
  3. Поясніть різницю між жадібним і лінивим квантифікатором. Що поверне <.+> і <.+?> для рядка "<b>текст</b>"?

  4. Поясніть метасимвол \b (межа слова). Чим результат IsMatch("код I10.9", @"I10") відрізняється від IsMatch("код I10.9", @"\bI10\b")?

  5. Що таке іменовані групи (?<name>...) і яку перевагу вони мають над числовими групами? Напишіть шаблон для парсингу рядка "Петренко;Іван;67" з іменованими групами last, first, age.

  6. Поясніть різницю між lookahead (?=...) і lookbehind (?<=...). Напишіть вираз, який витягує число зі строки "АТ: 140 мм рт.ст." без включення одиниць виміру у результат.

  7. Порівняйте підходи: (а) статичний метод Regex.IsMatch(str, pattern) у циклі; (б) new Regex(pattern, RegexOptions.Compiled) як поле класу. В якому випадку кожен підхід є оптимальним?

  8. Спроєктуйте клас PatientValidator зі статичними readonly полями Regex для валідації: коду МКХ-10 (формат [A-Z]\d{2} або [A-Z]\d{2}.\d), номера телефону (10-13 цифр, можливо з +, пробілами, дефісами). Реалізуйте методи ValidateIcd(string) і ValidatePhone(string).

Розроблено Tomka Yurii · © 2026 ·