Why Pay for Entertainment? Access Thousands of Free Downloads Now!

.NET Разработчик

Description
Дневник сертифицированного .NET разработчика.

Для связи: @SBenzenko

Поддержать канал:
- https://boosty.to/netdeveloperdiary
- https://patreon.com/user?u=52551826
- https://pay.cloudtips.ru/p/70df3b3b
We recommend to visit

⚡️Все самое важное в одном канале. Новости России и Мира.

Ссылка для друзей - https://t.me/+gFCT63NlnfE5YWZi

Самый большой канал в РФ

Обратная связь: @rob_lower

Last updated 5 days, 12 hours ago

🛒 Магазин сообществ в соц. сетях 24/7
⚡️ В наличии любые тематики и количества, связь в ЛС @timur_chik1


ac99e5f0c33c6df9805b

Last updated 6 months ago

NN
NN
1,378,925 @naebnet

Медиа про интернет, технологии и безопасность

Сотрудничество: @nnmanager
Ютуб: https://youtube.com/naebnet

Last updated 12 hours ago

6 days, 17 hours ago

День 1878. #УрокиРазработки Уроки 50 Лет Разработки ПО

Урок 1. Если вы неверно определили требования, неважно, как хорошо вы выполните остальную часть работы
IT-отдел взялся за создание новой информационной системы для своей компании. Разработчики считали, что прекрасно понимают требования и без опроса пользователей. Однако реакция пользователей на готовую систему была: «А если серьезно, где наше приложение?» Они категорически забраковали систему. Отказ от взаимодействия с пользователями, которое помогает убедиться в правильном понимании требований, был серьёзным упущением. Разработчики в итоге переделали систему, на этот раз внимательно прислушиваясь к пользователям. Это был дорогой урок о важности участия клиента в составлении требований.

Требования — это фундамент для всей последующей работы над проектом. Многочисленные исследования показали, что эффективная разработка и своевременное информирование о требованиях являются решающими факторами успеха любого проекта. И наоборот, неадекватное ви́дение проекта, неполные и неточные требования, а также меняющиеся требования и цели проекта — частые причины неудачи. При отсутствии качественной проработки требований заинтересованные стороны могут удивиться тому, что предлагает команда разработчиков. Такие программные сюрпризы часто оказываются неприятными.

Когда?
Нереально иметь полный набор требований перед началом реализации. Всегда будут появляться новые идеи, изменения и исправления, которые вы должны учитывать в своих планах развития. Но для любой части системы, которую вы создаёте, необходимо иметь как можно более полные и правильные требования. Либо планируйте доработку после окончания реализации. В проектах, практикующих Agile, предусмотрен дополнительный этап проверки требований. Чем дальше первоначальные требования от того, что действительно нужно клиентам, тем больше доработок понадобится. Учитывая, что всегда можно что-то добавить, вы никогда не сможете идеально выполнить требования. Но оговорённый объём разработки требует, чтобы вы сделали всё правильно, иначе успеха не видать.

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

Как?
Ничто не заменит постоянного взаимодействия с клиентами. Нельзя просто провести встречу в самом начале, а затем сказать клиентам: «Мы позвоним вам, когда закончим». В идеале команда должна быть на связи с представителями клиентов на протяжении всего времени разработки проекта. У разработчиков будет много вопросов и моментов, требующих уточнения.

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

Не всегда получается уговорить клиентов на такое тесное взаимодействие. Один из способов убедить клиента — привести примеры проблем, с которыми столкнулась организация из-за недостаточного участия клиентов в разработке продукта. Ещё лучше рассказать об опыте, когда взаимодействие с клиентами окупилось. Другой метод — предложить чёткий план взаимодействий для уточнения требований, который может предусматривать ряд неформальных обсуждений, встреч, обзоров требований и утверждения эскизов, прототипов и последовательности релизов.

Клиенты вероятнее позитивно оценят проект и будут охотнее вносить свой вклад, если будут видеть прогресс, например в виде периодического выпуска новых версий работающего ПО. Иногда трудно убедить заказчиков принять обновлённую программную систему. Представители заказчиков, работавшие с командой разработчиков, знающие суть нововведений и понимающие их необходимость, могут помочь облегчить этот переход.

