Результати пошуку
ITVDN: курси програмування
Відеокурси з
програмування

Замовити дзвінок

Вибери свою IT спеціальність

Підписка

Замовити дзвінок

+38 099 757 27 82
Результати пошуку за запитом: видеокурс c*
SEO-хакі для розробників

Автор: Greg Snow-Wasserman

Настройка разработчиком любого сайта для успешного SEO – довольно несложный процесс. Но что делать, если вам этого недостаточно? Что вы делаете, если уже есть sitemap и robots.txt, если вы оптимизировали URL и метатеги, оптимизировали сайт под мобильные устройства, но трафика по-прежнему нет? Мы собрали четыре быстрых и простых хака для разработчиков для того, чтобы ваш SEO взлетел и сайт продвинулся в результатах поиска. AMP для мобильных устройств Много важного было сделано для мобильного поискового трафика и того, чтобы оптимизировать сайты для пользователей мобильных устройств. Мера оптимизации мобильной рекламы в Интернете еще известна как «мобильное удобство». Мобильное удобство состоит из двух основных компонентов: Пользовательский интерфейс – насколько легко пользователям перемещаться по сайту и совершать действия? Он предназначен для сенсорных экранов?  Скорость – как важная составляющая общего удобства сайта, скорость экспоненциально важнее для мобильного SEO. Мобильные пользователи ожидают, что загрузка займет всего несколько секунд. Конечно, есть способ улучшить дружелюбие вашего сайта к мобильным устройствам: Accelerated Mobile Pages. Проект AMP от Google представляет собой набор спецификаций, предназначенных для создания страниц для мобильных устройств, которые просты в использовании и навигации, плавно отображаются и загружаются практически мгновенно. AMP состоит из трех частей, которые работают вместе: HTML: В основном обычный HTML с пользовательскими свойствами для изображений, видео и фреймов; а также ограниченные технические функции, определенные спецификациями открытых источников. AMP JavaScript библиотека: AMP JS библиотека управляет загрузкой ресурса для страницы, гарантируя, что любые сторонние ресурсы не блокируют рендеринг страницы. Google AMP Cache: Специальная сеть доставки контента, которая извлекает, хранит и обслуживает действительные страницы AMP и ресурсы из одного источника. Использование спецификации ускоренных мобильных страниц все равно, что создание ярлыка для мобильного удобства. Весь проект призван помочь сделать страницы дружественными для мобильных устройств: Пользовательский интерфейс: поскольку AMP JS загружает элементы страницы асинхронно, это гарантирует, что вышеописанное содержимое появляется перед чем-либо еще. Кроме того, AMP JS требует, чтобы соотношения были предопределены, поэтому браузер знает, как будет выглядеть страница, прежде чем начнется рендеринг. Пользователи больше не подвержены неравномерным страницам с контентом, который перескакивает при загрузке. Скорость страницы: есть причина, по которой AMP имеет право на звание «ускоренных». Согласно Google, время загрузки страниц AMP на 85% ниже, чем на других страницах. Оптимизация поисковой сущности В течение последних нескольких лет Google внедрял семантическую веб-технологию в свои результаты поиска. Эти семантические технологии строятся на так называемых «сущностях». Сущности, как вы, вероятно, догадываетесь, -  люди, места и вещи. Как базовые существительные помогут вам улучшить SEO вашего сайта? Благодаря красоте семантической сети и графу знаний Google, вот как. Один из наиболее очевидных примеров семантического поиска Google, Графа знаний – это поисковая оптимизация сущности в действии. Используя структурированную разметку данных, такую как JSON-LD, RDF / XML или другие RDF-форматы, вы можете оптимизировать сущность своего бренда, чтобы максимально использовать его в Графе знаний. Используйте инструмент, например, WooRank’s Metadata Tool, чтобы указать Google на ваши профили и блоги в социальных сетях. Просто введите URL-адреса ваших профилей в инструменте, а затем скопируйте разметку на свой сайт. Оптимизация сущностей также жизненно важна для местных предприятий или крупных предприятий с локальными филиалами. Семантическая сеть действительно важна для местных предприятий, поэтому вам необходимо использовать ее возможности. Это означает добавление оптимизации ваших объектов для структурирования важных данных в результатах локального пакета Google: Используйте семантическую разметку, такую как LocalBusiness schema, чтобы добавить важные данные к информации о вашей компании: Время работы Адрес Телефонный номер Принимаемые платежи Ценовой диапазон Рейтинги Не отчаивайтесь, если вы не видите немедленного повышения трафика на ваш сайт. Как это часто бывает в случае с семантическим SEO, оптимизация сущностей – это способ наиболее быстрого получения самой важной информации о вас пользователями. Даже если они не посещают ваш сайт, мы знаем, что локальный SEO улучшает посещения магазина и увеличивает количество покупок даже без увеличения трафика веб-сайта. Переход на HTTPS Обеспечение безопасности вашего сайта – отличная идея для вас и ваших пользователей, так что это действительно хорошая идея получить сертификат SSL. Кроме того, отказ от использования HTTPS приводит к тому, что ваш сайт теряет позиции в результатах поиска. Переход на HTTPS URL-адреса – это относительно простой способ улучшить SEO вашего сайта. Даже если вы недавно приобрели SSL-сертификат и перенесли его на HTTPS, у вас все еще есть некоторые прорехи в безопасности. Даже если ваш домен размещен на защищенном URL-адресе, но на странице есть ресурсы, которые размещены на незащищенных адресах, Google это не понравится. Первым шагом будет сканирование вашего сайта, чтобы найти все ваши URL-адреса, как безопасные, так и нет. Вы можете использовать традиционный поисковый робот, например, Screaming Frog, который скомпилирует список всех URL-адресов и позволит вам найти все ресурсы без HTTPS. Или используйте инструмент Woorank Site Crawl, чтобы найти каждый экземпляр HTTPS-страниц, размещающих ресурсы на HTTP URL-адресах. Эти активы включают: Изображения CSS файлы Видео Скрипты Фрэймы После того, как вы зафиксировали HTTPS-страницы с помощью HTTP-активов, вам нужно еще кое-что проверить: Robots.txt. Поскольку Google видит URL-адреса HTTP и HTTPS как отдельные сайты, использование небезопасных URL-адресов в файле robots.txt приведет к тому, что ваш файл robots.txt будет не таким эффективным. Sitemap. Использование URL-адресов, отличных от HTTPS, в вашем файле sitemap может привести к тому, что Google будет сканировать и индексировать незащищенные URL-адреса, что противоположно тому, чего вы хотите. Канонические метки. Использование неправильной формы URL-адреса для вашего канонического тега почти полностью отменяет назначение канонического тега. После того, как вы обновили файл sitemap и файл robots.txt, повторите сканирование своего сайта с помощью Site Crawl. Все ваши канонические теги без URL-адресов HTTPS будут отображаться в разделе Canonical как канонические несоответствия. Оптимизируйте ваши изображения Размер изображений Использовать изображения и видеоролики на вашем веб-сайте – это замечательное решение, которое значительно улучшает пользовательский интерфейс, разбивая текст и делая контент более потребляемым. Вы также можете использовать их для улучшения SEO вашего сайта. Первый SEO-хак, который нужно изучить, - это оптимизация ваших изображений, которая состоит в оптимизации размера изображения. Большие изображения – одна из основных причин низкой скорости страниц и длительного времени ожидания. И не секрет, что и люди, и Google ненавидят медленные страницы. При редактировании изображений уменьшите их до минимального размера. Многие редакторы изображений, такие как Adobe Photoshop, имеют опцию «Save for the Web», которая автоматически уменьшает размер файла при сохранении качества изображения. Если у вас нет Photoshop, есть несколько онлайн инструментов, которые вы можете использовать, чтобы избавиться от дополнительных данных, таких как EXIF: ImageOptim JPEGmini PunyPNG Вы также можете использовать консоль браузера или Google’s PageSpeed Insights для того, чтобы найти неоптимизированные изображения, которые замедляют загрузку ваших страниц. Название файлов и альтернативный текст Большая проблема при использовании изображений для SEO – это сообщить поисковым системам, что находится на изображении и как это относится к странице. Но все изображения можно оптимизировать по ключевым словам: Имя файла: имена файлов относятся к изображениям, подобно URL-адресам для веб-страниц. И они должны быть оптимизированы во многом таким же образом. Большинство хостеров изображений будут использовать имя файла изображения при создании его URL, так что такая оптимизация окупится еще больше. При создании имен файлов будьте описательными и краткими и не используйте подчеркивания. Избегайте использования имен файлов по умолчанию, например, «DSC673829.jpg» или «image_01.jpg», кроме случаев, когда это невозможно. Альтернативный текст: альтернативный текст вместе с именем файла является одной из наиболее важных частей изображения для SEO. Это представляет собой машиночитаемый «контент» изображения, так что это ваша возможность добавить ваше ключевое слово. Как и имена файлов, альтернативный текст должен быть кратким, но, если сделать его слишком коротким, это отрицательно скажется на его преимуществах. Хороший alt text для этого изображения: Выглядел бы так: img src="audit-alt-text-criteria.jpg” alt=”Alt text criteria in the WooRank SEO audit’/ Держите ключевые слова релевантными для фактического изображения, а не обязательно для страницы. Попытка использовать альтернативный текст типа “Alt text in SEO audit as SEO hack for developers” может оказаться похожим на спам-ключевик. Это нехорошо. Подведение итогов Конечно, есть вероятность, что ваши проблемы с трафиком Google могут выходить за рамки четырех хаков, перечисленных выше. Если ваш трафик все еще низкий, выясните, как диагностировать и лечить возникшую проблему. Если вы хотите начать развивать свою аудиторию, проведите один или два SEO-эксперимента. Узнайте, что работает именно для вас. Источник
Нововведення у С# 7.0

