• Архив

    «   Май 2012   »
    Пн Вт Ср Чт Пт Сб Вс
      1 2 3 4 5 6
    7 8 9 10 11 12 13
    14 15 16 17 18 19 20
    21 22 23 24 25 26 27
    28 29 30 31      

Облако тегов


И небольшое продолжение: о паттернах и просветленном разуме

Небольшое дополнение к предыдущему сообщению о Head First Design Patterns.

Вся книга написана в полуразговорном стиле, с постоянными попытками пошутить (да, они не всегда смешны и уместны) и рассказать о паттернах максимально доступным языком. Иногда это звучит неоднозначно, но мысли заложены очень толковые:

Читать подробнее...

О паттернах из Head First Design Patterns

Я таки дочитал «Head First Design Patterns»!

В целом впечатление положительное, хотя после книги Мейера разница ощущается уж очень серьезная.

Читать подробнее...

Инициализаторы объектов в блоке using

Инициализаторы объектов (Object Initializers) – это полезная возможность языка C#, которая позволяет инициализировать необходимые свойства объекта прямо во время его создания. Поскольку синтаксически эта «фича» очень близка к инициализации объекта с передачей параметров через конструктор, многие разработчики начинают забивать на принципы ООП (в частности, на понятие инварианта) и использовать ее, где только можно.

Читать подробнее...

О публичных и опубликованных интерфейсах.

Мартин Фаулер - небезызвестный автор рефакторинга и всяких enterprise паттернов - начал постить свои старые посты. В целом это весьма интересная идея, поскольку интерес к посту привлекается лишь определенное время после его публикации, а затем этот интерес падает (хотя ценность материала остается той же самой).

Читать подробнее...

"Лестничное остроумие" (очередные интересные мысли из книги Бертрана Мейера)

Хотелось бы, конечно, полностью определить проблемы, прежде чем приступать к их решению: анализ завершать до проектирования, проектирование - до начала реализации, реализацию - до поставки. Однако что делать, если в процессе реализации разработчик внезапно понимает, что система может что-то делать лучше или вообще должна работать иначе? Отругать его за то, что занимается не своим делом? А если он действительно прав?

Читать подробнее...

О повторном использовании кода

Сегодня существуют разные мнения по поводу успешности объектной технологии. С одной стороны, большинство современных mainstream языков программирования являются объектно-ориентированными, с другой стороны, нередко можно услышать критику ООП, дескать, объектно-ориентированное программирование «провалилось» и не оправдало тех надежд, которые были возложены на нее индустрией разработки ПО. Все, мол, ожидали наступления вселенского счастья в виде увеличения повторного использования, упрощения сопровождения, да и вообще, обещали, что думать придется кому-то другому, а я за это буду деньги получать.

Читать подробнее...

Видеоматериалы, блоги и подкасты для .NET разработчика

Видеоматериалы

В одной из своих статей Бьёрн Страуструп (папа С++) признался, что он не признает видеоматериалы в качестве источника для самообразования. И с ним сложно не согласиться, когда речь касается изучения с нуля языка программирования или технологии. Я правда сомневаюсь, что можно одолеть такого монстра, как С++, или стать гуру WPF лежа на диване и просматривая обучающее видео типа «Узнай все за 24 часа». Но если вы ставите себе цель познакомиться с некоторой технологией или новой возможностью языка программирования, или просто послушать философско-компьютерные размышления умного товарища, то в этом случае веб-касты, записи конференций или другой вид видеоматериалов может быть очень кстати.

Читать подробнее...

Что значат для вас юнит-тесты?

С технической точки зрения юнит-тесты – это очень простой инструмент, основанный на паре несложных концепций: (1) тестируемый класс, (2) набор тестовых методов, завернутых в некоторый класс и (3) набор методов, с помощью которых можно удостовериться в том, что состояние тестового класса соответствует (или не соответствует) некоторому значению.

Читать подробнее...

Замыкание на переменных цикла в C# 5.0

Многие разработчики языков программирования, библиотек да и классов простых приложений стремятся к интуитивно понятному интерфейсу создаваемых классов. Скотт Мейерс еще полтора десятка лет назад сказал о том, чтобы мы стремились разрабатывать классы (библиотеки, языки), которые легко использовать правильно и сложно использовать неправильно.