Источник: Карл Вигерс “Жемчужины Разработки”. СПб.: Питер, 2024. Глава 2.

1 week ago

День 1877. #ЧтоНовенького Garnet — Быстрое Хранилище Кэша с Открытым Кодом
Исследователи Microsoft уже почти десять лет работают над механизмами хранения данных для поддержки быстрого развития интерактивных веб-приложений и сервисов. Новая система хранения кэша Garnet, которая предлагает ряд преимуществ по сравнению с другими хранилищами кэша, была развернута в нескольких сервисах в Microsoft, например, в платформе Windows & Web Experiences, Azure Resource Manager и Azure Resource Graph, а также теперь доступна для загрузки.

Проблема с хранилищем кэша
Программный уровень хранилища кэша, развернутый как отдельно масштабируемый удаленный процесс, может снизить затраты на запросы данных и повысить производительность приложений. Это способствовало развитию индустрии хранилищ, включая многие системы с открытым исходным кодом, такие как Redis, Memcached, KeyDB и Dragonfly.

Современные кэши предлагают богатые API и наборы функций: необработанные строки, аналитические структуры данных, такие как Hyperloglog, и сложные типы данных, такие как отсортированные наборы и хэши. Они позволяют пользователям задавать точки восстановления и восстанавливать кэш, создавать фрагменты данных, поддерживать реплицированные копии, а также поддерживать транзакции и пользовательские расширения.

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

Garnet
В Microsoft Research работу над базой данных «ключ-значение» начали в 2016 году, тогда она называлась FASTER. С 2021 года, основываясь на требованиях сценариев использования, в Microsoft начали создавать новое удаленное хранилище кэша со всеми необходимыми функциями – Garnet.

Преимущества
1. Использует популярный протокол RESP, что позволяет использовать Garnet из немодифицированных клиентов Redis, доступных сегодня в большинстве языков программирования.
2. Предлагает гораздо лучшую масштабируемость и пропускную способность благодаря множеству клиентских подключений и небольшим пакетам, что приводит к экономии затрат для крупных приложений и сервисов.
3. Меньшие задержки на 99-м и 99,9-м процентилях, что имеет решающее значение для реальных сценариев.
4. Кроссплатформенный, расширяемый и современный. Cпроектирован таким образом, чтобы под него можно было легко разрабатывать ПО без ущерба для производительности. Благодаря использованию .NET, обеспечивает высочайшую производительность как в Linux, так и в Windows.

Возможности
1. Широкий спектр API, включая необработанные строки, аналитические и объектные операции, описанные ранее.
2. Режим кластера с сегментированием, репликацией и динамической миграцией ключей.
3. Транзакции RESP на стороне клиента и хранимые процедуры на стороне сервера на C#, что позволяет пользователям определять собственные операции как с необработанными строками, так и с новыми типами объектов.

Производительность
Судя по тестам в созданной Microsoft (sic!) утилите Resp.benchmark, Garnet превосходит конкурентов по производительности. Подробности можно найти здесь.

Кластерный режим
Помимо выполнения на одном узле, Garnet поддерживает режим кластера, который позволяет пользователям создавать и управлять сегментированным и реплицируемым развёртыванием. Garnet также поддерживает эффективную и динамическую схему миграции ключей для перебалансировки узлов. Пользователи могут использовать стандартные команды кластера Redis для создания кластеров Garnet и управления ими, а узлы общаются между собой для обмена данными и развития состояния кластера.

Источник: https://www.microsoft.com/en-us/research/blog/introducing-garnet-an-open-source-next-generation-faster-cache-store-for-accelerating-applications-and-services/

1 week, 1 day ago

День 1876. #Курсы Изучаем ИИ в .NET 8 с помощью Новых РуководствЕсли вы думали о том, чтобы внедрить в свои .NET-приложения искусственный интеллект и большие языковые модели (LLM), сейчас самое время. Microsoft предлагают новые краткие руководства, которые помогут вам.

Недавно выпущены несколько кратких руководств с практическими примерами приложений, которые вы можете использовать с большими языковыми моделями от OpenAI (скоро появятся и другие модели):
- Саммари текста
- Построение приложения чата
- Анализ данных в ИИ-чате
- Azure функция с ИИ
- Генерация изображений