Автор: Mads Torgersen

В этой статье мы расскажем о нововведениях в языке C# 7.0, которые были представлены в марте 2017 года как часть релиза Visual Studio 2017. В C# 7.0 появился целый ряд нововведений и основное внимание уделяется использованию данных, упрощению кода и улучшению производительности. Возможно, самой главной особенностью являются кортежи, которые упрощают получение различных результатов, и сопоставление с шаблоном, что упрощает код, который зависит от формы данных. Существует также множество других нововведений, как значительных, так и не очень. Надеемся, что в совокупности они сделают ваш код более эффективным и точным, а вы при этом будете работать продуктивнее и останетесь довольны результатом. Если вас интересует процесс разработки, который привел к этому набору функций, вы можете найти заметки, предложения и множество обсуждений на эту тему на сайте C# language design GitHub. Если данная информация кажется вам знакомой, это только потому, что релиз предварительной версии состоялся в августе прошлого года. В окончательной версии C# 7.0 изменились некоторые детали, некоторые из них - из-за отличных отзывов на указанную ранее статью. Получайте удовольствие от C# 7.0 и удачного хакинга! Out переменные В более ранних версиях C# использование out параметров является не таким легким, как нам хотелось бы. Прежде чем вызвать метод с out параметрами, сначала необходимо объявить переменные, чтобы перейти к нему. Поскольку вы обычно не инициализируете эти переменные (они все равно будут перезаписаны методом), вы также не можете использовать ключевое слово var, но вам нужно указать полный тип: public void PrintCoordinates(Point p) { int x, y; // have to "predeclare" p.GetCoordinates(out x, out y); WriteLine($"({x}, {y})"); } В C# 7.0 мы добавили out переменные, что позволяет объявлять переменную прямо в точке, где она передается как out аргумент: public void PrintCoordinates(Point p) { p.GetCoordinates(out int x, out int y); WriteLine($"({x}, {y})"); }  Обратите внимание, что переменные находятся в области видимости в окружающем блоке, поэтому последующая строка может их использовать. Многие виды утверждений не устанавливают свою собственную область действия, поэтому out переменные, объявленные в них, часто вводятся в область видимости. Поскольку out переменные объявляются непосредственно в качестве аргументов для out параметров, компилятор может обычно указывать, каков должен быть их тип (если только не существует конфликтующих перегрузок), поэтому вместо типа можно использовать ключевое слово var: p.GetCoordinates(out var x, out var y);  Общим использованием out параметров является шаблон Try..., где логическое возвращаемое значение указывает на успех, а out параметры переносят полученные результаты: public void PrintStars(string s) { if (int.TryParse(s, out var i)) { WriteLine(new string('*', i)); } else { WriteLine("Cloudy - no stars tonight!"); } }  Мы также допускаем «сбрасывание» в качестве out параметров в виде «_», что позволит вам проигнорировать параметры, которые вам не нужны: p.GetCoordinates(out var x, out _); // I only care about x Соответствие с шаблоном В C# 7.0 вводится понятие шаблонов, которые являются синтаксическими элементами, позволяющими проверить соответствие значения определенной «форме» и извлечь информацию из значения, если такое соответствие имеется. Примеры шаблонов в C# 7.0: • Константные шаблоны c (где c – константное выражение в C#), которые проверяют, равняется ли переменная этой константе. • Шаблоны типа T x (где T – тип и x – идентификатор), которые проверяют, имеет ли переменная тип T, и если да, то извлекают значение в новую переменную x типа T. • Var шаблоны var x (где x – идентификатор), которые всегда совпадают и просто помещают значение ввода в новую переменную x с тем же типом. Это только начало; шаблоны являются новым типом элемента языка C#, и в будущем мы обязательно добавим новые шаблоны в C#. В C# 7.0 мы улучшаем две существующие языковые конструкции с шаблонами: • is теперь может использоваться не только с типом, но и с шаблоном; • case в операторе switch теперь может использовать шаблоны, а не только константы. В будущих версиях C#, вероятно, мы добавим больше мест, где можно использовать шаблоны. Шаблоны с is Рассмотрим пример использования is с константным шаблоном и шаблоном типа: public void PrintStars(object o) { if (o is null) return; // constant pattern "null" if (!(o is int i)) return; // type pattern "int i" WriteLine(new string('*', i)); } Как видно из примера, переменные шаблона, представленные шаблоном, аналогичны out переменным, описанным ранее, поэтому могут быть объявлены в середине выражения и использоваться в ближайшей окружающей области. Также как out переменные, переменные шаблона изменяемы. Мы часто ссылаемся на out переменные и переменные шаблона совместно как «переменные выражения». Шаблоны и Try-методы часто используются вместе: if (o is int i || (o is string s && int.TryParse(s, out i)) { /* use i */ } Шаблоны с выражениями switch Мы обобщаем варианты использования switch: • Вы можете использовать любой тип (не только простые типы). • Шаблоны могут использоваться в выражениях case. • Вы можете добавлять дополнительные условия к выражениям case. Вот простой пример: switch(shape) { case Circle c: WriteLine($"circle with radius {c.Radius}"); break; case Rectangle s when (s.Length == s.Height): WriteLine($"{s.Length} x {s.Height} square"); break; case Rectangle r: WriteLine($"{r.Length} x {r.Height} rectangle"); break; default: WriteLine(""); break; case null: throw new ArgumentNullException(nameof(shape)); } Существует несколько особенностей, которые следует отметить в этом новом расширенном выражении switch: • Порядок выражений case теперь имеет значение: как и в случае с выражениями catch, у выражений case выбирается первое по порядку выражение, удовлетворяющее условию. Поэтому важно, чтобы условие квадрата было перед условием прямоугольника. Кроме того, как и в случае с выражениями catch, компилятор поможет вам пометить явные недостижимые условия. До этого вы не могли определить порядок выполнения, так что это не является нарушением существующего поведения. • Условие по умолчанию (default) всегда вычисляется последним: несмотря на то, что после него идет условие null, условие default будет проверено после него. Это сделано для совместимости с существующей семантикой. Однако, как правило, вы помещаете условие default  в конце. • Условие null в конце достижимо, потому что шаблоны типов следуют примеру текущего is  и не срабатывают для null. Это гарантирует, что null значения не будут случайно сопоставлены с первым шаблоном типа; вы должны явно указать, как им управлять (или оставить логику для условия default). Переменные шаблона, объявленные ключевым словом case..., находятся в области видимости только в соответствующем разделе switch. Кортежи Обычно хочется вернуть несколько значений из метода. Все доступные варианты в существующих версиях C# являются менее оптимальными: • Out параметры: использование является неэффективным (даже при использовании рассмотренных нововведений) и они не работают с асинхронными методами. • System.Tuple <...>: выглядит многословным для использования и требует выделения кортежного объекта. • Специальный вид переноса для каждого метода: слишком много кода для типа, единственной целью которого служит временная группировка нескольких значений. • Анонимные типы, возвращаемые через тип возврата dynamic: потери в производительности и отсутствие проверки статического типа. Для упрощения этой задачи в C# 7.0 были добавлены кортежи и литералы кортежей: (string, string, string) LookupName(long id) // tuple return type { ... // retrieve first, middle and last from data storage return (first, middle, last); // tuple literal }  Теперь метод эффективно возвращает три строки, объединенные как элементы кортежа. Вызывающий код метода получит кортеж и может индивидуально иметь доступ к элементам: var names = LookupName(id); WriteLine($"found {names.Item1} {names.Item3}."); Имена полей Item1 и т. д. являются именами по умолчанию для элементов кортежа и могут использоваться всегда. Но они не очень наглядны, поэтому вы можете добавить лучшие имена: (string first, string middle, string last) LookupName(long id) // tuple elements have names Теперь получатель этого кортежа имеет более описательные имена для дальнейшей работы: var names = LookupName(id); WriteLine($"found {names.first} {names.last}."); Вы также можете указать имена элементов непосредственно в литералах кортежей: return (first: first, middle: middle, last: last); // named tuple elements in a literal Как правило, вы можете назначать типы кортежей друг для друга, независимо от их имен: при условии, что отдельные элементы будут присваиваемыми, типы кортежей могут свободно преобразовываться в другие типы кортежей. Кортежи – это типы значений, а их элементы – общедоступные изменяемые поля. Они имеют значение равенства, а это значит, что два кортежа являются равными (и имеют одинаковый хэш-код), если все их элементы попарно равны (и имеют одинаковый хэш-код). Это делает кортежи полезными для различных ситуаций, а не только для возвращения нескольких значений из метода. Например, если вам нужен словарь с составным ключом, используйте кортеж в качестве ключа, и все будет работать правильно. Если вам нужен список с несколькими значениями в каждой позиции, также используйте кортеж для корректной работы. Кортежи полагаются на базовые структурные типы, которые называются ValueTuple <...>. Если вы выявите модель, что еще не включает эти типы, вы можете вместо этого выбрать их с помощью NuGet: • Щелкните правой кнопкой мыши проект в обозревателе решений и выберите «Manage NuGet Packages…». • Выберите вкладку «Browse» и выберите «nuget.org» в качестве «Package source». • Найдите «System.ValueTuple» и установите его. Распаковка кортежей Еще один способ использования кортежа – это его распаковка. Объявление распаковки является синтаксисом для разделения кортежа (или другого значения) на его части и назначения этих частей по отдельности новым переменным: (string first, string middle, string last) = LookupName(id1); // deconstructing declaration WriteLine($"found {first} {last}."); В объявлении распаковки можно использовать ключевое слово var для отдельных переменных: (var first, var middle, var last) = LookupName(id1); // var inside Или даже поместить var перед скобками как аббревиатуру: var (first, middle, last) = LookupName(id1); // var outside Вы также можете распаковать в уже существующие переменные с помощью присвоения распаковки: (first, middle, last) = LookupName(id2); // deconstructing assignment Распаковка выполняется не только для кортежей. Любой тип может быть распакован, если у него есть метод распаковки (образец или расширение): public void Deconstruct(out T1 x1, ..., out Tn xn) { ... } Out параметры соответствуют значениям, которые будут присвоены в результате распаковки. (Почему используются out параметры, а не кортежи? Чтобы можно было иметь несколько перегрузок метода с разным количеством параметров). class Point { public int X { get; } public int Y { get; } public Point(int x, int y) { X = x; Y = y; } public void Deconstruct(out int x, out int y) { x = X; y = Y; } } (var myX, var myY) = GetPoint(); // calls Deconstruct(out myX, out myY); Это будет обычный шаблон для создания «симметричных» конструкторов и методов распаковки таким способом. Так же, как и для out переменных, мы разрешаем «сбрасывать» в распаковке параметры, которые вам не нужны: (var myX, _) = GetPoint(); // I only care about myX Локальные функции Иногда вспомогательная функция имеет смысл только внутри одного метода, в котором вызывается. Теперь вы можете объявить такие функции внутри других функций как локальную функцию: public int Fibonacci(int x) { if (x < 0) throw new ArgumentException("Less negativity please!", nameof(x)); return Fib(x).current; (int current, int previous) Fib(int i) { if (i == 0) return (1, 0); var (p, pp) = Fib(i - 1); return (p + pp, p); } } Параметры и локальные переменные из области видимости доступны для локальной функции так же, как и для лямбда-выражений. В качестве примера рассмотрим методы, реализованные как итераторы, что обычно нуждаются в неитераторном методе-оболочке для точной проверки аргументов в момент их вызова (так как сам итератор не запускается, пока не будет вызван MoveNext). Локальные функции идеально подходят для этого сценария: public IEnumerable Filter(IEnumerable source, Func filter) { if (source == null) throw new ArgumentNullException(nameof(source)); if (filter == null) throw new ArgumentNullException(nameof(filter)); return Iterator(); IEnumerable Iterator() { foreach (var element in source) { if (filter(element)) { yield return element; } } } } Если бы Iterator был приватным методом рядом с Filter, то мог быть доступен для других членов в использовании напрямую (без проверки аргументов). Кроме того, необходимо было бы передавать все те же аргументы, что и Filter, вместо того, чтобы иметь их только в области видимости. Улучшения литералов В C# 7.0 появилась возможность добавлять «_» в качестве разделителя в числовые литералы: var d = 123_456; var x = 0xAB_CD_EF;  Вы можете поместить разделитель в любом месте между цифрами, чтобы улучшить читабельность. Они не влияют на значение. Кроме того, C# 7.0 представляет бинарные литералы, так что вы можете указывать битовые шаблоны непосредственно вместо того, чтобы знать шестнадцатеричную систему наизусть. var b = 0b1010_1011_1100_1101_1110_1111;  Локальные переменные и возвращаемые значения по ссылке Теперь можно не только передать параметры в метод по ссылке в  С# (с помощью ключевого слова ref), но и возвратить данные из метода по ссылке, а также сохранить в локальной переменной тоже по ссылке. public ref int Find(int number, int[] numbers) { for (int i = 0; i < numbers.Length; i++) { if (numbers[i] == number) { return ref numbers[i]; // return the storage location, not the value } } throw new IndexOutOfRangeException($"{nameof(number)} not found"); } int[] array = { 1, 15, -39, 0, 7, 14, -12 }; ref int place = ref Find(7, array); // aliases 7's place in the array place = 9; // replaces 7 with 9 in the array WriteLine(array[4]); // prints 9 Очень удобно передавать ссылки на определенные места в больших структурах данных. Например, в игре информация содержится в большом заранее выделенном массиве структур (во избежание пауз на сбор мусора). Теперь методы могут вернуть ссылку непосредственно на одну из таких структур, с помощью которой вызывающий код может читать и изменять эту структуру. Существуют некоторые ограничения для обеспечения безопасности: • Можно возвращать только ссылки, которые возвращать безопасно: ссылки, переданные в метод и ссылки на поля объектов. • Локальные переменные инициализируются определенной ячейкой памяти и в будущем не меняются. Обобщенные типы асинхронных возвратов До сегодняшнего дня асинхронные методы могли возвращать только void, Task или Task. В C# 7.0 позволяется создавать типы, которые также могут быть возвращены асинхронным методом. Например, можно создать структуру ValueTask, которая поможет избежать создания объекта Task в случае, когда результат асинхронной операции уже доступен в ожидаемое время. Для многих асинхронных сценариев, например, где используется буферизация, такой подход может значительно уменьшить число выделений памяти и таким образом значительно повысить производительность. Конечно, можно придумать и другие ситуации, в которых task-подобные объекты будут полезны. Правильное создание таких типов не будет простой задачей, поэтому мы не ожидаем, что большое количество разработчиков будут создавать их. Однако мы полагаем, что они будут появляться в различных моделях и прикладных интерфейсах, и вызывающий код сможет просто использовать await, как сейчас для Task. Больше членов в виде выражений Методы и свойства в виде выражений используются в C# 6.0, но не все типы членов можно было так объявлять. В C# 7.0 к списку членов в виде выражений добавилась поддержка аксессоров, конструкторов и финализаторов: class Person { private static ConcurrentDictionary names = new ConcurrentDictionary(); private int id = GetId(); public Person(string name) => names.TryAdd(id, name); // constructors ~Person() => names.TryRemove(id, out _); // finalizers public string Name { get => names[id]; // getters set => names[id] = value; // setters } } Это пример функции, которая была предоставлена сообществом, а не командой компилятора Microsoft C#. Ура, открытый код! Throw выражения Выбросить исключение в середине выражения очень легко: достаточно вызвать метод, который это сделает! Но в C# 7 теперь можно использовать throw как часть выражения в определенном месте: class Person { public string Name { get; } public Person(string name) => Name = name ?? throw new ArgumentNullException(nameof(name)); public string GetFirstName() { var parts = Name.Split(" "); return (parts.Length > 0) ? parts[0] : throw new InvalidOperationException("No name!"); } public string GetLastName() => throw new NotImplementedException(); } Источник
Уразливості в .NET платформі