Читать подробнее...

Бертран Мейер. Объектно-ориентированное конструирование программных систем


DISCLAIMER: более навороченной книги по ООП в природе нет и в ближайшее время, скорее всего, не будет; эта книга заслуженно считается классической книгой по объектной технологии и не зря является первой в списке рекомендуемых книг по этой теме (причем она первая не только в моем списке).

Читать подробнее...

15 возможностей ReSharper-а для навигации и редактирования

Инструменты – средство усиления вашего таланта. Чем они лучше и чем лучше вы ими владеете, тем больше вы сможете сделать.
Энди Хант и Дейв Томас «Программист-прагматик. Путь от подмастерья к мастеру»

Читать подробнее...

Наследование интерфейсов и контракты

В библиотеке Code Contracts, которая любезно предоставляет возможности контрактного программирования на платформе .NET, для задания предусловий и постусловий используются вызовы статических методов класса Contract. С одной стороны – это хорошо, поскольку альтернативная реализация на основе атрибутов была бы слишком ограниченной. С другой стороны – это добавляет определенные сложности, когда дело касается контрактов интерфейсов или абстрактных методов, которые по своей природе не содержат никакого кода, а значит и вызывать методы просто неоткуда.

Читать подробнее...

Альтернативная проверка предусловий в Code Contracts

При попытке использования библиотеки Code Contracts в реальном проекте может возникнуть небольшая сложность: хотя сам класс Contract с методами проверки предусловий и постусловий располагается в mscorlib, начиная с 4-й версии .NET Framework, но без установки самой библиотеки Code Contracts они не попадают в результирующую сборку.

Читать подробнее...

Принцип замещения Лисков и контракт

Идея этой заметки навеяна статьей Александра Бындю “Дополнение к LSP” и может рассматриваться, как развернутый комментарий к статье Александра.

Читать подробнее...

Повторное использование знаний

Уже не первый раз натыкаюсь на обсуждения вопросов о том, кто и как изучает новые технологии и о том, как справиться с тем огромным потоком «нововведений», которые ежегодно появляются в индустрии ПО. Однажды я уже отвечал на этот вопрос на кывт-е, и после очередного вопроса решил оформить эти мысли более структурированным образом.

Читать подробнее...

Об иерархиях наследования

Очередная интересная мысль от Бертрана Мейера, на этот раз касается она проектирования иерархий объектов:
Цитата
Произвольно или нет, но многие учебные презентации создают впечатление, что структуру наследования следует проектировать от наиболее общего (верхней ее части) к более специфическим частям (листьям). В частности, это происходит потому, что лучший способ описать существующую структуру – это идти от общего к частному, от фигур к замкнутым фигурам, затем к многоугольникам, прямоугольникам, квадратам. Но лучший способ описания структуры вовсе не означает, что он является и лучшим способом ее создания.

В идеальном мире, населенном совершенными людьми, мы бы сразу же обнаруживали правильные абстракции, выводили бы из них категории, их подкатегории и так далее. В реальном мире, однако, мы часто вначале обнаруживаем частный случай и лишь потом открываем общую абстракцию.

Читать подробнее...

Attached свойства для ограничения текстового ввода

WPF – это уже далеко не новая технология на рынке, но относительно новая для меня. И, как это часто бывает при изучении чего-то нового, появляется желание/необходимость в изобретении велосипедов с квадратными колесами и литыми дисками для решения некоторых типовых задач.
Одной из таких задач является ограничение ввода пользователем определенных данных. Например, мы хотим, чтобы в некоторое текстовое поле можно было вводить только целочисленные значения, а в другое – дату в определенном формате, а в третье – только числа с плавающей запятой. Конечно, окончательная валидация подобных значений все равно будет происходить во вью-моделях, но подобные ограничения на ввод делают пользовательский интерфейс более дружественным.

В Windows Forms эта задача решалась довольно легко, а когда в распоряжении был тот же TextBox от DevExpress со встроенной возможностью ограничения ввода с помощью регулярных выражений, то все было вообще просто. Примеров решения этой же задачи в WPF довольно много, большинство из которых сводится к одному из двух вариантов: использование наследника класса TextBox или добавление attached property с нужными ограничениями.

Читать подробнее...