Каждое из них по шагам знакомит вас с кодом, необходимым для выполнения этой темы, с использованием Azure OpenAI SDK. Скоро мы также будут добавлены версии этих примеров с использованием Semantic Kernel SDK.

Если ChatGPT, LLM, модели и OpenAI — это новые для вас термины или вы только начинаете работать в этой области, вот несколько дополнительных ресурсов, которые вы можете использовать, чтобы помочь изучить основные концепции:
- Get started with OpenAI in .NET – Об использовании OpenAI в .NET.
- Get started with OpenAI Completions with .NET – Введение в завершения с помощью OpenAI: ответы, генерируемые такой моделью, как GPT.
- Level up your GPT game with prompt engineering – Введение в запросы к ИИ, как их усовершенствовать и получать более релевантные результаты.
- Get started with ChatGPT in .NET - Описывает, что такое ChatGPT, а также основные понятия, такие как роли и история чата.
- Плейлист видео: Generative AI with .NET for Beginners

В Microsoft ждут ваших отзывов и предложений о вашем опыте изучения ИИ в .NET и о том, как сделать его лучше. Вы можете принять участие в опросе разработчиков .NET + AI.

Источник: https://devblogs.microsoft.com/dotnet/get-started-with-dotnet-ai-quickstarts/

1 week, 6 days ago

День 1871. #ВопросыНаСобеседовании#ASPNET Самые часто задаваемые вопросы на собеседовании по C#

30. Какие существуют возможности управления конфигурацией приложения .NET Core в разных средах (разработка/тестирование/производство)?

.NET Core предоставляет решение для управления конфигурациями в различных средах с помощью поставщиков конфигурации.

Во-первых, задать среду. Приложения .NET Core делают это, читая переменную окружения ASPNETCORE_ENVIRONMENT. Значение по умолчанию – "Production". Формально значение может быть любым, но лучше придерживаться одного из трёх стандартных:
- Development
- Staging
- Production
Это даст доступ, например, к методам расширения, таким как IHostingEnvironment.IsDevelopment(). Значение можно задать в переменных окружения машины. IDE, такие как Visual Studio, также могут брать это значение из файла launch.json из корня проекта.
Кроме того, среду можно задать принудительно в коде, вручную настроив веб хост:

var builder = new WebHostBuilder() .UseEnvironment(Environments.Production) .UseKestrel() .… ;

Среда определяется на раннем этапе старта приложения, поэтому дальнейшую настройку можно определять в зависимости от среды. Например, для управления конфигурацией можно использовать файл appsettings.json, который является файлом по умолчанию, считываемым приложением .NET Core. Можно иметь отдельные файлы конфигурации для каждой среды, например appsettings.Development.json или appsettings.Production.json, что даёт возможность переопределить настройки по умолчанию.

Вообще есть несколько вариантов настройки:
1. Использовать различные настройки в коде в зависимости от среды, например:

… if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } …

  1. Использовать различные файлы appsettings.{Environment}.json для хранения конфигураций, специфичных для среды.

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

  3. Важно исключить конфиденциальные данные, такие как строки подключения и секреты приложений, из системы управления версиями (например, файлов appsettings.json). Их лучше хранить либо в переменных среды, либо использовать безопасные методы, такие как пользовательские секреты в среде разработки или сервисы вроде Azure Key Vault в производственной среде.

В приложении использовать интерфейс IConfiguration для доступа к настроенным параметрам. См. подробнее.

См. также про изменения в конфигурации введённые в .NET6.

Источники:
-
https://dev.to/bytehide/net-core-interview-question-answers-4bc1 - Эндрю Лок “ASP.NET Core в действии”. 2-е изд. – М.: ДМК Пресс, 2021. Глава 11.

2 weeks ago

День 1870. #Шпаргалка#Git Популярные Настройки Git Config. Окончание
Начало
Продолжение

13. includeIf: отдельные конфигурации git для личного и рабочего
Многие используют это для настройки разных email для личных и рабочих репозиториев. Вы можете настроить это примерно так:

[includeIf "gitdir:~/code/<work>/"] path = "~/code/<work>/.gitconfig"

