Расшифровка типов питания в отелях
«А ты путешественник, что ли? А ну-ка, скажи что-нибудь по-гостиничному». Отельный язык напоминает позывные секретных агентов из шпионских саг: куча сокращений и аббревиатур, в которых скрывается сакральный смысл — в каких условиях ты проведёшь свой долгожданный отпуск. Чтобы не провалить операцию «Отдых», лови расшифровки типов питания.
Содержание
RO означает «room only». Расшифровка исчерпывающая: ты бронируешь только номер, питание в стоимость проживания не входит. Этот тип питания распространён в отелях, хостелах и на виллах. Такой вариант идеально подойдёт тем, кто не хочет привязываться к расписанию завтраков-обедов-ужинов. Ты можешь как угодно планировать свой день в поездке, не боясь пропустить уже оплаченную трапезу. А еду приготовишь на кухне или отведаешь все прелести местной кухни в ресторанах и кафе.
ВВ (он же «bed & breakfast» — постель и завтрак) — самый частый тип питания в отелях. В стоимость номера будет включён завтрак. Есть два распространённых формата — «шведский стол» и континентальный завтрак.
ВВ идеально подойдёт для тех, кто не в духе по утрам: не нужно заморачиваться с готовкой или выбором кафе, всё сервируют и уберут, тебе остаётся только хорошо кушать (почти как у бабушки).
Под аббревиатурой HB (он же «half board») скрывается полупансион — тип питания, в который входят завтрак и ужин. В завтраки, как правило, включены напитки (чай, кофе, сок, вода), а вот в ужины — нет. Напитки будут стоить в несколько раз дороже, нежели точно такие же в магазине. Однако такой тип питания очень удобен для семей с детьми и людей, соблюдающих режим питания. Об утренней и вечерней трапезе беспокоиться не придётся — всё будет строго по часам, а пообедать можно будет во время прогулки в городе.
Аббревиатурой FB (Full Board) обозначается трёхразовое питание — завтрак, обед и ужин. Этот тип питания подойдёт тем, кому нужен размеренный санаторный отдых без лишних передвижений. Как и в HB, в Full Board напитки входят только в завтрак. На обед и на ужин они могут подаваться за отдельную плату.
HB+ и FB+
В некоторых отелях встречается разновидность полупансиона HB+ и полного пансиона FB+. В этих типах питания включены бесплатные напитки во время всех приёмов пищи. Ассортимент и количество на одного гостя зависят от отеля.
С системой AI (All inclusive, или «всё включено») знакомы те, кто хоть раз бронировал отель в Турции. All inclusive включает трёхразовое питание, напитки и даже алкоголь местного производства. Такой тип питания предлагается в резорт-отелях, которые напоминают город в городе. У них есть собственная инфраструктура: бассейны, пляж, рестораны, бары и кафе на территории, фитнес-клубы, магазины и многое другое — словом, тут есть всё, чтобы вдоволь «потюленить» и лишний раз не выходить за пределы отеля. Такой тип питания подойдёт хронически усталым путешественникам, которым хочется устроить торжество лени, а также семьям с детьми, чтобы маленьким путешественникам в любой момент можно было чем-то подкрепиться.
UAI (Ultra All inclusive) представляет собой расширенный AI. Помимо трёхразового питания и местных напитков, ты сможешь отведать и напитки импортного производства, как алкогольные, так и без-.
Позывные получены. Мы за тебя спокойны, теперь точно не провалишь явку и выберешь отель с нужным типом питания. Мечтай, бронируй, отдыхай.
Модные словечки, которые сейчас очень популярны у детей. Сможете сказать, что они обозначают?
Наши дети порой странно выражаются. С нами они обычно не перекидываются такими словами и выражениям. А вот со своими сверстниками да! Давайте разберемся, что же они обозначают, чтобы быть в теме. Слов достаточно много. Но запомнить их не составит нам труда. Зато будем в тренде) и станем современными родителями)
Краш
Обозначает человека, в которого вы влюбились, по которому вы прямо «тащитесь». Очевидно, оно пришло от английского сrush (давить, сокрушать). При чем тут чувство симпатии к человеку? Хороший вопрос! Вероятно, когда-то в словосочетание fall in love (влюбиться) вместо слова fall (падать) вставили crush, чтобы таким образом подчеркнуть неподконтрольность и фатальность этого чувства. Выходит, «краш» — это не просто какая-то там влюбленность, а необъяснимая и внезапная. Прямого аналога в русском языке нет, так что приходится брать из английского. Есть и вариант-феминитив: крашиха. Ну а что? В духе времени!
Мой краш — Вадим из 9 “Б”. Только ему на меня пофиг.
Трушно
Это обозначает быть трушным. То есть правдивым, честным.
Буть уже в этой ситуации трушным.
Кринж
Еще одно словечко из английского (забежим вперед: как и почти все из списка). Сringe переводится как «съеживаться» и обозначает чувство стыда. Спросите, зачем же еще одно слово, если уже есть «стыд»? Ну, это не совсем оно. Кринж — это некая смесь между неловкостью и стыдом. Скорее всего, когда вы пытаетесь понять подростковую моду, вы ведете себя именно кринжово. В глазах своего ребенка, естественно. Ведь попытки взрослых прикинуться молодежью всегда ровно такие: немножко стыдные и неловкие. Аж съеживаешься.
Вчера моя мама пыталась включить видео-чат в Viber, господи, это был такой кринж.
Рофл Рофл
Это ROFL, записанный кириллицей. Набор букв получается из выражения Rolling On Floor Laughing, что означает очень сильно смеяться. Но слово «рофл» на глагол похоже слабо, так что превратилось во что-то вроде междометия. Типа как «лол». Это вы знаете же? Рофлом может быть какая-нибудь шутка. В общем-то, это почти синонимы. Но есть употребление посложнее: в некоторых случаях «рофлить» означает как бы издеваться, но не зло, а с юмором.
Пранк
Пранк — это тоже шутка, но скорее отдающая розыгрышем. То есть смешная фраза — это еще не пранк, а вот какое-то действие, после которого всем смешно. Как правило, в этом тоже есть некий элемент издевки: человек, над которым пранкуют, должен поначалу не понимать, что к чему. И только потом посмеяться. Короче говоря, Валдис Пельш в программе «Розыгрыш» занимался не чем иным, как пранковал. Еще до того, как это слово вошло в обиход русскоязычной молодежи.
Поставить в пятницу шесть уроков — уже просто пранк, который зашел слишком далеко.
Имбовый
«Имбовый» — это значит крутой. На фоне остальных, конечно же. Вообще, это пошло из онлайн игр, где имбовым называли какой-то элемент или предмет, делающей игру для его обладателя очень легкой и выигрышной.
Эта шмотка имбовая, если она у противника — игра слита.
Задонатить
Изначально «задонатить» означает «пожертвовать». Допустим, перевести 20 рублей на покупку СИЗов для врачей — это ваш донат. Но слово также стали использовать в компьютерных играх — его можно услышать в отношении покупок в игре. Если вы переводите реальные деньги в игровые, чтобы покупать какие-то штучки (клады, сундуки, оружие), то это тоже донаты. Не удивляйтесь, если услышите.
Задонатил за выходные 100 рублей на игры, мне капец.
Читы
Иначе говоря, коды к компьютерной игре, благодаря которым игрок получает какие-то бонусы. Это слово перешло из мира игр в обычную жизнь: списал домашку — читер, протер пыль только на нижних полках — читер. Короче говоря, обманщик, который ищет лучшей жизни простым путем.
Ты что, списала всю контрольную со шпоры? Ну и читер!
Чилить
Попросту говоря, отдыхать. Но если у старшего поколения отдых может подразумевать прополку грядок на протяжении нескольких часов, а у активных людей — сноуборд и водные лыжи, то у тех, кто использует слово «чилить» совсем другие понятия. Чилл — это расслабленный отдых, который подразумевает почти полное ничегонеделание. Лежать на пляже — чилл, не вставать с кровати весь день — чилл, сидеть в машине, чтобы воздух из окна обдувал — чилл.
Вчера весь день чилили с ребятами на Минском.
Чекать
Глагол to сheck в английском означает «проверить». Можно чекнуть, что задали по математике, или чекнуть, выложили ли новый видос на YouTube. Суть в том, что это делается ради уточнения какого-то факта.
Сейчас я чекну, что по погоде, и скажу, пойду или нет.
Чекиниться
Тоже слово, связанное с check. Зачекиниться — это значит отметиться, что вы были в каком-либо месте, обычно так говорят о заведениях общепита. Но просто сходить недостаточно: чек-ин, как правило, подразумевает отметку в соцсетях. Это ж современный мир — иначе не считается.
Нет, туда не хочу идти — там уже вчера зачекинились.
Олды
Слово придумано на базе английского old (старый), только в русском языке из него сделали существительное. Олдами называют всех людей, которые старше говорящего. Так что не обижайтесь, если услышите, что вы олд. 17-летний может вполне назвать олдом 19-летнего.
Говоришь прямо как олд, жесть.
Пипяо
Слово придумано, чтобы можно было не использовать подцензурный «п. ц». Конечно, у него есть более приличные варианты, сильно похожие на «капец». Но это для олдов. Вот «пипяо» — куда более непонятно со стороны.
Этот молодежный сленг — полный пипяо!
Еще одно странное словечко, как и пипяо. Если кто-то говорит «ауф», значит, он получил от этого удовольствие или что-то его сильно восхитило. Другой вариант употребления — после сомнительной современной пословицы, которые тоннами рождаются в соцсетях. Тогда «ауф» в конце как бы намекает на несерьезность вышесказанного и прикол.
Тот пацан просто ауф!
Хайп
Более употребительное слово среди олдов, но тем не менее вопросы вызывает. Хайп — это попросту говоря ажиотаж. В некоторых случаях — созданный искусственно. Кстати, нам нередко пишут читатели с претензиями, что мы написали что-то, чтобы «хайпануть», то есть сделать популярную новость из ничего. Что ж. Хайп может быть по фильму, по человеку, из-за новости и так далее.
Ну и хайп поднялся после «Хищных птиц» — вся лента в этом.
Орать
Нет-нет, это не то же самое, что кричать. Орать — это значит «очень сильно смеяться», но не только. В прямом смысле никто не орет (да и смеется тоже). Обычно так пишут, чтобы подчеркнуть, какие сильные эмоции вызывает нечто. Настолько, что уже непонятно: то ли смеяться, то ли плакать. Остается просто орать.
Ты видел, чем кончился сериал? Я просто ору!
Жиза
Здесь все просто: это сокращенный вариант наречия «жизненно». Идеальный вариант, чтобы проявить сочувствие — просто скажите, что озвученная проблема для вас «жиза». И сразу станете своим в доску.
Слышала, что вчера Катя говорила? Такая жиза, не могу.
Токсик
Быть токсичным — значит, своими действиями разрушать веру в себя других людей и делать их существование некомфортным. Например, отпускать шуточки на тему чьих-то прыщей — это токсично, потому что как бы человек сам ни шутил на эту тему, наверняка он переживает. Ну, а «токсик» как человек — это, собственно, тот, кто ведет себя таким образом.
Наш препод — настоящий токсик. Как с ним учились раньше?
Войсить
Voice (читается как «войс») — с английского переводится как «голос». Соответственно, глагол «войсить» используется вместо «записывать голосовое сообщение». Очень длинно ведь, правда? Даже «записать голосовуху» не так емко выглядит. Поэтому если кто-то войсит, не переживайте: человек просто общается в соцсетях.
Это он не тебе, он просто войсит.
Зашквар
Зашкваром называют что-то позорное и неприятное. Причем это может быть все что угодно: от похода в театр до пранка на перемене между уроками. Если что-то зашкварное, значит, оно позорное, если кто-то зашкварился — значит, опозорился. Правда, у зашквара, пожалуй, не такой оглушительный шлейф, как у позора. Чуть получше.
Он, конечно, зашкварился, когда надел эту майку на тусовку.
Бомбить
Как у меня бомбило от того, что мне мать сказала, вы бы видели.
Оффники
Это околофутбольный термин, которым называют парней «на спортивках». Они увлекаются всякими странными вещами вроде договорных драк, фанатеют от спорта и так далее. Поскольку в Беларуси такое движение не слишком и развито, то оффниками часто называют просто парней в спортивной одежде.
Оффники уже достали меня дергать, когда они уже отстанут?
Рил ток / инфа сотка
Фразы, похожие по своей сути. Обе они означают «точно говорю», «уверен на 100%». Первая пошла от английского «real talk» («серьезный разговор»), вторая — сокращенный вариант «информация на 100% достоверная».
Да там будет легко списать, рил ток просто. Инфа сотка — спрашивал у «А» класса.
Флекс
По-моему, он просто флексер.
Вписка
Если у автостоперов вписка — это временный ночлег, то у городской молодежи вписка — это тусовка у кого-то дома. В общем-то в обоих случаях сленговое слово родилось из глагола «вписаться [к кому-то в квартиру]». Кстати, еще буквально лет 10 назад вместо вписки в ходу был флэт. Как быстро летит время! Впрочем, так говорят и сейчас тоже. Но это более олдово.
Если пойдешь на вписку, возьми с собой еду.
Запилить
То же самое, что «сделать что-нибудь». Универсальное слово, потому что заменяет собой другие глаголы. Починить, сделать, составить, выложить, загрузить, снять — вместо всего этого можно сказать просто «запили». Вероятно, такое употребление слова «запили» вызвано популярным вирусным роликом, где употреблялась фраза «дверь мне запили». Почини то есть.
Давай запилим фотки в необычном стиле.
Лойс
Это то же самое, что и лайк. О происхождении этой формы можно только догадываться. Вероятно, кто-то просто сделал опечатку в слове like — и пошло-поехало.
Он ставит мне лойсы уже неделю, но так и не пишет. Что за фигня?
Стэнить
Стэнить — это быть поклонником определенной группы или музыканта, но по отношению к кино тоже употребляется. Вообще, слово не новое и пошло из песни Stan Эминема и Дайдо, которая (на секундочку) была выпущена в 2000 году. В треке есть строчка «Искренне твой, твой самый страстный поклонник, Стэн». Видимо, поэтому имя и стало нарицательным в таком значении.
Как можно не стэнить Тимоти Шаламе… Он же просто лапочка!
Вайб
Вайб — это приятные ощущения, которые можно почувствовать подсознательно. Можно сказать, в некотором смысле синоним этого слова — атмосфера. То есть приятный вайб по сути то же, что приятная атмосфера.
У этого кафе приятный вайб, сюда хочется ходить.
Форсить
Означает что-то вроде «продвигать», «делать популярным». Как вы понимаете, несколько насильственным путем — в этом и смысл продвижения. Слово можно употреблять в переносном смысле. Если кто-то часто упоминает какого-то конкретного человека, идею или продукт, можно с уверенностью предъявить претензию: «Да что ты форсишь это? Успокойся уже».
Она так форсила новые шоколадки с мармеладками, что все их стали есть.
Вот еще несколько англоязычных словечек, которые имеют простой аналог в русском:
Агриться = злиться. Пример: Не агрись на меня, я с тобой спокойно разговариваю.
Фейк = недостоверная информация, обман. Пример: Опять в вайбере фейк про бананы и коронавирус запустили?
Трабл = проблема. Пример: У меня траблы с учителем химии, он занижает оценки.
Крипово = страшно, жутко. Пример: Когда ты внезапно выскочила из темноты, было крипово.
Пруф = доказательство. Пример: Пока не дашь пруфы, не поверю, что Таня встречается с Димой.
Фиксить = исправлять. Пример: Блин, накосячил, когда переписывал сочинение в чистовик, сейчас пофикшу.
Таргет (может быть также тарджет) = цель. Пример: Мой таргет — бегать хотя бы по 20 километров в неделю.
Скилл = навык. Пример: Из скиллов у меня — только язык в трубочку могу скручивать.
Ливнуть = уйти. Пример: Он ливнул из чата, как только мы заговорили о его семье.
Шеймить = стыдить. Пример: Хватит шеймить людей за лишний вес, это бесит.
Юзать = использовать. Пример: Это видео можно юзать в презентации для универа.
Гамать = играть. Пример: Я гамаю только в CS.
Рандомный = случайный. Пример: Там варианты рандомно раздают, не поймешь, как сесть, чтобы один получить.
Изи = легко. Пример: Домашка по русскому? Да там изи.
Хард = сложно. Пример: Мой вариант ЦТ какой-то хардовый попался.
Нуб = новичок. Пример: Он в этой теме полный нуб.
Забайтить = спровоцировать. Пример: Подруга забайтила меня на репост конкурса.
Апнуться = повысить [уровень]. Пример: Наконец-то апнулся в игре, очень сложный левел (уровень).
Ну теперь мы все все понимаем, о чем разговаривают наши дети))
Не «типо», а «типа». Разберёмся почему
Хотя я весьма лояльно отношусь к современным морфологическим трансформациям в русском языке и охотно пользуюсь сленгом, но некоторые вещи режут ‘слух’. Они не относятся ни к виртуозной трансформации, ни к современным тенденциям, трансформации, а к банальной неграмотности. Я не стал усложнять, объясняя своими словами, а просто нашел доступную статью в интернете и решил поделиться.
Лингвист-морфолог, эксперт института филологии, массовой информации и психологии Новосибирского государственного педагогического университета рассказывает:
Рекордсменом по загадочности среди часто употребляемых слов можно назвать типо — «фантом» слова типа. Фантом, потому что такого слова не существует, что, однако же, не мешает носителям языка активно его использовать.
Разберемся, что такое типа и в каких контекстах мы используем это слово.
Известно, что словам русского языка свойственна морфологическая «миграция» и частеречная подвижность. Например, слово столовая — бывшее прилагательное (столовая комната), «поменявшее профессию»: оно стало существительным. В науке этот процесс называют субстантивацией (если мы говорим именно о переходе в существительное), а в общем смысле — переходом из одной части речи в другую. Мороженое, рядовой — тоже примеры такого грамматического перевоплощения. А вот слово благодаря — деепричастие-оборотень: становится предлогом. Сравните: Он обнял меня, благодаря за помощь; благодаря моей помощи он смог получить работу.
Так, числительные становятся прилагательными, деепричастия наречиями и предлогами, а местоимения частицами. Это явление частотно для нашей языковой системы и настолько важно для понимания грамматики, что теперь учителя начинают говорить о нем уже в начальной школе, несмотря на сложность.
Слово »типа« тоже затронуто таким переходом. Но и не только! Поэтому являет собой уникальный случай. Типа — это частица, а также междометие (в зависимости от функции в контексте). А сформировалась эта частица/междометие по-особенному — произошла из застывшего в форме родительного падежа существительного тип в значении ‘форма, вид чего-нибудь, обладающие определёнными признаками, а также образец, которому соответствует известная группа предметов, явлений’. В прямом значении, родственном своему происхождению, мы наблюдаем слово типа в таком контексте: «Я хочу купить платье типа такого», то есть «примерно такое платье», «платье такого типа». «Получается, ты спортсмен? — Да, типа того», то есть «вроде того», «не то чтобы спортсмен, но похоже на то». Поскольку слово типа с таким наполнением на определенном этапе своего существования было чрезвычайно востребованным для носителей языка, вскоре оно совершило переход к междометию и даже вводному (модальному) слову. Обратите внимание, каким мог быть путь этой эволюции: «Я к ней подошел и говорю типа…», то есть «говорю нечто вроде того». Вероятно, в какой-то момент слово просто поменяло место, что и привело его к новой функции: «Я к ней подошел типа и говорю…», «я к ней типа подошел и говорю…».
Возможно, что функции междометия у типа закрепились под влиянием английских «братьев» like и you know с таким же назначением. В определенный момент популярность и частотность типа в качестве междометия привела к новому витку эволюции (но многие носители языка считают это деградацией): «Я типа к ней подошел и типа говорю, типа…». Как мы видим, здесь слово практически полностью теряет значение и выступает в качестве слова-паразита.
Что касается «фантома» типо (даже более популярного чем существующее типа), здесь мы имеем дело с «ложной грамотностью». Носитель языка ощущает, что слово с такой ролью будто бы не должно иметь окончания а. Причина возникновения такого окончания непонятна (кто же догадается, что это застывший родительный?), да и совсем не анализируется. Зато создается впечатление, будто у слова типа есть наречная природа. Вот поэтому и хочется его отнести к быстро, скоро, налево, намертво. Так, вариант типо представляется грамотным и правильным, хотя это не так.
Каждый говорящий имеет право решать, как и в каких случаях использовать такой большой потенциал слова типа — употреблять его в качестве междометия, вводного слова, частицы, слова-паразита. Но главное помнить, что даже будучи словом-паразитом, слово типа — правильное, а типо — ошибка.
Популярные заблуждения о C#
Эта статья является развёрнутым комментарием к другой статье. Обычно я прохожу мимо, но сейчас меня почему-то задело.
Та статья представляла из себя практически «идеальную подборку заблуждений в вакууме». Причём они (заблуждения) являются довольно популярными и постоянно встречаются в различных блогах и подборках «99 вопросов для собеседования», «как пройти собеседование на джуниора» или в данном случае «шпаргалка по C#».
Почему они такие популярные? Я считаю, что потому, что они дают простые и короткие ответы, которые очень удобны для формата теста или квиза. Думать не надо, можно просто запомнить. Практикующие же разработчики повторяют их потому что эти заблуждения часто описывают наблюдаемое положение дел, но это не значит, что они истинны. Если посмотреть в окно в центре города, то можно сделать вывод что все машины — легковые, и это в большинстве случаев будет верно, но к правде имеет довольно слабое отношение.
Мне хочется, чтобы данная статья была не чисто моим мнением и не очередной компиляцией блогов. Поэтому я проведу аналогию (весьма сомнительную, но мне так захотелось) с юриспруденцией. У нас будет так:
Законопроекты — информация о версиях языка новее, чем в ECMA 334, а также ещё не выпущенных версиях. Эту информацию можно найти на гитхабе dotnet, а так же в статьях-анонсах на MSDN.
Подзаконные акты — документация (не статьи) MSDN.
Опыт законоприменения — статьи MSDN, Wikipedia и на других сайтах, информация не абсолютная, требует проверки.
Прямой опыт — то, что мы можем просто взять и проверить. Тут нам повезло больше, чем юристам, ведь нам не придётся что-то красть, чтобы проверить на сколько лет за это посадят ))
Не долго думая, возьмём план статьи отсюда и будем рассматривать мифы по списку. Если что-то забуду, добавляйте в комментах.
Ссылочные и значимые типы (value vs reference types)
Заблуждение: ссылочные типы (reference type) хранятся в куче (heap), а значимые (value types) — на стэке.
Почему распространено? Это — простое объяснение, и оно часто тиражируется. Более того, если написать простой метод с простыми переменными одного и другого типа, чем обычно его и иллюстрируют, то всё именно так и будет.
Закон: во всём стандарте есть только 2 упоминания слова «куча», и это вполне объяснимо, поскольку стэк и куча являются деталями реализации, а не самого языка. Второе упоминание — про то, что зафиксированные (fixed) объекты могут приводить к фрагментации кучи, это нам пока не интересно. А первое упоминание — в разделе 16.1 Structs/General, то есть общем описании, а не определении:
However, unlike classes, structs are value types and do not require heap allocation
Это означает только то, что структуры не требуют выделения на куче (но не означает что они располагаются на стэке).
Опыт: действительно, значимые типы, являющиеся локальными переменными в текущей реализации скорее всего окажутся на стэке. Но если мы создадим класс, членом которого является структура, то она, как и все остальные данные этого класса окажется в куче.
Для классов (ссылочных типов) на текущий момент действительно верно, что во всех простых случаях они окажутся размещёнными в куче. Но ссылочный тип чисто теоретически можно разместить на стэке. Более того, скоро это изменится вполне официально, так же спасибо @VladD-exrabbit за вот эту ссылку: https://github.com/dotnet/runtime/issues/11192
P.S.: ещё спасибо @PsyHaSTe за ссылки: один, два, три. «Как можно видеть, Липперта эти сравнения бесили ещё в 2009. »
Так чем же отличаются value и reference типы?
Читаем стандарт (в нём всё про значимые типы лежит в разделе Structs и слово struct используется для их описания):
— A variable of a struct type directly contains the data of the struct, whereas a variable of a class type contains a reference to an object that contains the data…
Тут текст про то, что структуры содержат в себе сами данные, а переменная со ссылочным типом — только ссылку. А значит структура не может в себе содержать поля, размер которых ещё не известен (в том числе своего же типа):
With classes, it is possible for two variables to reference the same object…
Переменные ссылочного типа могут (но не обязаны) указывать на один и тот же объект, а каждая значимая переменная содержит свою копию данных.
Это всё, что описано в разделе про семантику, а для языка это самое главное. Дальше идёт описание конкретно структур (16.4.3 Inheritance) а также свойства, вытекающие из семантики (16.4.4 Assignment — копирование данных при присваивании), 16.4.5 Default values — значение по умолчанию, 16.4.6 Boxing and unboxing — если нам надо передать ссылку, то требуется боксинг. А так же конструкции языка 16.4.7 Meaning of this, 16.4.8 Field initializers, 16.4.9 Constructors, 16.4.10 Static constructors, 16.4.11 Automatically implemented properties.
На собеседовании на вопрос о различии этих типов главное ответить, что у них разная семантика. Можно, конечно, погрузиться в дальнейшие различия (по списку из стандарта), но нигде среди них нет упоминания, что одно — это то, что идёт на стэк, а другое — в кучу.
stack vs heap
Заблуждение (1): стэк быстрый, а куча большая.
Почему? Потому что мелкие локальные переменные, такие как числа, обычно располагаются на стэке, а жирные объекты размещают в куче. Очевидно, что с мелкими объектами, которые известно где лежат, работать проще и быстрее. Но это скорее следствие, чем причина.
Закон: слово heap мы уже искали в стандарте и ничего серьёзного не нашли. Слово stack в основном встречается в параграфах про unsafe-блоки и stackalloc, но мы сейчас не про это.
Факт: размещать данные на куче действительно сложнее (нужно пройти через аллокатор памяти), а на стэке — быстрее (делать ничего не надо, уже известно где и сколько памяти мы используем). Но дальнейший доступ будет аналогичен (если и то и другое мы будем трогать одинаковым способом, например по ссылке) и скорость доступа будет зависеть только от эффектов локальности данных в кэше, но это уже не вопрос языка, а физической машины.
Размер стэка можно поменять для всего бинарника с помощью EDITBIN.EXE /STACK: file.exe
А для каждого отдельного потока — через второй аргумент конструктора new Thread().
По умолчанию, куча действительно больше стэка, но стэк можно увеличить, а куча, хоть и растёт по мере надобности, но не безгранична. Есть куча правил, по которым определяется её размер, так же её можно уменьшить в настройках. Иногда доступная куча оказывается меньше физически доступной памяти Тогда приходится расчехлять unsafe и делать offheap-аллокации.
Вывод: размер и того и другого определяются машиной и рантаймом, но не является определяющим признаком.
Передача по значению / указателю
Заблуждение: значимые типы (структуры) передаются по значению а ссылочные (классы) — по ссылке.
Почему оно популярно? Честно — не знаю. Возможно из курсов Си для начинающих.
Закон:
10.2.5 Value parameters
A parameter declared without a ref or out modifier is a value parameter.
10.2.6 Reference parameters
A parameter declared with a ref modifier is a reference parameter.
10.2.7 Output parameters
A parameter declared with an out modifier is an output parameter.
Думаю, тут всё понятно. То, как передаётся объект, определяется не его типом (ссылочный/значимый) а тем, как объявлен и передан аргумент функции. Добавляется ещё странная вещь под названием Output parameter со своей семантикой, но в реализации это такой же ref-параметр, только требующий инициализации в вызываемом методе. На этом дискуссию можно было бы закончить, но давайте немного займёмся сравнительным языкознанием.
Для сравнения я возьму Java 8-летней давности (в последний раз что-то значимое на джаве я писал примерно тогда, а с тех пор могло что-то поменяться), С++ (а не C, потому что иначе я сам запутаюсь) и C#. Я хотел тут повторить анализ целиком, но просто приведу ссылки: Java, C++, C#.
Краткий пересказ: в Java передача только по значению, но есть ссылочные типы и примитивы (это не совсем значимые типы как в C#, но для сравнения сойдёт) В C++ все типы — значимые, но можно передавать как по значению так и по ссылке (и ещё по указателю/адресу). А в C# сочетаются обе эти семантики: можно взять значимый или ссылочный тип и передать любой из них по ссылке или по значению. Это ортогональные понятия и не надо их смешивать.
P.S.: в новых версиях языка появились in-параметры. С семантической точки зрения они не определяют способ передачи (ведь при запрете изменения объекта нет никакой разницы, как он был передан), но с точки зрения реализации они работают как неизменяемые ref-параметры (readonly ref) и соответственно тоже передаются по ссылке.
P.P.S.: с out-параметрами тоже не всё так просто. Вот в этой статье есть подробный разбор: https://m.habr.com/ru/company/pvs-studio/blog/542210/, рекомендую к прочтению.
string — особенный тип
Заблуждение: ведёт себя как значимый тип, а лежит в куче.
Закон:
9.2.5 The string type
The string type is a sealed class type that inherits directly from object. Instances of the string class represent Unicode character strings.
Values of the string type can be written as string literals (§7.4.5.6).
The keyword string is simply an alias for the predefined class System.String
Как видим, не такой уж он и особенный.
Опыт: ну да, как и все другие классы (ссылочные типы) строки обычно размещаются в куче. Почему говорят, что он ведёт себя как значимый тип? Я много раз такое слышал, но так и не получил чёткого ответа, почему.
Про какие особенности речь?
1. Это неизменяемый (immutable) и запечатанный (sealed) класс. Это значит, что обычными способами нельзя изменить внутри него данные и нельзя от него унаследоваться. Ну и что? Вы можете создавать классы с такими же ограничениями, ничего особенного.
2. Можно сравнивать с помощью оператора==, а обычные структуры нельзя, и для голых классов сравнивается инстанс, но не данные. Ну и что? Для любого своего класса или структуры вы можете написать такой же оператор и они будут вести себя абсолютно так же.
Более того, иммутабельность строк можно нарушить с помощью небольшой щепотки магии. И да, это уже было на хабре.
const vs readonly
Заблуждение:
Закон:
12.20 Constant expressions
A constant expression is an expression that shall be fully evaluated at compile-time
Не «установить значение», а «значение вычисляется» (это тонкое, но важное различие).
15.5.3.1 General When a field-declaration includes a readonly modifier, the fields introduced by the declaration are readonly fields. Direct assignments to readonly fields can only occur as part of that declaration or in an instance constructor or static constructor in the same class.
Да, вроде бы похоже. Но почему они в разных разделах (12 и 15)? Давайте посмотрим на название: одно — это выражение, а другое — модификатор поля. И это главное их семантическое отличие.
Отсюда вытекает важная деталь реализации:
15.5.3.3 Versioning of constants and static readonly fields
Constants and readonly fields have different binary versioning semantics. When an expression references a constant, the value of the constant is obtained at compile-time, but when an expression references a readonly field, the value of the field is not obtained until run-time.
Значение константы фиксируется на момент компиляции. А статических readonly-полей (которые часто используют как замену) — на этапе выполнения. Если одна сборка зависит от другой, и берёт из неё константы и ридонли-поля, то при их изменении в первой сборке, константы во второй останутся старыми, а readonly-поля подцепятся свежие.
Факт: соберите тестовый проект, и откройте его в декомпиляторе. Вы увидите, что вместо констант встанут их значения (поэтому они и являются выражениями), а для readonly-полей останутся на них ссылки.
ref и out
Из статьи-«шпаргалки»: ref и out позволяют внутри метода использовать new и для class и для struct
Факт: см выше (Передача по указателю)
out тоже что ref, только говорит о том что, метод обязательно пересоздаст переменную
Тут, наверное, имелось в виду «переназначит», а не пересоздаст, но сильно придираться не будем.
События, делегаты
Заблуждение:
Закон: 15.8.2 Field-like events
Надеюсь, разницу, объяснять не надо.
P.S.: в новом C# можно не задумываться и писать Evt?.Invoke(«hello»);
Finalizer (destructor)
Заблуждение (1):
Foo() это «деструктор» класса Foo
Почему? Потому что по той или иной причине сами авторы языка так это называли, хотя вовремя одумались.
Закон:
15.13 Finalizers
[Note: In an earlier version of this standard, what is now referred to as a «finalizer» was called a
«destructor». Experience has shown that the term «destructor» caused confusion and often resulted to incorrect expectations, especially to programmers knowing C++. In C++, a destructor is called in a determinate manner, whereas, in C#, a finalizer is not. To get determinate behavior from C#, one should use Dispose. end note]
Причина: деструкторы и финализаторы отличаются семантикой, главное отличие — детерминированность.
P.S.: в комментах появилась хорошая историческая справка, спасибо @rstm-sf.
Заблуждение (2): вызывается, когда garbage collector доберется до объекта
Почему популярно? В большинстве простых случаев это действительно именно так и происходит.
Закон:
An instance becomes eligible for finalization when it is no longer possible for any code to use that instance. Execution of the finalizer for the instance may occur at any time after the instance becomes eligible for finalization (§8.9).
Обращаем внимание, что никаких гарантий нам тут не предоставляют.
Факт: финализатор будет вызван у объекта, если он у него есть и объект не побывал в методе SuppressFinalize до начала маркировки объектов на финализацию. Где-то между моментом определения что объект недоступен до момента фактического освобождения памяти. Но это не точно. Отменить финализацию можно с помощью метода GC.SuppressFinalize, хотя это может и не сработать. Более того, рекомендованный шаблон реализации IDisposable именно так и поступает.
Факт: действительно, специального синтаксиса для этого нет. Но можно, как обычно, залезть туда через рефлекшен:
Конечно, для симуляции корректного поведения следует пройтись по всей цепочке наследования (ведь так написано в стандарте).
Singleton
Заблуждение: не забудьте про потокобезопасность и lock
Почему? Потому что часто синглтон смешивают с ленивой инициализацией, хотя это два разных паттерна, которые могут встретиться независимо друг от друга.
В стандарте очевидно ничего такого нет, так что будем опираться на здравый смысл.
Раньше собеседующий ждал тут что-то типа такого кода:
Это известный паттерн double checked locking, он нужен для ленивой инициализации. А вопрос, напомню, стоял про синглтон.
Более того, этот код тоже имеет проблемы. Дело в том, что модель памяти работает не совсем так, как кажется на первый взгляд (это отдельная большая тема, явно не для собеседований уровня джун/миддл). Чтобы её решить, требуется или вставить volatile в нужном месте или аккуратно использовать MemoryBarrier().
Опыт: ничего из этого на самом деле не требуется для синглтона. Ведь рантайм нам даёт чёткие гарантии о потокобезопасности статических инициализаторов и мы просто можем написать:
Рантайм гарантирует, что это свойство будет потокобезопасно проинициализировано в какой-то момент начиная от запуска и до первого использования. Причём в текущей реализации это делается с достаточной степенью ленивости, так что для 99% случаев такой простой код будет самым безопасным и надёжным. Для любителей чуть большей ленивости есть решение со вложенным классом, но всё же не полной гарантией ленивости.
И, значит, для оставшегося 1% случаев, когда синглтону нужна гарантированная ленивость, мы можем написать:
И да, это тоже уже было на хабре, с кучей комментов.
P.S.: и так совпало, что сегодня же на хабре выложили вот такую подробную статью (18+)!
Вроде, по статье всё. Я явно что-то забыл, или написал неправильно, но для этого есть комменты, да будет срач!