18 фактов о Джоне Ските

Практически на каждом своем выступлении, будь то семинар или воркшоп, рано или поздно заходит речь об известных представителях .NET community, и одним из первых в этом списке идет Джон Скит (Jon Skeet), гуру stackoverflow.com и автор одной из самых интересных книг по языку C# - “C# in Depth”.

Чтобы рассказать о том, кто есть Джон и что он сделал для индустрии, достаточно привести о нем несколько фактов. Многие слышали факты о Чаке Норрисе, такие как «Чак Норрис досчитал до бесконечности. Дважды» или что «Чак Норрис – единственный человек, который обыграл стену в теннис». Но далеко не все знают о том, что подобные факты есть и о Джоне Ските (сам факт существования которых уже о многом говорит).

Читать подробнее...

Сказка о повторном использовании

Очередная цитата из книги Бертрана Мейера “Объектно-ориентированное конструирование программных систем”.

Читать подробнее...

Об изучении языков программирования

Очередное интересное высказывание, на этот раз найденное в последней книге Бертрана Мейера “Почувствуй класс”:
Цитата
Язык, который не влияет на ваш способ мышления, не стоит изучения.
   Алан Перлис

Читать подробнее...

Влияние психологии команды на архитектуру

Листаю замечательную книгу “Идеальная архитектура”, которая, по-сути, является сборником статей “архитектурной” тематики.

Читать подробнее...

The Art of Unit Testing

Есть некоторые категории знаний, которые профессиональный разработчик познает в процессе своей работы, не прилагая к этому особенных дополнительных усилий. Вот, например, мало кто из нас читал замечательную книгу по регулярным выражениям Джеффри Фирддла, чтобы познакомиться с одноименной темой. Безусловно, есть масса людей, для которых «регвыры» стали смыслом жизни и без подобных фундаментальных знаний никак не обойтись. Но в большинстве случаев пары мелких статей и справки в соответствующем разделе документации будет достаточно для более или менее комфортной работы с регулярными выражениями (если такое понятие, как «комфортная работа» с регулярными выражениями вообще существуетJ). Аналогичным образом мы обычно относимся и к изучению юнит тестирования. Ведь юнит-тесты – это же не rocket science; для их изучения не требуется многолетняя подготовка и множество бессонных ночей проведенных за изучением толстенных «талмудов» от гуру юнит-тестирования. Концепцию автоматизированного тестирования кода можно объяснить за 10 минут, а познакомившись с одним из тестовых фреймворков семейства xUnit (еще 15 минут), вы сможете работать с любым другим фреймворком практически сразу же. Затем нужно будет потратить еще 20 минут на изучение какого-нибудь изоляционного фреймворка, типа Rhino Mocks, и, вуаля, у нас есть еще один профессионал в области юнит-тестов.
  

Читать подробнее...

Ретроспектива 2011

Мы живем с вами в удивительное время, ежедневно занимаемся любимым делом, за которое, к тому же, еще и неплохо платят. Количество «новых» технологий растет, как на дрожжах, поэтому сейчас, как никогда раньше, важно уметь отфильтровывать важное от несущественного и понимать, в какие направления следует «инвестировать» свое время. Ведь на самом деле, все эти новые технологии - не что иное, как хорошо забытые старые; зачастую это лишь проверенные временем идеи, которые воплощаются в жизнь в новой форме.

Читать подробнее...

Стабы и моки

Существует категория классов, которые тестировать весьма просто. Если класс зависит только от примитивных типов данных и не имеет никаких связей с другими бизнес-сущностями, то достаточно создать экземпляр этого класса, «пнуть» его некоторым образом путем изменения свойства или вызова метода и проверить ожидаемое состояние.

Это самый простой и эффективный способ тестирования, и любой толковый дизайн отталкивается от подобных классов, которые являются «строительными блоками» нижнего уровня, на основе которых затем уже строятся более сложные абстракции. Но  классов, которые живут в такой «изоляции», немного по своей природе. Даже если мы по нормальному выделили всю логику по работе с базой данных (или сервисом) в отдельный класс (или набор классов), то рано или поздно появится кто-то, кто эти классы будет использовать для получения более высокоуровневого поведения, и этого «кого-то» тоже нужно будет тестировать.