14. url."git@github.com:".insteadOf 'https://github.com/'
Если вы часто случайно клонируете HTTP-версию репозитория вместо SSH-версии, а затем приходится вручную заходить в ~/.git/config и редактировать удалённый URL, это заменит https://github.com в удалённых репозиториях на git@github.com:

[url "git@github.com:"] insteadOf = https://github.com/

Кто-то вместо этого использует pushInsteadOf для замены только в git push, потому что не хочет разблокировать свой SSH-ключ при извлечении из общедоступного репозитория.

15. fsckobjects
Проверяет получаемые/отправляемые объекты. Если будет обнаружено повреждение или ссылка на несуществующий объект, операция прервётся:

transfer.fsckobjects = true fetch.fsckobjects = true receive.fsckObjects = true

16. Остальное
- blame.ignoreRevsFile .git\-blame\-ignore\-revs
Позволяет указать файл с коммитами, который следует игнорировать во время git blame, чтобы гигантские переименования не мешал.
- branch.sort \-committerdate
Заставит git branch сортировать ветки по последнему использованию, а не по алфавиту, чтобы упростить поиск ветвей. tag.sort taggerdate аналогично для тегов.
- color.ui false
Отключает подстветку.
- core.autocrlf false
В Windows для работы совместно с коллегами на Unix.
- core.editor emacs
Использовать emacs (или другой редактор) для сообщений коммита.
- diff.tool difftastic
Использовать difftastic (или другой редактор) для отображения различий.
- merge.tool meld
Использовать meld (или другой редактор) для разрешения конфликтов слияния.
- fetch.prune true и fetch.prunetags
Автоматически удалит локальные ветки и теги, которых больше нет в удалённом репозитории.
- gpg.format ssh
Позволит подписывать коммиты ключами SSH.
- log.date iso
Отобразит даты как 2024-03-14 15:54:51 вместо Thu Mar 14 15:54:51 2024
- merge.keepbackup false
Чтобы избавиться от файлов .orig, которые git создаёт при слиянии конфликтов.
- push.followtags true
Добавит новые теги вместе с добавляемыми коммитами.
- rebase.missingCommitsCheck error
Не позволит удалять коммиты во время rebase.

Источник: https://jvns.ca/blog/2024/02/16/popular-git-config-options/

2 weeks, 1 day ago

День 1869. #Шпаргалка#Git Популярные Настройки Git Config. Продолжение
Начало

5. push.default simple и push.default current
Параметры push.default сообщают git push автоматически отправлять текущую ветку в удалённую ветку с тем же именем.
- push.default simple — значение по умолчанию в Git. Это работает только в том случае, если ваша ветка уже отслеживает удалённую ветку.
- push.default current - аналогична, но она всегда передаёт локальную ветку в удалённую ветку с тем же именем.
current кажется хорошей настройкой, если вы уверены, что никогда случайно не создадите локальную ветку с тем же именем, что и несвязанная удалённая ветка. У многих людей есть соглашения об именах веток (например, julia/my\-change), которые делают конфликты такого рода маловероятными, либо у них просто мало сотрудников, поэтому конфликтов имён ветвей, вероятно, не происходит.

6. init.defaultBranch main
Создавать ветку main вместо ветки master при создании нового репозитория.

7. commit.verbose true
Добавит все различия коммита в текстовый редактор, где вы пишете сообщение о коммите, чтобы помочь вам запомнить, что вы делали.

8. rerere.enabled true
Позволяет использовать функцию rerere (reuse recovered resolution - повторно использовать восстановленное разрешение), которая запоминает, как вы разрешали конфликты слияния во время git rebase, и автоматически разрешает конфликты за вас, когда это возможно.

9. help.autocorrect 10
Если git обнаружит опечатки и сможет определить ровно одну действительную команду, аналогичную ошибке, он попытается предложить правильную команду или даже автоматически запустить предложение. Возможные значения:
- 0 (по умолчанию) - показать предложенную команду.
- положительное число - запустить предложенную команду через указанные децисекунды (0,1 секунды).
- "immediate" - немедленно запустить предложенную команду.
- "prompt" - показать предложение и запросить подтверждение для запуска команды.
- "never" - не запускать и не показывать предлагаемые команды.

