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

Sdílet
Vložit
  • čas přidán 6. 09. 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...

Komentáře • 38

  • @ramil9209
    @ramil9209 Před 2 lety +3

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

  • @user-ok7sf3ft5g
    @user-ok7sf3ft5g Před měsícem

    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");

  • @WP517i
    @WP517i Před 2 lety

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

  • @dvoryanoff1
    @dvoryanoff1 Před rokem

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

  • @evgeniy4472
    @evgeniy4472 Před 2 lety

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

  • @ivannebyshinets5682
    @ivannebyshinets5682 Před 2 lety

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

  • @firemanhood1526
    @firemanhood1526 Před 3 lety

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

  • @Ksushadik
    @Ksushadik Před 11 měsíci

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

  • @hop173
    @hop173 Před 2 lety

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

  • @nouchance
    @nouchance Před 2 lety

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

  • @user-ry7ci3op9k
    @user-ry7ci3op9k Před 2 lety

    Спасибо!

  • @Ksushadik
    @Ksushadik Před 11 měsíci

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

  • @Misha1300
    @Misha1300 Před rokem

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

    • @Misha1300
      @Misha1300 Před rokem

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

    • @ArtsiomAuhustsinovich
      @ArtsiomAuhustsinovich Před rokem

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

    • @Misha1300
      @Misha1300 Před rokem

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

  • @muxa000
    @muxa000 Před rokem +1

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

  • @asyncawait2839
    @asyncawait2839 Před 2 lety

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

    • @AndreyShyrokoriadov
      @AndreyShyrokoriadov  Před 2 lety

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

  • @kozhevnikov1986
    @kozhevnikov1986 Před 3 lety

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

    • @AndreyShyrokoriadov
      @AndreyShyrokoriadov  Před 3 lety

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

  • @kozhevnikov1986
    @kozhevnikov1986 Před 3 lety

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

    • @kozhevnikov1986
      @kozhevnikov1986 Před 3 lety

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

    • @AndreyShyrokoriadov
      @AndreyShyrokoriadov  Před 3 lety +2

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

  • @JohnDoe-uu5jy
    @JohnDoe-uu5jy Před 3 lety

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

    • @AndreyShyrokoriadov
      @AndreyShyrokoriadov  Před 3 lety

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

    • @JohnDoe-uu5jy
      @JohnDoe-uu5jy Před 3 lety

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

    • @AndreyShyrokoriadov
      @AndreyShyrokoriadov  Před 3 lety +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 Před 3 lety

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

    • @JohnDoe-uu5jy
      @JohnDoe-uu5jy Před 3 lety

      Можно попробовать для проверки сделать так:
      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 Před 3 lety

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