Читать подробнее...

Кто такой «хороший программист»?

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

Читать подробнее...

Идеальная архитектура

Существует много разных взглядов на разработку архитектуры и дизайна современных приложений. Некоторые архитекторы стремятся продумать все до мелочей, разрисовать use case-ы всех классов и модулей, проанализировать миллион возможных способов их использования, все их обязательно задокументировать и уже потом приступить к этапу кодирования.

Другие, наоборот, считают, что «думать уже поздно» и давным-давно пора «делать», поэтому они кидаются на баррикады с криками «Ура», выдавая на гора тонны никому не нужного кода. Как и любая крайность, такой подход не приводит ни к чему хорошему. Но, как и во многих других случаях, существует промежуточный вариант, когда проектированию и архитектуре уделяется должное внимание, когда они не ставятся во главу угла, а используются для выявления правильных абстракций и поиска компромиссов в противоречивых требованиях заказчика.

Читать подробнее...

Observable.Generate и перечисление списков

В библиотеке реактивных расширений (a.k.a. Rx – Reactive Extensions) существует вспомогательный метод Observable.Generate, который позволяет генерировать простые observable-последовательности.
Код
IObservable<string> xs = Observable.Generate<int, string>(     
      initialState: 0, // начальное значение
      condition: x => x < 10, // условие завершения генерации
      iterate: x => x + 1, // изменение значения
      resultSelector: x => x.ToString() // преобразование текущего значения в результат
      ); xs.Subscribe(x=> Console.WriteLine("x: {0}",x));

ПРИМЕЧАНИЕ
Обратите внимание на явное указание параметров обобщенного метода. Причина такого странного поведения (ведь обобщенные параметры методов должны спокойно выводиться компилятором) в том, что в компиляторе языка C# есть известный баг, в результате которого вывод типов плохо дружит с именованными параметрами. Подробнее об этом можно почитать на stackoverflow или на connect-e. Да, кстати, это дело пофиксили в Visual Studio 11.

Читать подробнее...

Повторная генерация исключений

Обработка исключений появилась в mainstream языках программирования вот уже более трех десятилетий назад, но сегодня все еще можно встретить разработчиков, которые боятся их использовать. Некоторые считают, что генерация исключений в конструкторе повредит их хрупкой карме и их настигнет кара в виде поддержки кода двадцатилетней давности, написанного стадом безумных индусов. Некоторые все еще застряли в эпохе языка С и даже в языке C# интенсивно используют коды возврата в виде магических чисел или даже строк, считая, что исключения придумали трусы, а настоящие самураи могут обойтись и без них. (Хотя мы-то с вами знаем, что настоящие самураи следуют “Принципу самурая” и никаких кодов возврата не используют).

Дополнительную сложность добавляют конкретные платформы и языки программирования. Сегодня на собеседовании C# разработчика, когда речь заходит об обработке исключений, обязательно прозвучит вопрос: «А в чем отличие «проброса»  исключения с помощью конструкций throw; и throw ex;?». И хотя, это страшный баян, и большинство разработчиков давно знают правильный ответ на этот вопрос, в реальном коде встретить «некошерный» вариант очень даже просто.

Читать подробнее...

Проблемы передачи списка перечислений или Почему абстракции «текут»?

Все нетривиальные абстракции дырявы.
Джоэл Спольски (Закон дырявых абстракций)


А иногда дырявятся и довольно простые абстракции.
Автор этой статьи



Большинство современных разработчиков знакомы с «законом дырявых абстракций» по знаменитой заметке Джоэла Спольски с одноименным названием. Заключается этот закон в том, что как бы ни был хорош протокол взаимодействия, фреймворк или набор классов, моделирующих предметную область, рано или поздно нам приходится спускаться на уровень ниже и разбираться с тем, как же эта абстракция устроена. Внутреннее устройство абстракции должно быть проблемой самой абстракции, но возможно это только в наиболее общих случаях и лишь до тех пор, пока все идет хорошо (*).
Когда-то давно, в «небольшой» мелкомягкой компании решили, а почему бы нам не «абстрагироваться» от местоположения объекта и сделать сам факт того, является ли объект локальным или удаленным, лишь «деталью реализации». Так появились технологии DCOM и ее наследник .NET Remoting, которые скрывали от разработчика, является ли объект удаленным или нет. При этом появились все эти «прозрачные прокси», которые позволяли работать с удаленным объектом, даже не зная об этом. Однако со временем выяснилось, что эта информация архиважна для разработчика, поскольку удаленный объект может генерировать совершенно другой перечень исключений, да и стоимость работы с ним несравнимо выше, чем взаимодействие с локальным объектом.