10. core.pager delta
«Пейджер» — это то, что git использует для отображения результатов git diff, git log, git show и т. д.
delta – это модный инструмент для просмотра различий с подсветкой синтаксиса.

11. diff.algorithm histogram
Алгоритм сравнения Git по умолчанию часто плохо справляется с переупорядочением функций. Например:

```
-.header {
+.footer {
margin: 0;
}

-.footer {
+.header {
margin: 0;
+ color: green;
}
```

Это сильно путает. Но с diff.algorithm histogram всё становится гораздо понятнее:

```
-.header {
- margin: 0;
-}
-
.footer {
margin: 0;
}

+.header {
+ margin: 0;
+ color: green;
+}
```

Ещё один популярный вариант - patience.

12. core.excludesFile – глобальный .gitignore
core.excludesFile = ~/.gitignore позволяет установить глобальный файл gitignore, который применяется ко всем репозиториям, для таких вещей, как .idea или .vs, которые вы никогда не хотите коммитить в какой-либо репозиторий. По умолчанию это ~/.config/git/ignore.

*Окончание следует…

Источник:* https://jvns.ca/blog/2024/02/16/popular-git-config-options/

2 weeks, 5 days ago

День 1865. #ЗаметкиНаПолях Безопасность Типов в xUnit с Помощью TheoryData<T>
В xUnit есть небольшая, но очень полезная особенность – класс TheoryData<T>.

Проблема
Имеем следующий код тестов репозитория:

```
public static IEnumerable<object[]>
Data => new List<object[]>
{
new object[] {
new Action<IServiceCollection>(
s => s.UseSqliteAsStorageProvider())
},
new object[] {
new Action<IServiceCollection>(
s => s.UseSqlAsStorageProvider())
},
new object[] {
new Action<IServiceCollection>(
s => s.UseInMemoryAsStorageProvider())
}
};

[Theory]
[MemberData(nameof(Data))]
public void TestStorageProvider(
Action<IServiceCollection> act)
{ … }
```

Проблема здесь в том, что данные имеют тип IEnumerable<object[]>, а параметр act — тип Action<IServiceCollection>. То есть теоретически можно передать в метод что угодно, и компилятор с радостью это примет. Вот тут-то и пригодится TheoryData<T>.

Решение
TheoryData<T> — это класс, который позволяет обертывать данные строго типизированным способом. Например:

```
public static TheoryData<Action\<IServiceCollection>>
Data => new()
{
s => s.UseSqliteAsStorageProvider(),
s => s.UseSqlAsStorageProvider(),
s => s.UseInMemoryAsStorageProvider()
};

[Theory]
[MemberData(nameof(Data))]
public void TestStorageProvider(
Action<IServiceCollection> act)
{ … }
```

Точно такой же тест, но более типобезопасный. Теперь компилятор не позволит передать в метод ничего, кроме Action<IServiceCollection>.

Источник: https://steven-giesel.com/blogPost/a8aa3385-8829-444a-b269-7ecb38aeaf2f/typesafety-in-xunit-with-theorydatat

2 weeks, 6 days ago

День 1864. #ЗаметкиНаПолях Необязательные Параметры Могут Быть в Середине
В .NET необязательные параметры не всегда должны быть последними параметрами в сигнатуре метода. Хотя C# не позволяет объявлять необязательные параметры в середине, это можно сделать в IL или других языках, таких как VB.NET или F#. Кроме того, компилятор может создавать методы с необязательными параметрами в середине списка параметров.

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

Чтобы лучше понять суть вопроса, начнём с простого примера. Следующий код недопустим в C#:

// CS1737 Optional parameters must appear after all required parameters void Sample(int a = 1, int b) { }

При компиляции метода с необязательными параметрами компилятор заменяет синтаксис C# двумя атрибутами: [Optional] и [DefaultParameterValue]. Атрибут [Optional] используется для пометки параметра как необязательного, а атрибут [DefaultParameterValue] используется для установки значения по умолчанию. Следующий код допустим в C#:

```
// Вывод: 42
Sample(b: 2);

// Объявляем "a" как необязательный
// со значением 40 по умолчанию
void Sample(
[Optional, DefaultParameterValue(40)]
int a,
int b)
{
Console.WriteLine(a + b);
}
```

