Змінюй хід війни! Допомагай ЗСУ!
  • Знижка на баннерну рекламу 30%! Банер на всіх сторінках сайту, в мобільній та десктопній версії за 14 тис. грн на місяць. Статистика сайту. Контакт: kharkovforum.com@gmail.com

Интересные вопросы для .NET разработчиков под web

  • Автор теми Автор теми Yaroslav4ik
  • Дата створення Дата створення
Статус: Офлайн
Реєстрація: 05.03.2007
Повідом.: 38
Интересные вопросы для .NET разработчиков под web

В процессе работы я постоянно натыкался на какие-либо проблемы, загвоздки по решению тех или иных задач в программировании. После успешного решения проблемы я сохранял вопросы и ответы, к которым я иногда прибегаю чтобы освежить память.
Здесь я выложу эти интересные на мой взгляд вопросы, а вы пробуйте ответить. Думаю это будет полезно как для начинающих программистов, так и для среднего уровня. Также их можно будет использовать синиорам при собеседовании людей. И так, вперед! ;)
 

Вкладення

  • lambdaExpression1.webp
    lambdaExpression1.webp
    23.6 КБ · Перегляди: 221
Имхо, если MyPerson сделать структурой, вопрос действительно можно использовать на собеседовании.

что выведет это:
Код:
class Program
{
    static int x = 100;

    static void Main(string[] args)
    {
        Action action = GetAction();

        action();

        x = 200;

        action.Invoke();
    }

    static Action GetAction()
    {
        var y = x;
        return () => Console.WriteLine(y);
    }
}
 
Что-то все молчат, поддержу тему, нужная ведь, и полезная.

Yaroslav4ik, там случится Exception (FirstOrDefault вернет null, а потом случится попытка взять свойство FirstName от null).

1stein: два раза по 100, изменение x уже не влияет на y. Если написать () => Console.WriteLine( x + y), будет 200 и 300. y стала статической переменной в контексте action.

Кстати, между action() и action.Invoke() разница есть ? :)
 
а что выведет это ? :
Код:
class Program
    {
        static int x = 100;

        static void Main(string[] args)
        {
            Action action = GetAction();
            x = 1;
            action.BeginInvoke(null, null);
            Thread.Sleep(99);
            x = 2;
            action.BeginInvoke(null, null);
            x = 3;
            action.BeginInvoke(null, null);
        }

        static Action GetAction()
        {
            Thread.Sleep(100);
            var y = x;
            return () => Console.WriteLine(y+x);
        }
    }
 
Делегат создан с y = 100 (уже не поменяется никогда) и x = 100. Перед созданием ждали 100 мс в основном потоке, сам делегат выполняется без ожиданий.

Перед первым вызовом x = 1, вызов делегата, основной поток ждет 99мс, за это время делегат скорее всего успеет вывести 101. Понятно, что успеет, но утверждать это на 100% не получается.

Перед вторым вызовом x = 2, вызов делегата, он пошел выводить 102. Успеет ли ? :) Пока он там работает с консолью, x присваивается значение 3. До вывода на консоль значения 102 или после ? :) Затем тут же опять вызывается делегат, который пытается успеть вывести 103. Но приходит злобный убийца мусора и судьба его печальна.

В общем, при строгом формальном подходе я лично считаю, что результат непредсказуемый, зависит от много чего. Ни один поток не закончен по EndInvoke(). Дискутабельно.
 
Кстати, между action() и action.Invoke() разница есть ? :)

Поидее нет, в первом случае также вызывается Invoke, правда делает это компилятор.

Затем тут же опять вызывается делегат, который пытается успеть вывести 103. Но приходит злобный убийца мусора и судьба его печальна.

Не силен в многопоточности, но все же, почему придет сборщик мусора в то время когда основной поток спит?
 
Основной после x = 3 не спит, поэтому приход сборщика мусора наступает через пару микросекунд после начала вывода на консоль. Собственно, можно попробовать проверить, убьет ли сборщик спящий поток, заменить последнюю строчку на такое:

Код:
return () => 
{
  Thread.Sleep(500);
  Console.WriteLine(y+x);
}

Если 103 не выведет - значит, убили.
 
Основной после x = 3 не спит, поэтому приход сборщика мусора наступает через пару микросекунд после начала вывода на консоль. Собственно, можно попробовать проверить, убьет ли сборщик спящий поток, заменить последнюю строчку на такое:

Код:
return () => 
{
  Thread.Sleep(500);
  Console.WriteLine(y+x);
}

Если 103 не выведет - значит, убили.

Что-то вообще ничего не выводится вродекак:confused:
 
Ну да, что и требовалось доказать :)

Все пропало. Пропало все (с) ЮВТ.

Делегат спит дольше, чем выполняется основной поток, поэтому все три потока делегата убивает сборщик мусора.

Мир многопоточности суров и непредсказуем :)
 
Не может такого быть, чтобы основной поток завершился, затем завершился процесс, выгрузилась CLR и собрался мусор всего за каких-то 100 (или даже 500) мс, выведет все три меседжа 101, 102 и 103, и киньте в меня exception-ом если это не так :)
 
Квест, эксперимент немного искажен дебагом :) Сборщик-то мусора стоит и ждет на брякпоинте.

Запусти это же, только EXE из операционки, чтобы консоль видеть.
 
Запусти это же, только EXE из операционки, чтобы консоль видеть.

Проверял и простым запуском экзешника скомпилированного без дебагера. Выводит все три... ) Выходит что все не настолько быстро происходит у CLR. Вобщем не важно, все равно тема совсем не специфична для web-девелопмента :)
 
Проверял и простым запуском экзешника скомпилированного без дебагера. Выводит все три... ) Выходит что все не настолько быстро происходит у CLR. Вобщем не важно, все равно тема совсем не специфична для web-девелопмента :)

Ты какой код проверяешь я сколько не проверял ничего на консоль не выводится. Вот код.
Код:
class Program
    {
        static int x = 100;

        static void Main(string[] args)
        {
            Action action = GetAction();
            x = 1;
            action.BeginInvoke(null, null);
            Thread.Sleep(99);
            x = 2;
            action.BeginInvoke(null, null);
            x = 3;
            action.BeginInvoke(null, null);
        }

        static Action GetAction()
        {
            Thread.Sleep(100);
            var y = x;
            return () => { Thread.Sleep(100); Console.WriteLine(y + x); };
        }
    }
 
Ты какой код проверяешь

Тот что в посте №4. А у тебя тут доп. задержка в 100 мс во время return-а, поэтому если ничего не выводится значит BeginInvoke создает фоновый а не активный поток, и приложение не ждет пока он выполниться прежде чем завершиться.
 
Очень понравился код Влада.
А почему идет так медленно изучение ?
 
Назад
Зверху Знизу