Читать подробнее...

Dispose pattern

Не стоит следовать некоторой идиоме только потому,
что так делают все или так где-то написано.
Мысли автора статьи во время чтения и рефакторинга чужого кода



Ни для кого не будет секретом, что платформа .NET поддерживает автоматическое управление памятью. Это значит, что если вы создадите объект с помощью ключевого слова new, то вам не нужно будет самостоятельно заботиться о его освобождении. Сборщик мусора определит «достижимость» объекта, и если на объект не осталось корневых ссылок, то он будет освобожден. Однако, как только речь заходит о ресурсах, таких как сокет, буфер неуправляемой памяти, дескриптор операционной системы и т.д., то сборщик мусора, по большому счету, умывает руки и весь «головняк» по работе с такими ресурсами ложится на плечи разработчика.

«А как же финализаторы?» – спросите вы. Ну,да, есть такое дело, финализаторы действительно предназначены для освобождения ресурсов, но проблема в том, что время их вызова не детерминировано, а это значит, что никто не знает, когда они будут вызваны и будут ли вызваны вообще. Да и порядок вызова финализаторов не определен, поэтому при вызове финализатора некоторые «части» вашего объекта уже могут быть «разрушены», поскольку их финализаторы уже были вызваны. В общем, финализаторы – они-то есть, но это скорее «страховочный трос», а не нормальное средство управления ресурсами.

Читать подробнее...

Еще раз о повторном использовании

Сегодня открыл книгу «Банды четырех», чтобы уточнить определение одного из паттернов проектирования и в первой же главе увидел выделенную когда-то цитату:
Цитата
«Поднаторевшие в объектно-ориентированном проектировании разработчики скажут вам, что обеспечить «правильный», то есть в достаточной мере гибкий и пригодный для повторного использования дизайн, с первого раза трудно, если вообще возможно. Прежде чем считать цель достигнутой, они обычно пытаются опробовать найденное решение на нескольких задачах, и каждый раз модифицируют его».

Эрик Липперт, один из разработчиков компилятора C#, очень часто говорит о проблеме «преждевременного обобщения» (premature generalization), с которой я, например, сталкиваюсь постоянно.

Читать подробнее...

Принцип самурая

В мире разработки софта существует много идей и «метафор», позаимствованных из других, казалось бы, не сильно связанных с программированием областей. Можно вспомнить паттерны проектирования, позаимствованные у архитекторов, или понятие «технического долга», пришедшее из финансовой индустрии, да и «эффектом второй системы» страдают проектировщики любых систем, а не только программных (*). Все это упрощает коммуникацию между разработчиками или между разработчиками и заказчиками, а также упрощает понимание той или иной проблемы в разработке ПО.

Еще одной метафорой, или скорее принципом разработки, является «принцип самурая», призванный описать «контракт» между функцией и вызывающим ее кодом и заключается в следующем. Любая функция, реализующая некоторую единицу работы должна следовать тому же кодексу чести «бусидо», по которому живет любой самурай. Так, самурай не будет выполнять никаких заданий, противоречащих его «кодексу чести» и если к нему подойти с «непристойным» предложением, то он снесет вам башку раньше, чем вы успеете глазом моргнуть. Но если уж самурай возьмется за дело, то можно быть уверенным в том, что он доведет его до конца (**).

Читать подробнее...

Вы, конечно, шутите, мистер Фейнман

Мое знакомство с мистером Фейнманом началось с перевода статьи Эрика Липперта «Что бы сделал мистер Фейнман». В этой замечательной заметке в виде шуточного рассказа приведены ответы на «нестандартные вопросы», так любимые некоторыми «мелкомягкими» компаниями при отборе кандидатов на работу. А поскольку мистер Фейнман всегда любил «нестандартные вопросы» и давал на них еще менее «стандартные ответы», то интервью получилось веселым и, как я узнал позднее, очень похожим на неопубликованную главу из книги «Вы, конечно, шутите, мистер Фейнман».