Обратите внимание, что компилятор C# более строг, чем в других языках, в отношении допустимых значений в [DefaultParameterValue]. Он гарантирует, что тип значения совпадает с типом параметра, но может не допускать некоторых допустимых преобразований. Например, следующий код будет допустим в VB.NET или F#, но не в C#:

// CS1908 The type of the argument to the DefaultParameterValue attribute must match the parameter type void Sample( [Optional, DefaultParameterValue(default)] CancellationToken cancellationToken) { }

Тот же метод в F# допустим:

type Class1 = static member Sample( [<Optional; DefaultParameterValue(CancellationToken())>] ct: CancellationToken) = ()

Кстати: даже компилятор C# может сгенерировать метод с необязательными параметрами в середине списка параметров. При создании индексатора с необязательными параметрами компилятор генерирует метод с необязательным параметром в середине:

// Создаёт метод (set\_Item) с необязательным параметром в середине // int set\_Item(int a, int b = 2, int value) public int this[int a, int b = 2] { set { } }

Источник: https://www.meziantou.net/optional-parameters.htm

3 weeks ago

День 1863. #ЗаметкиНаПолях REST vs RESTful. В чём Разница? Окончание
Начало

RPC через HTTP vs RESTful
Часто говорят, что сервис «не REST», из-за неправильных URI или использования глаголов HTTP. Имеется в виду представление данных REST как единообразного набора ресурсов.

Это различие иногда формулируется как различие между вызовами удаленных процедур (RPC) и REST. Представьте себе веб-сервис для перечисления, добавления и удаления товаров онлайн-магазина.

В одной версии есть один URL, который мы запрашиваем с помощью HTTP GET или POST. Вы взаимодействуете с сервисом, отправляя данные POST, содержащие то, что вы хотите сделать. Например, добавить элемент с помощью NewItem:

POST /inventory HTTP/1.1 { "NewItem": { "name": "new item", "price": "9.99", "id": "1001" } }

Запросить через POST и ItemRequest:

POST /inventory HTTP/1.1 { "ItemRequest": { "id": "1001" } }

Некоторые реализации также допускают запросы через GET-параметры:

POST /inventory?id=1001 HTTP/1.1

И т.п.

Это не REST. Мы не обмениваемся состоянием ресурсов. Мы вызываем функцию с аргументами, которые находятся в документе JSON или параметрая URL.

RESTful-сервис имеет URI для каждого ресурса. Поэтому добавление нового товара будет выглядеть так же, как в примере выше. Но на этом сходства заканчиваются.
Запрос элемента – это всегда GET:

GET /item/1001 HTTP/1.1

Удаление - DELETE:

DELETE /item/1001 HTTP/1.1

Изменение - PUT:

```
PUT /inventory HTTP/1.1
{
"Item": {
"name": "new item",
"price": "7.99",
"id": "1001"
}
}

```

Разница важна. В REST операции используют различные глаголы HTTP, которые соответствуют действиям с данными: GET, POST, PUT, DELETE и PATCH имеют определённые контракты. Большинство хорошо спроектированных REST API также возвращают определённые коды HTTP в зависимости от результата запроса. Основным различием является то, что URI соответствуют данным, а не удалёнными методам.

REST против RESTful и модель зрелости Ричардсона
Разработка URI в соответствии с ресурсами и использование глаголов HTTP способствует предсказуемости API. Когда разработчики поймут, как вы структурировали ресурсы, они смогут сделать обоснованные прогнозы относительно структуры API. В этом смысле основное внимание уделяется пониманию самих данных, а не связанных с ними операций.

Но даже если вы не можете сделать API полностью предсказуемым, вы можете документировать любой REST-сервис с помощью HATEOAS. Тогда каждый элемент, возвращаемый сервером, будет содержать ссылки для удаления или изменения ресурса.

Многие сайты не соответствуют этому требованию, но по-прежнему называются REST. Леонард Ричардсон создал модель уровней зрелости REST:
0 – API через HTTP с вызовом удалённых методов с аргументами.
1 – Использование ресурсов вместо методов.
2 – Правильное использование HTTP-глаголов.
3 – Использование HATEOAS, что делает видимым весь API или его часть.
По Филдингу требуется третий уровень, так что большинство приложений не являются REST.

