Elementor Header #8

35. Детерминированность

1. Введение

Детерминированность — это свойство кода, при котором одинаковые входные данные всегда дают одинаковый результат.

Тип кода Описание Пример
Детерминированный Одинаковые входные данные → один и тот же результат 2 + 3 всегда = 5
Недетерминированный Результат зависит от внешних факторов Random().Next(1, 100)

📌 Пример кода:

				
					// Детерминированная функция
int Sum(int a, int b) 
{
    return a + b;
}
Console.WriteLine(Sum(2, 3)); // Всегда 5

// Недетерминированная функция
int GetRandomNumber() 
{
    return new Random().Next(1, 100);
}
Console.WriteLine(GetRandomNumber()); // Разные числа

				
			

2. Детерминированные и недетерминированные операции

Тип операции Примеры Детерминированность
Арифметика +, -, *, / ✅ Детерминированная
Строковые методы ToUpper(), Replace() ✅ Детерминированная
Дата и время DateTime.Now ❌ Недетерминированная
Случайные числа Random().Next() ❌ Недетерминированная
Чтение файлов File.ReadAllText() ❌ Недетерминированная

📌 Пример:

				
					Console.WriteLine(DateTime.Now); // Каждый раз разное время

				
			

3. Почему детерминированность важна?

Преимущество Описание
📌 Предсказуемость Код проще тестировать
🚀 Кэширование Можно сохранить результат и не вычислять заново
🏆 Безопасность в многопоточной среде Детерминированные функции легче параллелить

📌 Пример кэширования результата:

				
					Dictionary<int, int> cache = new Dictionary<int, int>();

int Square(int x)
{
    if (!cache.ContainsKey(x))
    {
        cache[x] = x * x;
    }
    return cache[x];
}

Console.WriteLine(Square(5)); // Кэширует и возвращает 25
Console.WriteLine(Square(5)); // Берёт из кэша

				
			

3. Двойные кавычки (") – Строки (string)

Двойные кавычки используются для текстовых данных (string).

				
					Dictionary<int, int> cache = new Dictionary<int, int>();

int Square(int x)
{
    if (!cache.ContainsKey(x))
    {
        cache[x] = x * x;
    }
    return cache[x];
}

Console.WriteLine(Square(5)); // Кэширует и возвращает 25
Console.WriteLine(Square(5)); // Берёт из кэша

				
			

4. Как сделать код детерминированным?

Плохая практика Хорошая альтернатива
DateTime.Now внутри функции Передавать дату как аргумент
new Random() внутри функции Передавать Random как параметр
Использование глобальных переменных Локальные переменные

📌 Пример с Random:

				
					// Плохой вариант: каждый раз создаётся новый объект Random
int GetRandomValue()
{
    return new Random().Next(1, 100);
}

// Хороший вариант: передаём генератор случайных чисел
int GetRandomValue(Random random)
{
    return random.Next(1, 100);
}

Random rnd = new Random();
Console.WriteLine(GetRandomValue(rnd)); // Теперь более предсказуемо

				
			

Заключение

Детерминированность Недетерминированность
Один и тот же вход → один и тот же выход Результат зависит от внешних факторов
Легче тестировать и отлаживать Труднее предсказать результат
Подходит для многопоточности Может вызвать неожиданные баги

🚀 Вывод:
Используйте детерминированные функции, когда это возможно!

Тестовое задание

Задание Что нужно сделать
1️⃣ Написать детерминированную функцию, которая принимает строку и делает её заглавной с ! в конце ("hello""HELLO!")
2️⃣ Написать недетерминированную функцию, которая возвращает случайное число от 1 до 10

📌 Пример решения:

Правильный код:

				
					string message = "Hello, world!";
char quote = '\"';
string path = @"C:\Users\Admin";

				
			

Попробуйте написать и запустить этот код, чтобы убедиться в правильности выполнения операций и особенностях работы с числами с плавающей точкой.

logo