Читать подробнее...

Wanted! Старые хиты Эрика Липперта

Если вы вдруг не знали, то помимо всякой ерунды, публикуемой в этом блоге, я еще занимаюсь и переводом блога Эрика Липперта (Eric Lippert) Fabulous Adventures in Coding на русский язык. В русскоязычном варианте этот блог носит название Невероятные приключения в коде.

Занимаюсь я этим делом вот уже полтора года и ни разу не пожалел потраченного времени. Я надеюсь, что чтение статей Эрика на русском языке доставляет хоть малую толику того удовольствия, которое я получаю при переводе!

Читать подробнее...

Неявно типизированные поля в C#

Сегодня на кывте был задан очередной весьма интересный вопрос о том, почему в языке C# существуют неявно типизированные локальные переменные (implicitely-typed local variables) a.k.a. var, но нет неявно типизированных полей?

На самом деле, такое положение дел вовсе не случайно; так что давайте рассмотрим несколько причин, почему компилятор ведет себя именно так, а не иначе.

Читать подробнее...

О книге “MS Visual C++ 2010 в среде .NET. Библиотека программиста”

Если посмотреть на мои обзоры книг (*), то может возникнуть подозрение в предвзятости, поскольку отзывы либо положительные, либо восторженные. Объясняется эта ситуация довольно просто: прежде чем браться за чтение книги разумно совершить «разведку боем» и выяснить, насколько чтение той или иной книги полезно и актуально. Если отзывы на книгу хорошие, автор внушает доверие, а тема интересна, то есть все шансы на то, что и вы не пожалеете о потерянном времени. Если же отзывы сугубо отрицательные и за версту тянет стилем изложения «Для чайников» в самом плохом смысле этого слова, то и время на такую книгу тратить не стоит.

Читать подробнее...

Effective Concurrency от Герба Саттера

Герб Саттер, если вдруг кто не знает, это гуру С++ и многопоточности, автор нескольких весьма популярных книг и сотни известных статей, главный дизайнер языка C++/CLI и всяких там многопоточных расширений, в общем, крут парень, ничего не скажешь.

Но именно в данном случае интересно не это. Сегодня я отправил Гербу мыло с просьбой разрешить перевод и публикацию у себя в блоге его серии статей Effective Concurrency, и получил от него ответ через 40 (!) минут. То что ответ был отрицательным, это уже второе, но сам факт, что такие люди отвечают столь оперативно не может не радовать.

Читать подробнее...

Гарантии безопасности исключений

Основные баталии по поводу того, что лучше использовать при программировании на C# – исключения или коды возврата для обработки, ушли в далекое прошлое (*), но до сих пор не утихают баталии другого рода: да, хорошо, мы остановились на обработке исключений, но как же нам их обрабатывать «правильно»?

Существует множество точек зрения о том, что же такое «правильно», большая часть из которых сводится к тому, что нужно перехватывать только те исключения, которые ты можешь обработать, а все остальные пробрасывать вызывающему коду. Ну, а в случае, если на верхний уровень пробралось дерзким образом непонятное исключение, то стрелять все приложение целиком, поскольку уже не понятно, находится ли оно, родимое, в согласованном состоянии или нет.

Читать подробнее...

О синглтонах и статических конструкторах

Изначально автор хотел назвать эту статью следующим образом: «О синглтонах, статических конструкторах и инициализаторах статических полей, о флаге beforeFieldInit и о его влиянии на deadlock-и статических конструкторов при старте сервисов релизных билдов в .Net Framework 3.5», однако в связи с тем, что многострочные названия по неведомой автору причине так и не прижились в современном компьютерном сообществе, он (автор) решил сократить это название, чудовищным образом исказив его исходный смысл.

Читать подробнее...

О вреде изменяемых значимых типов

Большинство программистов, которых нелегкая судьба свела с платформной.Net знают о существовании значимых типов (value types) и ссылочных типов (reference types). И довольно многие из них прекрасно знают, что помимо названия, эти типы имеют и другие различия, такие как расположение объектов оных типов в памяти, а также в семантике.

Читать подробнее...

Вернуться. Нормальное отображение страницы