То, насколько хорошо архитектура соответствует стандарту, не так важно, как то, насколько хорошо она соответствует потребностям и может расти вместе с бизнесом.

Архитектурный шаблон REST имеет множество преимуществ. Филдинг разработал его для Интернета, и 18 лет спустя большинство ограничений, которые он добавил, все ещё с нами. В 2000 году у нас не было Android или iPhone, а IE5 занимал 50% рынка браузеров. Но Филдинг понимал, что нужно онлайн-приложениям и как веб-клиенты будут развиваться от механизмов отображения HTML в полноценные приложения. Инструменты, которые мы используем сегодня, адаптированы к REST, а не наоборот.

Модель зрелости Ричардсона — хорошее руководство для разработки приложений. Желательно находиться на втором уровне модели и посмотреть, как третий уровень может улучшить ваш дизайн.

Источник: https://blog.ndepend.com/rest-vs-restful/

3 weeks, 2 days ago

День 1861. #ВопросыНаСобеседовании#Многопоточность Самые часто задаваемые вопросы на собеседовании по C#
29. Какие потенциальные проблемы могут возникнуть при использовании Thread.Abort() для завершения работающего потока? Объясните последствия и предложите альтернативные методы корректной остановки потока.

Использование Thread.Abort() для завершения работающего потока может привести к нескольким потенциальным проблемам:
1. Непредсказуемое состояние.
Thread.Abort() вызывает исключение ThreadAbortException, которое немедленно прерывает поток, потенциально оставляя общие ресурсы, структуры данных или критические разделы в несогласованном состоянии.
2. Утечки ресурсов.
Если прерванный поток выделил ресурсы, такие как дескрипторы, файловые потоки или соединения с базой данных, они могут не быть освобождены, что приведёт к утечке ресурсов.
3. Взаимные блокировки.
Прерванные потоки, удерживающие блокировки или другие примитивы синхронизации, могут не иметь возможности их освободить, что приводит к взаимоблокировкам в других потоках.
4. Обработка ThreadAbortException.
Если поток перехватывает ThreadAbortException и игнорирует его, запрос на прерывание завершится неудачно, и поток продолжит выполнение.
5. Устарело и больше не поддерживается.
Метод Thread.Abort() не поддерживается в .NET Core, .NET 5 и более поздних версиях, что указывает на то, что его не следует использовать в современных приложениях.

Чтобы корректно остановить поток, есть следующие альтернативы.

1. Общий флаг
Добавим логический флаг, который будет периодически проверяться выполняемым потоком. Если флаг установлен в true, поток должен завершиться. Обязательно использовать ключевое слово volatile или класс Interlocked, чтобы обеспечить правильную синхронизацию:

```
volatile bool stopRequested = false;
var thread = new Thread(() => {
while (!stopRequested)
{
// выполняем работу
// ...
}
});

// Останавливаем поток
stopRequested = true;
```

2. Токен отмены
Если использовать задачи вместо потоков, библиотека параллельных задач (TPL) предоставляет модель отмены с использованием токена отмены:

```
var cts = new CancellationTokenSource();
var task = Task.Run(() =>
{
while (!cts.IsCancellationRequested)
{
// Выполняем работу
// ...
}
});

// Останавливаем задачу
cts.Cancel();
```

Грамотная остановка потоков с помощью этих методов гарантирует освобождение ресурсов, правильное управление блокировками и сохранение согласованного состояния общих данных. Она также совместима с современными версиями .NET и TPL.

Источник: https://dev.to/bytehide/c-multithreading-interview-questions-and-answers-4opj

We recommend to visit

⚡️Все самое важное в одном канале. Новости России и Мира.

Ссылка для друзей - https://t.me/+gFCT63NlnfE5YWZi

Самый большой канал в РФ

Обратная связь: @rob_lower

Last updated 5 days, 12 hours ago

🛒 Магазин сообществ в соц. сетях 24/7
⚡️ В наличии любые тематики и количества, связь в ЛС @timur_chik1


ac99e5f0c33c6df9805b

Last updated 6 months ago

NN
NN
1,378,925 @naebnet

Медиа про интернет, технологии и безопасность

Сотрудничество: @nnmanager
Ютуб: https://youtube.com/naebnet

Last updated 12 hours ago