Автор: Редакция ITVDN

Необходимо ли вам знать об уязвимостях в .NET? Возможно, вы по-новому взглянете на код, а может, и на свою жизнь. А вдруг вам захочется сменить квалификацию и уйти в research новых видов атак? Кто знает. Но если вы задались вопросом об уязвимости, то вы наверняка интересуетесь тем, как разрабатывать надёжные и защищённые приложения. Итак, давайте поговорим об уязвимостях, которые находят в .NET Framework.  DoS (Denial of service) – атака на ASP .NET MVC приложение. Эта атака способна серьезно нарушить работу вашего сайта, например, замедлить его, а в отдельных случаях и вовсе его заблокировать.  Как работает На сервер производятся запросы, которые он не может обработать, в результате чего сервер не успевает обрабатывать запросы обычных посетителей и выглядит для них как неработающий. Как исправлять Упростить регулярное выражение Заменить регулярное выражение на custom алгоритм Задать timeout для обработки любого регулярного выражения, используя конструктор, или для всех регулярных выражений, используя AppDomain.   Это отличные примитивные меры, когда вам не очень хочется разбираться в том, какие у вас регулярные выражения и насколько они сложные. Тем более, что такие решения вам ничего не стоят, но дают результат. Атака повышения привилегий (ЕоР) на SQL-сервер. В данном случае это luring атака, которая может скомпрометировать все данные на сервере. Атака повышения привилегий (ЕоР) в ASP .NET Core 1.0. Эта уязвимость была зафиксирована как ошибка бизнес-логики, но позже выяснилось, что она может привести к раскрытию данных и повышению привилегий пользователя. Как работает Атакующий «заманивает» более привилегированный компонент, чтобы что-то сделать от его имени. Самый простой способ осуществить такую атаку – убедить цель запустить код атакующего в более привилегированном контексте безопасности. Как исправлять Единого сюжета, как избежать этих уязвимостей, к сожалению, нет. Можно дать лишь общие рекомендации. Например: Зарегистрировать request-сервис в контексте синглтона Дважды проверять любой код, работающий с security sensitive, c sandboxing и с модификацией данных Runtime check – ещё один хороший способ защиты от подобных вещей Минимум привилегий везде Раскрытие информации ХХЕ -  это уязвимость к XML-инъекциям, которая приводит к чтению произвольных файлов на атакуемом сервере. Как работает Чтобы понять суть ХХЕ, давайте сначала разберёмся с ХМL форматом. ХМL формат может содержать описание своей структуры в теге DOCTYPE. В этом же теге могут содержаться и некоторые Entity. Если говорить по-простому, то это аналог константы, который дальше может использоваться в ХМL коде и, при парсинге этого кода, будет автоматически раскрываться. Уже это обстоятельство может привести к DoS атаке, если вы добавите Entity, которые рекурсивно раскрываются, и не зададите timeout. Парсер начнёт их раскрывать бесконечно долго. Классическая ХХЕ атака проходит следующим образом. Атакующий отправляет скомпрометированный ХМL файл на сервер, где этот файл парсится, после чего из сервера возвращается ответ. Ответ может быть совершенно любого типа, хотя существует вероятность, что злоумышленник получит именно тот локальный файл, который ему нужен. Как исправлять Запретить использование DTD файлов и External Entity Занулить resolver Ввести ограничение на размер и установку timeout Одной из причин появления уязвимостей может быть десериализация бинарных данных. Десериализация данных – это обратный процесс сериализации. То есть если при сериализации мы переводим какую-либо структуру данных в последовательность битов, то при десериализации мы восстанавливаем начальное состояние этой структуры. Как при этом процессе может возникнуть уязвимость? Допустим, у вас есть класс, реализующий команду, который запускает какой-то конвертор. Вы через конструктор передаете ему параметры этого конвертора и они валидируются в конструкторе. При этом использовать можно не каждый, а только ваш локальный конструктор. В чём же проблема? А проблема состоит в том, что при десериализации данных конструктор не будет запущен. То есть ваши данные будут десериализованы так, как они есть, включая приватные поля. Как исправлять Использовать кастомный сериализатор Использовать минимум привилегий в процессе десериализации О возможных способах десериализации вы можете узнать больше в статье Джеймса Форшав «Are you my Type? Breaking .NET Trough Serialization». Вывод К всеобщему сожалению, сейчас не существует ни одного полностью защищённого  веб-приложения. Поэтому проблема уязвимостей остаётся актуальной. Злоумышленники находят всё новые и новые способы взлома серверов и нанесения всяческого вреда компаниям или обычным людям. Следовательно, для гарантии безопасности вашего приложения вам необходимо знать, как устранять уязвимости и препятствовать их появлению. Материал подготовлен на основе выступления Михаила Щербакова, Independent Consultant, на конференции по .NET-технологиям DotNext 2016 Moscow.
Упаковка значних типів С#. Що під капотом?

