#27 Что такое иммутабельность неизменяемость строк? Ответ на вопрос собеседования C# / .Net

Поділитися
Вставка
  • Опубліковано 6 вер 2024
  • #strings #immutablestrings #stringbuilder #csharp #dotnet #строки #andriyshyrokoriadov
    В видео описаное что такое иммутабельность неизменяемость строк. Помимо неизменяемости строк дано описание:
    - каким типом является строка - ссылочным или значимым
    - что такое String Builder
    - сравнение конкатенации строк со String Builder
    Обзор представлен в форме ответа на вопрос, который встречается на собеседованиях на позицию "программист C# / .Net".
    Подписывайтесь на канал [программирование, путешествия]: / @andreyshyrokoriadov
    0:05 - введение
    0:30 - каким типом является строка - ссылочным или значимым
    3:47 - что такое иммутабельность неизменяемость строк
    6:45 - класс String Builder
    8:00 - сравнение производительности конкатенации строк со String Builder
    12:30 - внутренняя имплементация класса String Builder
    Текст к фильму доступен по ссылке: ashyrokoriadov...
    Дополнительная информация:
    - строки - docs.microsoft...
    - String Builder - docs.microsoft...

КОМЕНТАРІ • 38

  • @user-ok7sf3ft5g
    @user-ok7sf3ft5g Місяць тому

    7:27 это же строковые литералы, компилятор их соединит в одну строку на этапе копиляции. Tоже самое будет если мы их объявим как
    const string s = "Hello";
    const string s1 = " ";
    const string s2 = "world";
    Console.WriteLine(s + s1 + s2);
    вызов Console.WriteLine будет транслирован как Console.WriteLine("Hello world");

  • @ramil9209
    @ramil9209 2 роки тому +3

    Я ещё не досмотрел видео, но уже пишу коммент, это супер круто, ты рассказываешь как это работает под капотом, то что я искал, спасибо за работу! Желаю продвижения каналу

  • @WP517i
    @WP517i 2 роки тому

    Недавно задали вопрос про интернирование строк. Так и пришел к этому видео! Спасибо большое!

  • @dvoryanoff1
    @dvoryanoff1 Рік тому

    Неожиданная подача, но очень понятно. 👍

  • @Ksushadik
    @Ksushadik 10 місяців тому

    Видео супер. Спасибо

  • @firemanhood1526
    @firemanhood1526 3 роки тому

    Только недавно решал какую-то кату в кодварс где работал со строкой и каждый раз при изменении строки ее нужно было присваивать в переменную, хотя это ссылочный тип, не понимал почему! а тут такая инфа на вес золота! Спасибо, это топ!

    • @dy0mber847
      @dy0mber847 2 роки тому

      Какой у тебя kyu?

  • @evgeniy4472
    @evgeniy4472 2 роки тому

    Боже, какое крутое видео) Благодарю за Вашу работу.

  • @ivannebyshinets5682
    @ivannebyshinets5682 2 роки тому

    Спасибо за отличный контент!

  • @nouchance
    @nouchance 2 роки тому

    Спасибо большое!

  • @user-ry7ci3op9k
    @user-ry7ci3op9k 2 роки тому

    Спасибо!

  • @hop173
    @hop173 2 роки тому

    хороший материал

  • @Ksushadik
    @Ksushadik 10 місяців тому

    Если в строковом типе данных мы инициализируем объект и присваиваем какое - то значение, а это значение уже есть у другого объекта, то место в памяти для второго объекта выделено не будет, так как оно уже есть и объект будет ссылаться на это же значение первого объекта. Это вроде называется интернированием. Поправьте, если ошибаюсь. Для других объектов класcа Object подобное тоже применимо? Или это только строк касается? После объявления оператора new() разве не выделяется отдельное место в памяти для объектов , даже если их данные будут полностью совпадать с данными других объектов?

  • @muxa000
    @muxa000 Рік тому +1

    3:02 - "согласитесь, это вообще бред" - а джава-программисты с этим живут 😀

  • @Misha1300
    @Misha1300 Рік тому

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

    • @Misha1300
      @Misha1300 Рік тому

      А также возник еще один вопрос: если строковый тип работает так, как я описал его выше, то как в такой же ситуации работает StringBuilder? Если я создам две разные переменные типа StringBuilder с одним и тем же значением внутри, то эти переменные будут ссылаться на одну и ту же область памяти, как и обычный string, или это будут два независимых объекта типа SB?

    • @ArtsiomAuhustsinovich
      @ArtsiomAuhustsinovich Рік тому

      При == или Equals две строки будут сравниваться по значению (это исключение для объекта типа string). При использовании object.ReferenceEquals как следует из названия метода сравниваться будут ссылки, но если вы просто определите две стринг переменные с одинаковым значением, то для второй будет использована уже существующая строка в string pool и ReferenceEquals вернёт true. Но если вы объявите str1 = "Hello" а str2 = "Hello1".Replace("1", "") например, то Replace вернёт новую строку и тогда ReferenceEquals вернёт false, т.к. ссылки будут разные уже

    • @Misha1300
      @Misha1300 Рік тому

      @@ArtsiomAuhustsinovich Интересно, этого я не знал, насчёт Replace. Спасибо

  • @asyncawait2839
    @asyncawait2839 2 роки тому

    Спасибо!
    Может я проглядел, но не нашел примера кода по ссылке, где сравниваются StringBuilder и со сложением строк.

    • @AndreyShyrokoriadov
      @AndreyShyrokoriadov  2 роки тому

      Тогда я еще не давал примеров в своём репо... однако сам код простой и каждый его сможет повторить за 15 минут.

  • @kozhevnikov1986
    @kozhevnikov1986 3 роки тому

    откуда информация, что размер стека в 64-битных системах 4Mb? Можно источник?

    • @AndreyShyrokoriadov
      @AndreyShyrokoriadov  3 роки тому

      Конкретного источника нет, однако на форумах часто об этом пишут и спрашивают. Например, тут:
      stackoverflow.com/questions/28656872/why-is-stack-size-in-c-sharp-exactly-1-mb

  • @kozhevnikov1986
    @kozhevnikov1986 3 роки тому

    Вы слышали про интернирование строк? на 3 минуте вы говорите бред. (ReferenceEquals(string1, string2) вернет True)

    • @kozhevnikov1986
      @kozhevnikov1986 3 роки тому

      на 6 минуте вы говорите уже противоположное

    • @AndreyShyrokoriadov
      @AndreyShyrokoriadov  3 роки тому +2

      Я думаю, Вы не поняли, что я сказал. Рекомендую еще раз пересмотреть эту часть видео, только на этот раз внимательно и с пониманием.
      А что касается кода, то да - тут я согласен:
      var string1 = "SampleString";
      var string2 = "SampleString";
      Console.WriteLine(string1 == string2); // TRUE
      Console.WriteLine(ReferenceEquals(string1, string2)); // TRUE

  • @JohnDoe-uu5jy
    @JohnDoe-uu5jy 3 роки тому

    Подскажите, а разве в методе FillStringCollection() в цикле при заполнении List не происходит неявного создания множества переменных типа string?

    • @AndreyShyrokoriadov
      @AndreyShyrokoriadov  3 роки тому

      Я немного поправлю Ваше предложение: "...в методе FillStringCollection() в цикле при заполнении List происходит ЯВНОЕ создание множества (100 000) переменных типа string". Здесь мы явно создаем каждую строку в линии 46. Однако при конкатенации ("+") создание строк происходит не явно и проблема состоит в том, что не все об этом знают при написании кода.

    • @JohnDoe-uu5jy
      @JohnDoe-uu5jy 3 роки тому

      ​@@AndreyShyrokoriadov Тогда непонятно откуда такие разительные отличия в работе двух методов. В любом случае сначала происходит заполнение коллекции List 100 000 уникальных строк (100 000 переменных), которые создаются на куче и даже на их создание должно уходить значительное время.
      То что при конкатенации неявно создаются новые переменные строкового типа и тем самым ещё нагружают память это понятно, но тут слишком огромная разница во времени.

    • @AndreyShyrokoriadov
      @AndreyShyrokoriadov  3 роки тому +1

      Я не поленился и запустил код, который я показывал в видео, но прежде я добавил таймеры, чтобы понять сколько выполняется каждый кусочек кода. Я использовал класс Stopwatch из пространства имен System.Diagnostics.
      Результаты следующие:
      - метод FillStringCollection() = 00:00:00.0600504;
      - метод ConcatStrings() = 00:03:18.6770528; 3 минуты!
      - метод ConcatStringsWithStringBuilder() = 00:00:00.0085115;
      Процессор Intel Core i7 6 генерации.

    • @JohnDoe-uu5jy
      @JohnDoe-uu5jy 3 роки тому

      @@AndreyShyrokoriadov Мне кажется в методе FillStringCollection() в цикле заполнения коллекции List в выражении result.Add(Guid.NewGuid().ToString()) переменная типа string создаётся по слабой ссылке и поэтому после заполнения сборщик мусора её удаляет и поэтому ресурсы не нагружаются. Как вы думаете?

    • @JohnDoe-uu5jy
      @JohnDoe-uu5jy 3 роки тому

      Можно попробовать для проверки сделать так:
      static void FillStringCollection()
      {
      var result = new List();
      for (int i = 0; i < 100000; i++)
      {
      @string = Guid.NewGuid().ToString();
      result.Add(@string);
      }
      _strings = result;
      }

  • @awdesawdeska6161
    @awdesawdeska6161 3 роки тому

    Ошибка в названии, в слове "неизменяеиость"