Автор: Yi Zhang

Недавно у меня была действительно интересная дискуссия с участником команды, который является экспертом по системам типов в .NET. В ходе беседы он указал на интересный аспект упаковки типа значений в .NET при использовании ограничений. Заинтригованный этой дискуссией, я решил рассмотреть вопрос подробнее. Основы Прежде чем углубиться в подробности, давайте рассмотрим некоторые основы и посмотрим, какую роль может играть упаковка при вызове методов типа значение. Предположим, у нас есть следующий код: Здесь нет ничего особенного. Foo - это структура, которая имеет целочисленное поле value. Она приватно реализует метод интерфейса, который пытается изменить значение этого поля, а также обычный метод, который делает то же самое. Теперь, если у нас есть следующий код: Какое правильное значение после вызова AddValue и после вызова Add? Если вы знакомы с языком, это, пожалуй, вовсе не удивит вас. Но давайте немного углубимся и посмотрим, как JIT это делает: Давайте сначала посмотрим на вызов AddValue. Обратите внимание, что я показываю код сборки x64, который гораздо проще понять. Первые 4 аргумента всегда передаются в регистре rcx, edx, r8, r9 (остаток передается через стек), а возвращаемое значение возвращается в rax. Все это 64-разрядные регистры. В приведенном выше коде JIT передает указатель «this» в rcx (указывает на часть стека, начиная с rbp-18h, и целое число 10 (0x0a) в rdx / edx (edx - это просто нижняя 32-битная часть rdx). Теперь, если вы посмотрите на фактический код Foo.AddValue: Не стесняйтесь игнорировать некоторые из отладочной тарабарщины (clr! JIT_DbgIsJustMyCode). Если вы следите за моими комментариями в сборке (начиная с ;), вы можете увидеть, что 10 добавляется в первую 4-байтовую ячейку памяти в 'this', что и должно делать value + = val. И вы получите следующее: Вызов интерфейса в методе экземпляра типа значения. Теперь давайте взглянем на вызов интерфейса - он немного усложняется: Опять-таки, я поставил комментарии по правой стороне кода сборки. Он в основном создает упакованную Foo, копирует значение во вновь созданную упакованную Foo. Обратите внимание, что смещение 8 для указателя MethodTable в начале объекта  имеют только те объекты и упакованные типы значений, которые являются объектами, разумеется. У обычных типов значений его нет. На данный момент проигнорируйте весь код отправки интерфейса (это не относится к нашему обсуждению), в конце концов вы придете к некоторым интересным инструкциям ниже: Этот код, на самом деле, мало что делает. Но он  дает нам  понимание того, как система работает в целом. Глядя на старый код, который мы показали ранее для метода AddValue, ожидаемо, что он укажет на первое поле. Однако все объекты для поддержки операций типа (таких как рефлексия, кастинг и т. д.) имеют свое первое поле размера указателя в качестве указателя типа, который в языке CLR называется MethodTable. Таким образом, CLR необходимо сгенерировать unboxing-заглушку, которая распаковывает запакованное значение и вызывает базовый JIT-метод, который предполагает работу с распакованным указателем this. Обратите внимание, что распаковка не включает копирование, она просто добавляет к ней смещение. Это фактически означает, что операция + = вступит в силу в упакованной копии. Однако поскольку упакованная Foo известна только компилятору, обновленное значение всегда теряется. И именно поэтому вы увидите: В случае наличия обобщений Теперь давайте добавим некоторые обобщения в микс: Несмотря на то, что это фантастический универсальный метод, сам вызов и лежащий в его основе код не имеет ничего удивительного. Как вы могли ожидать, несмотря на то, что вызывающий элемент передает Foo по ссылке, Add_WithoutConstraint создает его копию, прежде чем вызывает в IAdd, и модификация снова навсегда потеряна. Добавление ограничений Теперь интересный случай, о котором я хотел поговорить ранее в этой статье (спасибо, что остались со мной до сих пор!). Давайте создадим обобщенный метод с общим ограничением, где T является интерфейсом IAdd: Возможно, это не совсем очевидно для всех, foo.Add (val) - это вызов интерфейса с помощью инструкции callvirt: callvirt instance void IAdd :: Add (int32), потому что это единственный способ, который знает компилятор для вызова интерфейса. Интересной частью является то, что, когда мы вызываем Add_WithConstraints, вызов происходит точно таким же образом, за исключением того, что код, который мы вызываем, радикально отличается: Как вы видите, код удивительно прост. Без упаковки, без трансляции интерфейса и прямого вызова метода Foo.IAdd.Add. Никакое значение не теряется. И вы можете наблюдать побочный эффект: Причина в том, что компилятор теперь имеет достаточно информации, чтобы понять, что код для Foo и вызов интерфейса попадет именно на Foo.IAdd.Add, поэтому он пропускает формальности и вызывает функцию напрямую. Это как оптимизация производительности, но также с заметным побочным эффектом. Вывод Когда вы работаете с интерфейсом по типам значений, обратите внимание на потенциальные затраты производительности на упаковку и проблему корректности отсутствия видимых изменений. Если вы хотите избежать этого, вы можете использовать общие ограничения для ограничения вызова интерфейса, чтобы компилятор мог полностью оптимизировать вызов упаковки и интерфейса, и сразу перейти к правильной функции. Вы найдёте полный код в этом сообщении. Источник
React vs Angular: дві сторони JS

Автор: Редакция ITVDN

В мире дедлайнов правильный выбор технологии играет ключевую роль. Имея многолетний опыт за спиной, мы были вовлечены в разработку на десятках языков, с использованием фреймворков и библиотек. Собрав вместе наши знания, мы решили пролить свет на вопрос: React или Angular? и поделиться своими мыслями с вами. Так что в этой статье мы собираемся преобразовать наш опыт frontend разработки в информацию, которая поможет определить лучшую для вас технологию. Почему Angular 2? Angular JS – это open-source библиотека, предоставляющая всё необходимое для создания клиентской части сайта. Используя Angular 2, вы можете заметить, что вторая версия избавлена от ненужной сложности, которая присутствовала в предыдущей версии. Команда, работавшая над Angular 2, устранила или заменила почти все концепции первой версии. Я говорю о модулях, контроллерах, областях видимости, директивах и так далее. Однако они не остановились только на упрощении фреймворка. Они также добавили новые примечательные фичи и некоторые улучшения. Среди фич мы хотели бы выделить встроенную поддержку приложений и server-side рендеринг. Говоря об улучшениях, мы не можем упустить тот факт, что производительность Angular 2 резко возросла. Как Angular стал популярным? Тот факт, что Angular – создание Google, внушает доверие сам по себе. Фреймворк разработан таким образом, что не травмирует психику разработчиков, которые ранее учили другие технологии и языки. Многие разработчики утверждают, что если код на Angular кажется сложным – тогда ты делаешь что-то не так. Сайты, созданные на Angular JS: YouTube (for PS3), GoodFilms, Freelancer, Upwork. Итак, почему Angular 2 может быть полезным? Давайте рассмотрим его основные плюсы и минусы. Angular pros and cons by Cleveroad Почему ReactJS? В отличие от Angular, ReactJS – это JavaScript-based библиотека с открытым исходным кодом и JSX компилятором. Он в основном сосредоточен на пользовательском интерфейсе и разрешает создавать многоразовые UI рассматриваемые компоненты. Используя React, вы всегда должны помнить, что это не MVC фреймворк, а только библиотека для рендеринга вашего View (V из MVC). Таким образом, React – это интерфейс-ориентированное решение, когда ваши пользователи получают весьма отзывчивый интерфейс с плавной загрузкой. Как React стал популярным? За этим проектом стоит Facebook. ReactJS-решения дружественны с SEO. Производительность и гибкость ReactJS очень высоки. Известные сайты, сделанные с помощью ReactJS: Netflix, Feedly, Airbnb, Walmart Сейчас давайте рассмотрим, почему ReactJS может быть полезным. React pros and cons by Cleveroad Как сделать выбор? Сейчас мы глубже рассмотрим детали и нюансы, которые могут быть достаточно важными при выборе технологии. Лицензия Вы должны быть ознакомлены с видами лицензий фреймворка. Большинство лицензий довольно гибкие в работе, и вы можете использовать их для создания коммерческих приложений без каких-либо проблем. Однако существует целый ряд лицензий, которые не дают вам такой свободы действий. Лучше просто поискать информацию, нежели потом узнать, что вы не имеете права на коммерческое распространение своего продукта, не так ли? Примечание: Одним из преимуществ Angular JS и ReactJS является то, что это open-source фреймворки без каких-либо ограничений в использовании. Стоит отметить, что Angular использует MIT лицензию вместо 3-clause BSD лицензии, которая используется в React. Однако BSD отличается от MIT только присутствием запрета на использование имени владельца прав в рекламных целях. Паттерн MVC Паттерн Model-View-Controller разрешает разделять проекты на три компонента: модель, вид и контроллер. Таким образом, модификацию каждого компонента можно проводить независимо друг от друга, что способствует сжатию кода и повышению качества конечного результата. Помимо шаблонов MVC существуют также Model-View-Presenter (MVP) и Model-View-View-Model (MVVM). Примечание: Среди всех особенностей Angular 2 наличие out-of-the-box MVC паттерна является значительным преимуществом перед React. Из трёх букв акроним MVC имеет только букву «V» – View (в переводе «вид»). Так что если вам нужны буквы «М» и «С», то придётся искать их в другом месте. Размещение шаблонов Говоря о преимуществах Angular 2, стоит упомянуть о простоте написания шаблонов отображения. Имея действительно простой интерфейс, Angular позволяет получить конечный результат с более интуитивным подходом к пользовательскому интерфейсу, который требует меньше кода и кажется «очевидным». React же требует специальные функции для управления отображением данных. В основном это значит, что вам следует определить способ представления данных перед тем, как они будут внесены в DOM. Это может привести к отключению во время попыток определить, как будет отображаться определённый элемент.  Примечание: До 80% того, что вы делаете при создании онлайн-сервиса, основывается на написании пользовательского интерфейса. Так что, лучше взвешивайте подходы этих технологий к шаблонизации, чтобы понять, какой из фреймворков соответствует вашим предпочтениям в написании кода. Привязка данных Angular использует двухстороннюю привязку данных. С её помощью фреймворк может присоединить DOM к данным Model через контроллер. В двух словах: когда пользователь взаимодействует с входными данными и задаёт новое значение вашему приложению, то не только View может быть обновлен, а и Model тоже. Соответственно, вам не нужно писать какой-либо метод отслеживания этих изменений в приложении. Примечание: Подход Angular влияет на производительность из-за того, что создается вотчер (watcher) при каждой привязке данных. React использует одностороннюю привязку, где поток данных направлен только в одном направлении. Благодаря этому, вы всегда будете знать, в каком месте ваши данные меняются. Примечание: Подход React гораздо проще отлаживать, когда речь идёт о больших приложениях. Стоит сказать пару слов о клиентском и серверном рендеринге. Фактически server-side рендеринг использовался в первых версиях Angular и создавал трудности для маркетинга. Поскольку браузер воспринимает рендеринг клиентской стороны, то JavaScript дает отличные возможности для SEO оптимизации. Это является существенным недостатком, ведь большинство цифровых продуктов нуждаются в маркетинговой поддержке, дабы остаться в живых. Кроме того, client-side рендеринг может сильно повлиять на загрузку страниц. Однако начиная со второй версии, разработчики Angular исправили эту проблему, перенеся модель рендеринга на сторону сервера. Производительность Как вы знаете, Angular создает наблюдатель (watcher) для каждой привязки данных, чтобы отслеживать все изменения в DOM. Как только View получает некоторые обновления, Angular начинает сравнивать полученные значения с начальными. Дело в том, что данная технология проверяет не только те значения, которые изменились, но и все остальные тоже. Примечание: Производительность Angular 2 может стать причиной проблем для массивных приложений. Разработчики ReactJS ввели концепцию виртуального DOM, которая позволяет создавать легкое дерево DOM, сохраняя его на сервере. Каждый раз, когда пользователь взаимодействует с сайтом, например, заполняет форму, React создает новый виртуальный DOM для сравнения с предыдущим. После того, как библиотека обнаружит все различия между этими двумя моделями – виртуальный DOM будет перестроен. Весь процесс на сервере выполняется, таким образом снижая нагрузку на браузер. Примечание: Производительность ReactJS возрастает, когда дело доходит до больших объемов данных, поскольку в этом фреймворке нет вотчеров. Взгляните на график, показывающий оценку React и Angular по некоторым критериям. Эти оценки основаны на нашем личном опыте. Cleveroad evaluation of technologies У нас было небольшое собрание, посвященное вопросу «React или Angular?», в ходе которого наши frontend разработчики имели возможность обсудить все плюсы и минусы этих технологий. Они пришли к выводу, что Angular лучше подходит для их предпочтений в написании кода, а также для рабочих задач, с которыми они сталкиваются ежедневно. Для подведения итога всему сказанному выше мы подготовили для вас график. В нём сравниваются Angular 1.X, Angular 2 и React. React vs Angular versions Опыт Cleveroad Из этих двух технологий наши разработчики предпочитают Angular. Имея много наработок, связанных с этим фреймворком, мы способны работать более эффективно, сокращая время, необходимое для реализации проекта. Таким образом наши клиенты экономят на стоимости проекта из-за сокращения часов разработки. Все наши проекты, основанные на этой технологии, имели большое количество frontend-логики в своей структуре, которая часто изменяется. Кроме того, в проектах предусматривался ряд изменений в дизайне. Использование библиотеки React может увеличить время разработки и повысить общую стоимость конечного продукта. Вот некоторые из наших проектов: Age In Days, Count, Lifetile. Все эти веб-сайты основаны на AngularJS в нашей компании. Вы также можете посмотреть наш tech stack, который мы обычно применяем вместе с разработкой на Angular 2. Серверные решения: AWS, DigitalOcean, Hetzner, Microsoft Azure Back-end технологии: Node.js + Typescript 2, Angular 2 Базы данных: MySQL, MongoDB, Redis, PostgreSQL Облачные хранилища: WS S3, Azure storage Платёжные системы: Stripe, Braintree Инфраструктура и управление проектами: Webpack 2, Docker и CI, Jira, Bitbucket / Git Подводя итог Вероятно, проблема выбора между Angular и React в мире frontend может быть сопоставима с выбором между iOS и Android. Обе технологии имеют свои преимущества и недостатки, своих поклонников и ненавистников. Таким образом, у каждого разработчика есть определенные причины использовать ReactJS или другую технологию. В 2017 году все больше веб-проектов будет основано на Angular 2 благодаря фичам, позволяющим упростить жизнь разработчиков. Например, хорошая отладка, шаблон MVC, рендеринг на стороне сервера и т. д. В результате это сократит количество часов, необходимых для разработки, и, соответственно, снизит цены на разработку и обслуживание. Оригинал- https://www.cleveroad.com/blog/react-vs-angular-ultimate-performance-research-2017#.WKMPN5BkZMM.twitter
Що таке мікросервіс?

Автор: Robert Reppel

В этой статье мы рассмотрим, что вкладывается в понятие «микросервис», в чем состоят преимущества микросервисов в разных сферах деятельности. Business и Project Management Создание микросервиса, который соответствует требованиям в контексте управления бизнесом и проектами, имеет большое значение для большинства разработчиков и ИТ-специалистов – это именно то, что приносит выигрыш. Микросервис представляет собой направленный на решение одной задачи фрагмент кода, который продолжает функционировать и правильно работать, даже если «весь мир остановился». С точки зрения управления проектами, ценность микросервиса заключается в том, что он проходит и продолжает работать без прямых зависимостей от других систем. Например, поскольку у него есть собственное хранилище данных, и он не делает никаких вызовов внешних API, чтобы получить необходимую для работы информацию, для микросервиса не важно, работает ли общая база данных/имеет ли она доступ к API. Это очень сильно сокращает накладные расходы на координацию с другими командами, потому что команда, владеющая сервисом, может намного легче выполнить свои задачи, не будучи заблокированной другими зависимостями. Усилия по обеспечению качества также значительно сокращаются, поскольку полностью автономная служба не может быть нарушена побочными эффектами от другого кода, который, например, обновляет одну и ту же общую базу данных. Если провести аналогию с едой и напитками, то причину создания микросервиса можно описать так: ваша кофеварка будет работать независимо от того, подключен тостер или нет. Для бизнеса корректно реализованная архитектура микросервиса подразумевает лучшие варианты для продукта: Если вы продаете онлайн виджеты и создаете сервис оплаты, можно будет предлагать сервис оплаты за любые другие товары или услуги, а не только за виджеты. Автономные микросервисы гораздо более универсальны при выходе на новые рынки. Ваша микроволновая печь будет полностью независима от посудомоечной машины. Хотя первоначально микроволновка предназначалась для использования в домах, она прекрасно справится с работой на яхтах и космических кораблях, независимо от того, идет ли речь о посудомоечной машине или нет. Computer Science Микросервис - это state machine. Его состояние представляет собой транзакционную границу. Представьте себе светофор: Цвет, который должен появиться, зависит от цвета, который светофор показывает на данный момент. Если «currentColor=green», тогда команда «Switch to next color» может работать правильно только в том случае, если никто другой не переключает свет на следующий цвет, пока обрабатывается ваша команда «Switch to next color». Так что любой «микросервис», который не представляет транзакционную границу, будет подвержен побочным эффектам от других компонентов системы (как на примере светофора). И больше не будет соответствовать бизнес- и управленческому пониманию микросервисов. Software Engineering Любой отдельный фрагмент кода, который можно рассматривать как черный ящик, где единственный способ связи с ним через его API, можно рассматривать как «микросервис». Когда микросервис оценивает бизнес-правила, то для принятия решений использует те источники информации, которые были переданы в предыдущих вызовах API, а также параметры текущего вызова API. Пример работы микросервиса в поиске событий или совместной работы событий на основе архитектуры.  Publish-subscribe – это хорошее решение для координации потока информации между службами, поскольку приводит к более слабой связи, чем в альтернативных вариантах. Известный Bezos memo расшифровывает это как для целых команд, так и для «микросервисов» любого размера. По каким причинам – смотрите выше в “Business и Project Management”. Не нужно читать об установке термостата центрального отопления, чтобы просто отрегулировать температуру морозильника. Networking & Infrastructure Микросервис представляет собой набор компонентов (например, контейнеров, логических или физических баз данных и т. д.), которые обеспечивают определенную часть бизнес-функций. Их можно создавать, уничтожать, масштабировать и контролировать как единое целое. Они продолжают работать правильно, даже если все остальные службы не работают. Хорошим показателем качества внедрения микросервиса и проектирования его инфраструктуры является возможность контроля, оповещения и масштабирования на основе запросов бизнеса, а не технических критериев. Например, «Обработка платежей не работает (... но выполнение заказа продолжает работать нормально)». Что означает «работа в нормальном режиме»? Если обработка платежей не работает, то как все может «работать в нормальном режиме»? Работа в нормальном режиме означает отсутствие ошибок и отсутствие ошибочного принятия решения из-за неправильных данных. Это может быть достигнуто посредством конечной согласованности. Например, выполнение заказа инициируется событием PaymentProcessed. Ни одно из них не может произойти, если обработка платежей не работает, поэтому выполнение будет завершать заказы, обработка платежей которых происходила до отключения, но не последующие. Когда обработка платежей вернется в оперативный режим, служба выполнения начнет получать события PaymentProcessed для пропущенных заказов и будет постепенно догонять. С точки зрения UX, это означает, что у предприятия есть варианты для разработки отказоустойчивых приложений. То есть вместо полного сбоя в работе, функции, которые обрабатываются незатронутыми микросервисами, могут оставаться доступными для пользователей. Вывод «Микросервис» ничем не отличается от многих компонентов, которые составляют сложную технику, окружающую нас каждый день: Минимальная зависимость от других механизмов («Требуется 12В от аккумулятора автомобиля и подключение к антенне») Четко определенный API как единственный способ взаимодействия с микросервисом («Единственный способ отрегулировать громкость – с помощью этой ручки»). Причины, по которым микросервисы работают в более развитых отраслях это: облегчение разделения труда, простое взаимодействие с механизмами и скорость их создания с меньшим количеством ошибок. Источник
Значні зміни у збирачі сміття в .NET 4.6.2

Автор: Maoni Stephens

В этой записи нашего блога мы хотели бы обсудить некоторые значительные изменения, которые были сделаны в сборщике мусора (GC от англ. garbage collector) .NET 4.6.х. Мы рекомендуем Вам использовать самую последнюю версию, 4.6.2. Наш главный разработчик, Маони Стивенс описала улучшения, которые были реализованы в 4.6.2. фреймворке. Эти изменения были сделаны для того, чтобы улучшить производительность фреймворка и позволить сборщику мусора работать более эффективно. Как сделать закрепление объектов более эффективным В предыдущих версиях .NET Framework, когда объект определялся как прошедший проверку закреплённый объект, мы не могли перемещать этот объект и смежные ему существующие объекты. Поскольку мы оставляем закрепленные объекты в поколениях 0 и 1 (таким образом вы сможете вскоре использовать свободное пространство между ними), это значит, что нам необходимо просматривать их во время выполнения сборки мусора. Если бы многие другие объекты вокруг закрепленных объектов пережили бы процесс сборки мусора, тогда время сбора мусора в 0 и 1 поколениях могло бы быть больше желаемого. Начиная с версии 4.6.2, это ограничение было отменено, так что мы можем собирать смежные существующие объекты вокруг закрепленных объектов. Во время тестирования мы заметили впечатляющие улучшения времени сбора в сценариях, где сборщик мусора искусственным образом закреплял многие объекты. На рисунке Before два не закрепленных объекта собираются, но не закрепленный объект рядом с закрепленным остается в gen0. В 4.6.х, это ограничение было отменено, так что мы можем переносить смежные существующие объекты вокруг закрепленных. Во время тестирования мы заметили впечатляющие улучшения времени сбора в сценариях, где сборщик мусора искусственным образом закреплял многие объекты. На рисунке After мы можем увидеть, что не закрепленный объект, следующий по отношению к закрепленному, переходит в следующее поколение: Если вы закрепляете много объектов, например, при длительных операциях ввода-ввывода, при этом наблюдаете длинные паузы сборщика мусора, вы, скорее всего, извлечете выгоду из этого изменения. Более эффективное использование свободного пространства во втором поколении В предшествующих версиях фреймворка при переносе объектов из поколения 1 в поколение 2 использовалась техника first fit, а это означало, что GC не использовал память, которая не подходила для хранения объекта. Эта техника приводила к потере памяти. На рисунке Before, мы видим, что F0 область освобождена, потому что была слишком мала для того , чтобы сохранить выживший объект S. Мы смогли поместить S в F1 при этом часть F1 остается (для дальнейшего уплотнения памяти при переносе из gen1). Чтобы улучшить этот подход и более эффективно использовать память, мы ввели список, в котором мы размещаем объекты слева направо в свободном пространстве в сегменте, который подходит по размеру. Мы должны очень аккуратно относиться к использованию маленьких сегментов, так как их может быть очень много. Также, мы работали над политиками определения сегмента, который следует попробовать использовать для хранения объекта, так как мі не хотим продлевать сборку мусора в первом поколении поиском свободного подходящего места в памяти. Мы хотим продолжать делать сборку мусора в фоновом режиме где это возможно, чтобы более эффективно использовать свободное пространство. На картинке After F0 остается в свободном списке и может быть использован для уплотнения памяти объектами из gen1. И мы сразу пробуем поместить S в F1. Если вы наблюдаете увеличение памяти gen2, то одной из причин может быть то, что у вас закончились элементы в свободно списке. Следовательно, продвижение оставшихся объектов из gen1 потребует увеличение размера gen2. Для сценариев, которым помогает это изменение, вы увидите, что размер gen2 увеличивается намного медленнее, и мы сможем разместить больше коллекций gen1 для каждой коллекции gen2. Это также означает, что вы будете видеть блокировку gen2 реже, потому что, когда куча становится слишком большой, это приводит к чрезмерной загрузке памяти, мы будем блокировать gen2 и выполнять уплотнение. В наших тестах, мы наблюдали сценарии, в которых соотношение количества сборов в поколениях gen1 и gen2 возросло в 20 к 1 -  более чем 200 сборам для поколения gen1 для каждого сбора в поколении gen2. Резюме Если вы столкнулись с ситуациями, описанными выше, вам обязательно нужно попробовать .NET 4.6.2, чтобы получить преимущества улучшений в сборщике мусора. Источник
Що таке Angular?

Автор: TJ VanToll

Иногда стоит обернуться назад и посмотреть на мир разработки глазами новичка. В компании Progress мы часто используем Angular. Angular — это основная составляющая нашего веб-фреймворка Kendo UI, так же, как и фреймворка для мобильных приложений NativeScript. Поэтому у нас часто спрашивают, что такое Angular и как его использовать. Когда появился Angular? Кем он поддерживается? Почему мы используем Angular? Когда его лучше не использовать? В этой статье мы ответим на эти и некоторые другие вопросы. Мы рассмотрим, что являет собой Angular, как он появился и в каких случаях его лучше всего применять. После этого кратко рассмотрим несколько примеров того, как работают Angular-приложения. Но давайте все по порядку. Как же появился Angular? Angular появился как side project. В 2009 году Miško Hevery и Adam Abrons выпустили проект под названием <аngular />, чтобы помочь разработчикам, а также и дизайнерам создавать веб-приложения, используя простые HTML-теги. Имя “Angular” пошло от угловых скобок или “<>”, которые обрамляли все теги. Например, < div >, < span > и другие.  Miško рассказал о том, как возникла идея создать фреймворк в интервью 2013 года: “Мы хотели понять, можно ли упростить работу веб-дизайнеров, а не только разработчиков. Смогут ли они добавить еще больше HTML в свой код, чтобы превратить обычную статическую форму во что-то более стоящее, что можно отправить по емейлу. Идея заключалась в следующем: будь у вас небольшой бизнес, продающий пиццу или что-либо другое, то вы могли бы добавить простую систему заказа, используя необходимые теги, и они действительно отправляли бы письмо на сервер." Поскольку домен angular.com был занят – собственно, как и сейчас – создатели фреймворка переименовали Angular в GetAngular и выпустили небольшой сайт, на котором можно было узнать о всех фичах фреймворка. Домашняя страница Angular по состоянию на декабрь 2009 года (из Internet Archive).  Скоро Miško начал работать в Google, а в 2010 году занялся проектом Google Feedback. Miško убедил своего менеджера, Brad Green, переписать проект, используя его Angular. Оптимизация сроков и кода, которые показала команда в работе, помогли убедить Google в силе Angular. Brad Green и Miško Hevery показывают, как много времени и сил удалось сэкономить на проекте, используя Angular. Это скриншот презентации на конференции ng-conf 2014 keynote, которую стоит посмотреть, если вы хотите знать всё о происхождении Angular. Вскоре после успеха Google Feedback та же команда переписала open-source библиотеку и в мае 2011 года была выпущена версия Angular 1.0. В течение нескольких лет Angular стремительно набирал популярность, и сегодня Google заявляет, что более 1,5 миллиона разработчиков используют Angular. Что делает Angular? Angular — фреймворк JavaScript, который помогает разработчикам создавать приложения. Библиотека предоставляет множество фич, которые делают простые реализации сложных задач современных приложений, таких как привязка данных, маршрутизация и анимация. Angular также представляет ряд конвенций о подходах к разработке приложений. Это может быть очень полезно для больших команд, которые должны работать вместе на одном проекте. Angular - это одна из немногих библиотек JavaScript, которые обеспечивают обширный style guide с большим количеством наглядных примеров того, как вы можете писать свой код, используя этот фреймворк. Когда использовать Angular? Технически вы можете использовать Angular где угодно, но лучше всего он работает в нестандартных приложениях с данными. Если вы ознакомитесь с различными приложениями Angular, собранными на madewithangular.com, вы увидите реальные приложения, которые собирают данные из форм и работают с ними. Angular работает не только с формами. Разработчики создали множество игр при помощи Angular и такие сумасшедшие вещи, как приложения с дополненной реальностью. Однако, большинство туториалов и документации по Angular все равно содержат информацию о создании некоторых form-based приложений. Например, вы встраиваете документацию Angular в приложение, где вы создали героев и их список через форму. Окончательный результат демо-приложения Tour of Heroes из Angular документации. Angular хорош в form-based приложениях, он подходит для больших и сложных приложений. Angular - не самый простой и не самый маленький фреймворк JavaScript. Следовательно, если вы создаёте нечто небольшое, вам лучше подобрать для работы фреймворк попроще, например, jQuery. Angular хорошо подойдёт для разработчиков приложений в средних и больших командах. Если вы разрабатываете приложение самостоятельно, может показаться, что шаблонного кода и конвенций разработки в Angular намного больше, чем вам нужно. Angular также хорошо подходит для приложений, которые должны работать в нескольких средах разработки. Если приложение должно работать на веб, а также на Windows или Maс, вы можете придерживаться одного из многочисленных туториалов для запуска Angular-приложений с популярным Electron project. Если же у вас приложение, которое нужно запустить на веб, iOS или Android, можете использовать NativeScript для рендеринга вашего приложения в мобильной среде. В некоторых случаях вы даже можете распространять код через эти платформы, экономя ценное время разработки. Кто поддерживает Angular? Angular Core Team состоит из большого количества людей во всем мире и из сообщества Angular. При этом большая часть разработок Angular изо дня в день осуществляется сотрудниками Google. Примерно 20 сотрудников Google входят в Angular Core Team и все ТОП-разработчики проекта Angular являются сотрудниками Google. Следует отметить, что, несмотря на контроль Google над Angular, сам фреймворк по-прежнему много в чём зависит от усилий сообщества. Более двух тысяч человек внесли свой вклад в open-source репозиторий Angular, в общем доступе есть бесчисленные туториалы и guides, многочисленные компании предлагают обучение и набор инструментов для разработчиков. Если контроль над проектом принадлежит одной компании, это неплохо, так как снижает конфликтные вопросы при принятия нестандартных решений. Какую версию Angular мне лучше использовать? На данный момент существует две популярные версии Angular. Версия 1 доступна на https://angularjs.org/  и является обновлённой версией того Angular, что был представлен Miško и его командой в 2011 году. Другая популярная версия теперь называется просто Angular и доступна на https://angular.io/. Современный Angular – это полностью переделанная версия для новых браузеров, рабочих процессов и платформ разработки. Почти во всех случаях вам следует придерживаться последней версии Angular. В ближайшем будущем команда Angular будет стремиться поддерживать Angular 1, но нет никаких оснований полагать, что они будут поддерживать и более старые версии. Более того, Angular 1 не допускает использования библиотеки вне браузера, поэтому вы не можете воспользоваться такими библиотеками, как NativeScript для создания мобильных приложений. Как выглядит Angular-приложение? Теперь, когда вы имеете некоторое представление об Angular, давайте углубимся в код. Начнём с небольшого приложения “hello world”. Все приложения Angular начинаются с НТМL-страницы, которая выглядит следующим образом. В реальном приложении тег < script > внутри тега < head > может быть немного сложным, но в высокоуровневых приложениях он такой же, как и другие веб-приложениях – вы загружаете кусок JavaScript-кода в HTML-документ, и приложение работает.   Есть одна уникальная вещь в выше приведённом примере – элемент < my-app >. Вы не используете этот элемент регулярно в веб-приложении. Цель Angular – постоянно расширять словарь НТМL, позволяя вам определять собственные теги. Такие пользовательские теги называют компонентами, и вы можете определять их поведение в коде. Вот простейшая реализация элемента < my-app >: Есть несколько моментов, которые вам нужно знать, чтобы понять, что происходит в данном фрагменте кода. Первое – это код на TypeScript, а не на JavaScript. TypeScript может показаться вам пугающим, если вы не встречались с ним раньше, но его основы понять нетрудно. TypeScript – надстройка над JavaScript, то есть весь синтаксис JavaScript доступен на TypeScript. Кстати, весь приведённый выше синтаксис – import, export, @Component и остальные – это или нынешние фичи JavaScript, или те, что появятся в ближайшем будущем. Так что, когда вы учите TypeScript, вы изучаете будущее JavaScript. TypeScript, к тому же, отличается превосходной документацией, к которой вы можете обратиться в любое время. TypeScript был создан и поддерживается Microsoft. Он стал очень популярным за последние несколько лет, поэтому можете смело использовать его в разработке своих приложений. Он никуда не денется. Давайте еще раз посмотрим на TypeScript-код, определяющий компонент < my-app >: В Angular вы используете тег @Component, который известен как декоратор, чтобы отметить классы, которые учитывают элементы, которые могут быть использованы в вашей HTML-разметке. У вас есть возможность передавать свойства @Component для описания элемента.  Свойство selector определяет имя тега при вводе в HTML. Использование селектора < my-app > показывает Angular, что делать, когда он видит тег < my-app > в HTML. Свойство template контролирует, что HTML должен делать, когда используется компонент. Пример использования template: "< h1 >Hello World< /h1 >", тут видно, как Angular определяет, какие действия применять при < my-app > и почему это приложение представляет базовый тег < h1 > при предварительном просмотре в браузере.  Отображение базового примера “Hello World” в браузере. Зачем мне использовать Angular? Angular- не самый простой в мире фреймворк, и понадобится время, чтобы понять те концепции, на которых он построен. Но когда вы возьметесь за Angular, то сможете делать действительно крутые приложения, обходясь небольшим количеством кода. Например, вы хотите добавить привязку данных к предыдущему примеру. Для этого используется очень простой синтаксис. Хотите построить форму для запуска приложения? Хотите, чтобы эта форма имела валидацию данных и двустороннюю привязку? Для этого есть простой гайд. Ваше приложение слишком большое и вы хотите структурировать его? И для этого тоже создан гайд. Попали в модульное тестирование и хотите знать, как проверить код? Такая возможность тоже есть. Хотите добавить такие профессиональные виджеты, как диаграммы и графики? Kendo UI и похожие фреймворки упрощают добавление этих высококачественных компонентов пользовательского интерфейса. Пользуясь Angular, не рассчитывайте на простоту фреймворка, но будьте уверены в его невероятной надёжности и хорошей документации. Этот фреймворк прошёл не одно боевое испытание и заслужено используется миллионами разработчиков для написания крутых приложений. Сообщество Angular – огромное, и все хелпы легко найти в Google, Stack Overflow и по всему интернету. Ищите разработчика? Тысячи Angular девелоперов откликнутся на ваш запрос. Есть даже специальные рекрутинговые сайты. Я уже упоминал о том, что Angular – мультиплатформенный? Вернемся к нашему примеру Hello World. У вас уже есть начало для iOS и Android приложения – просто переключите элемент HTML на компонент, который NativeScript может отобразить в мобильной среде, как , например. Вот так примерно будет выглядеть код. А вот как этот код работает в нативных iOS и Android приложениях. Angular делает это и многое другое возможным. От создания потрясающих приложений до расширения мультиплатформенной разработки, Angular может стать отличным решением для вашего следующего проекта.   Если вы ищите больше информации о том, что может предложить Angular, начинайте изучать туториалы по быстрому старту работы с Angular и начинайте кодить. Если вы хотите использовать Angular для разработки мобильных приложений, посмотрите, как использовать его с NativeScript. Вы изучите один из самых популярных фреймворков JavaScript, когда будете знакомиться со столь популярным миром мобильной разработки. Оригинал статьи: http://linkis.com/telerik.com/7vemI
Angular vs React - що крутіше?

Автор: Dominik T

Angular – технология с полным набором инструментов и к тому же с лучшими вариантами подхода к решению. Кому-то он подходит, а кому-то – нет. С другой стороны, React – небольшая технология, которая необходима вам только при создании какого-то приложения.  Обе технологии имеют свои достоинства и недостатки. Какая из них подойдёт вам больше? Попытаемся выяснить в этой статье. Технологии Вот основные технологии, о которых я буду говорить: Angular React Vue Кривая обучения Допустим, вы знаете JavaScript + ES2015 достаточно хорошо. Какую следующую технологию будет проще выучить? Vue – наилучший выбор, если вы ищите легкости в процессе изучения технологии. React – менее абстрактный, тем не менее, вам понадобится больше времени, чтобы изучить best practices, так как есть много вариантов написать одно и то же или ошибиться. А вот после изучения Angular вы также будете знать всё, что связанно с ним (typescript, MVC…). Angular - большая технология и учить придётся долго.   Масштабируемость Angular - легко масштабируемый благодаря своему дизайну, который так же хорош, как и мощная командная строка. React требует больше проверок и поэтому более масштабируемый, чем Vue и, я думаю, что частично это правда. Vue идёт сразу после React. Он хорош, однако ему не хватает лучших практик масштабируемости, из-за чего вы получаете очень запутанный код. Совместимость с другими технологиями React. Несмотря на то, что он не работает с DOM-деревом, он основан на чистой JavaScript логикe и популярeн настолько, что содeржит в сeбe альтeрнативы библиотeкам, работающим с DOM. Vue прекрасно работает как с ДОМ-деревом, так и с JavaScript. Второе место занимает лишь потому, что у него меньше библиотек, которые могли бы быть действительно полезны для обоих (как для ДОМ, так и для JavaScript). Angular мог бы быть лучше, если бы не typescript, который требует строгой типизации.   Инструменты React, Angular and Vue. Все перечисленные технологии имеют отличные CLI и работают с любым инструментом по типу webpack. Пользователи и популярность React точно стал наиболее популярным в 2016, когда его стали использовать англоговорящие frontend и full stack разработчики. React – хороший выбор для мобильных и даже десктопных приложений на JavaScript. Vue и Angular. Vue – потому что он очень быстро развивается. Angular – потому что он создан Google, а его предшественник Angular 1 был когда-то очень популярен. Востребованность React и Angular. В зависимости от того, где вы находитесь, зависит, какая технология будет доминировать. Angular больше используют в Азии, особенно в Индии, а React – в англоязычных странах, таких как US и UK. Vue менее популярен и не поддерживается большими компаниями, поэтому остальные отдают предпочтение Angular и React. Производительность По этому параметру не ставлю ранги, так как все они сопоставимы. Возможно, React станет немного быстрее, когда полностью будет поддерживать Fiber, но сейчас существует только бета-версия. Перспективы для компаний Angular имеет open source лицензию. Он поддерживается Google, что, возможно, делает его лучшим выбором для компании, и разница между проектами Angular невелика.    React был бы очень хорошим выбором, если бы не лицензия с патентом. Однако, существуют бесплатные альтернативы, которые работают также, как и React. Например, Infernojs или мой любимый rax. Vue – не дитя большой компании, это очень успешный сторонний проект одного человека. Компании часто игнорируют его, хотя, возможно, и не стоило бы. Вне сети Рендеринг –  как раз то, о чем можно много говорить. Все технологии способны осуществлять его, но некоторые справляются лучше, чем другие. React – лучший выбор благодаря react native, alibaba rax, reactWindows и next.js. Vue подойдёт vue-разработчикам, которые предпочитают разработку под мобильные устройства. Спасибо за это alibaba weex. У Angular есть ionic 2 и nativescript, но эти технологии не позволяют достичь производительности react native. Простота и длина кода Vue имеет предварительно встроенные привязки данных и MVC модель, его легче настроить, нежели Angular и React. React пугающе прост для понимания, но нужно реально много времени, чтобы настроить react project. Angular совсем непростой. Эта сложность вызывает много путаницы 3rd party libraries и синтаксиса. Время разработки Vue, безусловно, лёгок в установке и не требует много изменений или синтаксиса, за что его и любят. Он был создан для борьбы с утомительной работой. React настраивается дольше, но после начала работы над приложением будет легко добавлять новые фичи. Angular хоть и является весьма конкурентоспособным, но количество ненужного синтаксиса, который он требует для работы простых вещей, отбрасывает его на последнее место. Размер Vue - наименьший и много в себе содержит. Вы можете подумать, что это не имеет значения, но если речь пойдёт о дешёвом Android 3G смартфоне, то вы уже не будете так уверены. React - больше чем Vue, но все же меньше, чем Angular. Angular - больше всех предыдущих, что вызывает увеличение времени загрузки и проблемы производительности на мобильных устройствах. Будущее Вот лично мои прогнозы для этих технологий на 2017 год: Vue будет приобретать популярность и всё большее количество разработчиков переключится на него. Вполне вероятно, что это может заставить крупные компании продвигать и поощрять Vue. Команда React представит Fiber  и сделает React быстрее, чем Vue и Angular. Создатели Angular попытаются привлечь больше людей, но, скорее всего, им это не удастся. Так что же лучше для вас? Подводя итог, можно сказать, что нет идеального решения, и никогда не будет. Тем не менее, вот полезные советы, которые помогут вам сделать выбор: Если вы разработчик «до мозга костей», тогда попробуйте все и выбирайте между Vue или React, доверяйте своему чувству. Если вы новичок в разработке, выбирайте или Vue, или React. Angular подойдёт компаниям с большими командами. Google -> Angular. Если любите простоту, тогда выбирайте Vue. Если нравится использовать шаблоны, тогда выбор стоит между Vue или Angular. Если предпочитаете JavaScript и JSX, попробуйте поработать с каждой технологией. Если вы работаете с Typescript, используйте Angular или Vue. Выбирайте подходящую технологию поскорее, не стоит пребывать в неопределённости. Я сомневался несколько месяцев, и это было невесело. Я решил пожертвовать популярностью и выбрал то, что считал для себя наилучшим вариантом – Vue. Ютубер funfunfunction сказал лучшее, что я когда-либо слышал про JS framework fatigue: «Существует точка в вашей карьере программиста, когда вы понимаете, что это не лучший инструмент». Здесь нет правильного или неправильного выбора, его просто необходимо сделать. Так что, продолжайте учиться и исследовать. Все будет учить Вас чему-то новому. Оригинал статьи на английском языке. 
Чи змінить нашу віртуальну реальність (VR) нашу роботу?

Автор: Редакция ITVDN

Мир технологий стремительно проникает во все сферы нашей жизни. Big data и  достижения в области вычислительной техники постоянно повышаются и, соответственно, повышают уровень повседневной жизни, предоставляя больше доступных возможностей в решении проблем и предлагая больше средств для повышения наших знаний. Виртуальная реальность  стала последним достижением популярных технологий. Идея создания VR находилась в разработке в течение многих лет и совсем недавно стала реальностью, которая способна изменить нашу жизнь, и особенно нашу рабочую среду. Простой интернет-запрос выдаст, что устройства, поддерживающие VR, уже можно приобрести для личного пользования. Они особенно популярны в игровой индустрии в таких компаниях, как PlayStation, Facebook и Xbox, которые предлагают механизмы виртуальной симуляции для усиления интерактивного опыта и создания связей по всему земному шару. Однако виртуальная реальность стала чем-то большим, нежели просто геймерской фишкой. Она предлагает бесконечные возможности в различных отраслях и уже используется для улучшения работы как в нефтегазовой промышленности, так и в автомобильной индустрии. Передовая технология оказывает значимое влияние на обучение и образование, где её преимущества огромны. Возьмём медицину, например. Недавно врачи смогли провести операцию на открытом сердце, используя загруженные файлы компьютерных сканирований и VR-технологию. Будучи в состоянии визуализировать опыт и моделировать среду, виртуальная реальность даёт возможность практиковать и развивать навыки совершенно революционным путём. Так же, как и моделирование медицинских процедур, компании имеют возможность демонстрировать повышенную подготовку к торговым показам для сотрудников или даже для клиентов, чтобы они испытали продукт или услугу за счёт использования виртуальной реальности. Возможности, предоставленные технологиями VR,  наряду с повышением навыков и психологической подготовкой, станут большим достижением в мире деловых отношений. То же самое относится и к строительству, маркетингу, e-commerce, туризму и в значительной степени к индустрии развлечений. TechNet IT и Melody VR совершают огромный прогресс в мире музыки благодаря живым концертам и использованию технологий виртуальной реальности. Наушники VR позволят фанатам не только слушать музыку или смотреть клипы, но и окунуться в  атмосферу живого шоу, ощутить эффект присутствия. Этот тип интерактивной VR открывает широкие возможности благодаря  доступности, устраняя такие препятствия, как время и деньги. Для преуспевания компании в условиях постоянной конкуренции виртуальная реальность обеспечивает неограниченную способность к расширению границ, преодолению барьеров и максимизации производительности. Всего лишь имея доступ к развитию навыков обучения на работе и запуску новых продуктов, компании смогут привлечь больше клиентов и сотрудников, что, вероятнее всего, приведет бизнес к росту по всем показателям. В конечном итоге, VR может полностью трансформировать наше восприятие вещей, и даже есть вероятность того, что это плохо скажется на нашем взаимодействии друг с другом, работе, учёбе, коммуникации и общении с другими людьми. Это создает совершенно новый способ получения опыта в жизни, и VR может стать важной частью нашей деятельности до такой степени, что мы не будем знать, как мы жили без этой технологии раньше. А что вы думаете о виртуальной реальности?
Notification success