День 1251. #Безопасность #СписокУязвимостей
Памятка по Уязвимостям в C# Приложениях. Продолжение
Начало 1-4
Продолжение 5-9
10. Небезопасная конфигурация TLS и неправильная проверка сертификата
Помимо правильного шифрования информации в ваших хранилищах данных, вам также необходимо убедиться, что вы общаетесь с доверенным компьютером, а не со злоумышленником. TLS использует цифровые сертификаты в качестве основы для шифрования с открытым ключом, и вам необходимо проверить эти сертификаты, прежде чем устанавливать соединение с третьей стороной. Вы должны убедиться, что сервер, к которому вы пытаетесь подключиться, имеет сертификат, выданный доверенным центром сертификации (certificate authority - CA), и что ни один из сертификатов в цепочке не просрочен.
11. Массовое присвоение (оверпостинг)
Относится к практике присвоения значений нескольким переменным или свойствам объекта. Уязвимости массового присвоения возникают, когда приложение автоматически назначает пользовательский ввод нескольким переменным, объектам или свойствам. Это функция многих платформ приложений, предназначенная для упрощения разработки.
Однако эта функция иногда позволяет злоумышленникам перезаписывать, изменять или создавать новые переменные или свойства объекта по своему желанию. Это может привести к обходу аутентификации и манипулированию логикой программы. Чтобы предотвратить массовое присвоение, вы можете отключить эту функцию в используемой вами среде или использовать белый список, чтобы разрешить присвоение только для определённых свойств или переменных. Например, в ASP.NET можно использовать атрибут Bind на аргументе метода действия контроллера.
12. Отравление заголовка Host
Веб-серверы часто размещают несколько разных веб-сайтов на одном и том же IP-адресе. После того, как HTTP-запрос поступает на IP-адрес, сервер перенаправляет запрос на хост, указанный в заголовке Host. Хотя заголовки Host обычно устанавливаются браузером пользователя, они всё равно являются пользовательским вводом, и поэтому им нельзя доверять.
Если веб-приложение не проверяет заголовок Host перед его использованием для создания относительных адресов, злоумышленники могут запустить ряд атак, таких как XSS, подделка запросов на стороне сервера (SSRF) или атак с отравлением веб-кэша через заголовок Host. Например, если приложение использует заголовок Host для определения местоположения сценариев, злоумышленник может отправить вредоносный заголовок Host, чтобы приложение выполнило вредоносный сценарий:
Веб-сайты часто должны автоматически перенаправлять своих пользователей на другие страницы. Например, такой сценарий возникает, когда не прошедшие авторизацию пользователи пытаются получить доступ к странице, требующей входа в систему. Веб-сайт обычно перенаправляет их на страницу входа, а затем возвращает в исходное местоположение после авторизации.
Во время атаки с открытым перенаправлением злоумышленник обманом заставляет пользователя посетить внешний сайт, предоставляя ему URL-адрес законного сайта, который перенаправляет куда-то еще. Это может заставить пользователей поверить, что они все ещё находятся на исходном сайте, и помочь мошенникам создать более правдоподобную фишинговую страницу (см. подробнее).
Чтобы предотвратить открытые перенаправления, вам необходимо убедиться, что приложение не перенаправляет пользователей на вредоносные места. Например, вы можете полностью запретить перенаправления за пределы сайта, проверяя URL-адреса перенаправления. Есть много других способов предотвращения открытых перенаправлений, таких как проверка реферера запросов или использование индексов страниц для перенаправлений. Однако из-за сложности проверки URL-адресов открытые перенаправления остаются распространенной проблемой в современных веб-приложениях.
Продолжение следует…
Источник: https://dzone.com/articles/c-applications-vulnerability-cheatsheet
Памятка по Уязвимостям в C# Приложениях. Продолжение
Начало 1-4
Продолжение 5-9
10. Небезопасная конфигурация TLS и неправильная проверка сертификата
Помимо правильного шифрования информации в ваших хранилищах данных, вам также необходимо убедиться, что вы общаетесь с доверенным компьютером, а не со злоумышленником. TLS использует цифровые сертификаты в качестве основы для шифрования с открытым ключом, и вам необходимо проверить эти сертификаты, прежде чем устанавливать соединение с третьей стороной. Вы должны убедиться, что сервер, к которому вы пытаетесь подключиться, имеет сертификат, выданный доверенным центром сертификации (certificate authority - CA), и что ни один из сертификатов в цепочке не просрочен.
11. Массовое присвоение (оверпостинг)
Относится к практике присвоения значений нескольким переменным или свойствам объекта. Уязвимости массового присвоения возникают, когда приложение автоматически назначает пользовательский ввод нескольким переменным, объектам или свойствам. Это функция многих платформ приложений, предназначенная для упрощения разработки.
Однако эта функция иногда позволяет злоумышленникам перезаписывать, изменять или создавать новые переменные или свойства объекта по своему желанию. Это может привести к обходу аутентификации и манипулированию логикой программы. Чтобы предотвратить массовое присвоение, вы можете отключить эту функцию в используемой вами среде или использовать белый список, чтобы разрешить присвоение только для определённых свойств или переменных. Например, в ASP.NET можно использовать атрибут Bind на аргументе метода действия контроллера.
12. Отравление заголовка Host
Веб-серверы часто размещают несколько разных веб-сайтов на одном и том же IP-адресе. После того, как HTTP-запрос поступает на IP-адрес, сервер перенаправляет запрос на хост, указанный в заголовке Host. Хотя заголовки Host обычно устанавливаются браузером пользователя, они всё равно являются пользовательским вводом, и поэтому им нельзя доверять.
Если веб-приложение не проверяет заголовок Host перед его использованием для создания относительных адресов, злоумышленники могут запустить ряд атак, таких как XSS, подделка запросов на стороне сервера (SSRF) или атак с отравлением веб-кэша через заголовок Host. Например, если приложение использует заголовок Host для определения местоположения сценариев, злоумышленник может отправить вредоносный заголовок Host, чтобы приложение выполнило вредоносный сценарий:
var scriptURL = $"https://{Request.Host}/script.js";13. Открытые перенаправления
Веб-сайты часто должны автоматически перенаправлять своих пользователей на другие страницы. Например, такой сценарий возникает, когда не прошедшие авторизацию пользователи пытаются получить доступ к странице, требующей входа в систему. Веб-сайт обычно перенаправляет их на страницу входа, а затем возвращает в исходное местоположение после авторизации.
Во время атаки с открытым перенаправлением злоумышленник обманом заставляет пользователя посетить внешний сайт, предоставляя ему URL-адрес законного сайта, который перенаправляет куда-то еще. Это может заставить пользователей поверить, что они все ещё находятся на исходном сайте, и помочь мошенникам создать более правдоподобную фишинговую страницу (см. подробнее).
Чтобы предотвратить открытые перенаправления, вам необходимо убедиться, что приложение не перенаправляет пользователей на вредоносные места. Например, вы можете полностью запретить перенаправления за пределы сайта, проверяя URL-адреса перенаправления. Есть много других способов предотвращения открытых перенаправлений, таких как проверка реферера запросов или использование индексов страниц для перенаправлений. Однако из-за сложности проверки URL-адресов открытые перенаправления остаются распространенной проблемой в современных веб-приложениях.
Продолжение следует…
Источник: https://dzone.com/articles/c-applications-vulnerability-cheatsheet
👍2
День 1252. #Курсы
Сегодня порекомендую вам ещё один молодой и сильно недооценённый (судя по небольшому количеству подписчиков) образовательный канал на ютубе. Канал Dev Jungles от Андрея Подколзина (да, в этот раз контент на русском).
Андрей начинал с длинных стримов по постройке веб сервера на .NET 5 с нуля, оптимизации C# кода с помощью BenchMarkDotNet или профилировки памяти с помощью dotMemory.
Однако в последнее время на канале стали появляться и более короткие обучающие видео, вроде:
- Истории криптографии
- Топ вопросов на собеседовании по C#
- Топ вопросов про многопоточность
- Модель CPU и Assembler к нему на чистом C#
Смотрим, наслаждаемся, обучаемся.
Сегодня порекомендую вам ещё один молодой и сильно недооценённый (судя по небольшому количеству подписчиков) образовательный канал на ютубе. Канал Dev Jungles от Андрея Подколзина (да, в этот раз контент на русском).
Андрей начинал с длинных стримов по постройке веб сервера на .NET 5 с нуля, оптимизации C# кода с помощью BenchMarkDotNet или профилировки памяти с помощью dotMemory.
Однако в последнее время на канале стали появляться и более короткие обучающие видео, вроде:
- Истории криптографии
- Топ вопросов на собеседовании по C#
- Топ вопросов про многопоточность
- Модель CPU и Assembler к нему на чистом C#
Смотрим, наслаждаемся, обучаемся.
👍34
День 1253. #ЗаметкиНаПолях #AsyncTips
Регулировка очередей
Задача
Имеется очередь «производитель/потребитель», но производители могут работать быстрее потребителей, что может привести к неэффективному использованию памяти. Также вам хотелось бы сохранить все элементы в очереди, а следовательно, требуется механизм регулировки производителей.
Решение
Если элементы производятся быстрее, чем потребители могут потреблять их, очередь придётся отрегулировать. Для этого можно задать максимальное количество элементов. Когда очередь будет «заполнена», она блокирует производителей, пока в очереди не появится свободное место.
Регулировка может выполняться посредством создания ограниченного канала (вместо неограниченного). Так как каналы асинхронны, производители будут регулироваться асинхронно:
Блокирующие очереди «производитель/потребитель» также поддерживают регулировку. Вы можете использовать тип
Регулировка необходима в том случае, если производители работают быстрее потребителей. Один из сценариев, которые необходимо рассмотреть: могут ли производители работать быстрее потребителей, если ваше приложение будет работать на другом оборудовании? Обычно некоторая регулировка потребуется для того, чтобы гарантировать нормальную работу на будущем оборудовании и/или облачных платформах, которые нередко более ограничены в ресурсах, чем машины разработчиков.
Регулировка замедляет работу производителей, блокируя их, чтобы потребители гарантированно могли обработать все элементы без излишних затрат памяти. Если обрабатывать каждый элемент не обязательно, можно использовать выборку вместо регулировки (об этом в будущих постах).
См. также
- Асинхронные очереди
- Блокирующие очереди
Источник: Стивен Клири “Конкурентность в C#”. 2-е межд. изд. — СПб.: Питер, 2020. Глава 9.
Регулировка очередей
Задача
Имеется очередь «производитель/потребитель», но производители могут работать быстрее потребителей, что может привести к неэффективному использованию памяти. Также вам хотелось бы сохранить все элементы в очереди, а следовательно, требуется механизм регулировки производителей.
Решение
Если элементы производятся быстрее, чем потребители могут потреблять их, очередь придётся отрегулировать. Для этого можно задать максимальное количество элементов. Когда очередь будет «заполнена», она блокирует производителей, пока в очереди не появится свободное место.
Регулировка может выполняться посредством создания ограниченного канала (вместо неограниченного). Так как каналы асинхронны, производители будут регулироваться асинхронно:
var queue = Channel.CreateBounded<int>(1);Тип
var writer = queue.Writer;
// Эта запись завершается немедленно.
await writer.WriteAsync(7);
// Эта запись (асинхронно) ожидает удаления 7
// перед тем как вставить в очередь 13.
await writer.WriteAsync(13);
writer.Complete();
BufferBlock<T>
также имеет встроенную поддержку регулировки, следует задать параметр BoundedCapacity
:var queue = new BufferBlock<int>(Производитель в этом фрагменте кода использует асинхронный метод
new DataflowBlockOptions
{
BoundedCapacity = 1
});
// Эта отправка завершается немедленно.
await queue.SendAsync(7);
// Эта отправка (асинхронно) ожидает удаления 7
// перед тем как ставить в очередь 13.
await queue.SendAsync(13);
queue.Complete();
SendAsync
.Блокирующие очереди «производитель/потребитель» также поддерживают регулировку. Вы можете использовать тип
BlockingCollection<T>
для регулировки количества элементов, для чего при создании передается соответствующее значение:var queue = new BlockingCollection<int>(boundedCapacity: 1);Итого
// Это добавление завершается немедленно.
queue.Add(7);
// Это добавление ожидает удаления 7
// перед тем, как добавлять 13.
queue.Add(13);
queue.CompleteAdding();
Регулировка необходима в том случае, если производители работают быстрее потребителей. Один из сценариев, которые необходимо рассмотреть: могут ли производители работать быстрее потребителей, если ваше приложение будет работать на другом оборудовании? Обычно некоторая регулировка потребуется для того, чтобы гарантировать нормальную работу на будущем оборудовании и/или облачных платформах, которые нередко более ограничены в ресурсах, чем машины разработчиков.
Регулировка замедляет работу производителей, блокируя их, чтобы потребители гарантированно могли обработать все элементы без излишних затрат памяти. Если обрабатывать каждый элемент не обязательно, можно использовать выборку вместо регулировки (об этом в будущих постах).
См. также
- Асинхронные очереди
- Блокирующие очереди
Источник: Стивен Клири “Конкурентность в C#”. 2-е межд. изд. — СПб.: Питер, 2020. Глава 9.
👍3
День 1254. #DDD
Обязанности Агрегатов в DDD
Агрегат происходит из DDD и предоставляет способ инкапсулировать бизнес-логику в нескольких связанных объектах.
Основные правила агрегатов:
1. Каждый агрегат имеет один корневой объект. Агрегаты называются по их корневому объекту.
2. Дочерние элементы агрегатов не сохраняются отдельно, а только как часть агрегата. Более того, доступ к ним также должен осуществляться только через агрегат.
Например, навигационные свойства должны существовать только от корней агрегатов к дочерним элементам (но не наоборот и не между агрегатами). Т.е. корень должен иметь возможность обращаться к любому из своих дочерних элементов, а дочерние элементы обычно имеют только свойство ID своего родителя.
3. Корень отвечает за валидность всего агрегата
Это не означает, что весь код должен находиться в корневом объекте. Корень может делегировать полномочия своим дочерним элементам при выполнении задач, за которые он отвечает.
Рассмотрим простой пример сущности
- создание нового заказа,
- добавление
- изменение количества в
Некоторые бизнес-правила:
- валидный заказ имеет хотя бы один
- валидная коллекция
- валидный
Очевидно, что
Многие разработчики также считают, что правило агрегата, гарантирующее, что весь агрегат является «действительным», требует метода для проверки достоверности. Иногда это полезно, но лучший дизайн — это тот, который изначально не допускает существования недопустимых значений. Снова рассмотрим тип
Итого
Корень агрегата отвечает за то, чтобы агрегат находился в допустимом состоянии. Но это не означает, что каждая операция, выполняемая над любым элементом агрегата, должна находиться в корне агрегата. Это также не означает, что агрегат должен иметь метод, выполняющий проверку. Использование надлежащего объектно-ориентированного дизайна и обеспечение того, чтобы ваши объекты инкапсулировали и управляли своим собственным состоянием, обеспечивает более чистый дизайн.
См. также Сущности и Объекты-Значения
Источник: https://ardalis.com/aggregate-responsibility-design/
Обязанности Агрегатов в DDD
Агрегат происходит из DDD и предоставляет способ инкапсулировать бизнес-логику в нескольких связанных объектах.
Основные правила агрегатов:
1. Каждый агрегат имеет один корневой объект. Агрегаты называются по их корневому объекту.
2. Дочерние элементы агрегатов не сохраняются отдельно, а только как часть агрегата. Более того, доступ к ним также должен осуществляться только через агрегат.
Например, навигационные свойства должны существовать только от корней агрегатов к дочерним элементам (но не наоборот и не между агрегатами). Т.е. корень должен иметь возможность обращаться к любому из своих дочерних элементов, а дочерние элементы обычно имеют только свойство ID своего родителя.
3. Корень отвечает за валидность всего агрегата
Это не означает, что весь код должен находиться в корневом объекте. Корень может делегировать полномочия своим дочерним элементам при выполнении задач, за которые он отвечает.
Рассмотрим простой пример сущности
Order
, которая имеет коллекцию сущностей OrderItem
. Order
— корень:public class OrderНекоторые типичные операции агрегата:
{
// прочие свойства и методы опущены
public IEnumerable<OrderItem> OrderItems { get; private set;}
}
public class OrderItem
{
// прочие свойства и методы опущены
public int ProductId { get; set; }
public int Quantity { get; set; }
}
- создание нового заказа,
- добавление
OrderItem
в заказ,- изменение количества в
OrderItem
.Некоторые бизнес-правила:
- валидный заказ имеет хотя бы один
OrderItem
,- валидная коллекция
OrderItems
не содержит повторяющихся ProductId
,- валидный
OrderItem
имеет положительное количество.Очевидно, что
Order
здесь отвечает за первые 2 бизнес-правила, а вот за валидацию количества (и, возможно, других своих свойств) может (и должен) отвечать OrderItem
. Можно, конечно, пойти дальше и использовать для свойства Quantity
тип, не допускающий отрицательных значений, но сегодня не об этом.Order
, отвечающий за валидность всего агрегата, может при этом использовать поведение OrderItem
. Ему не нужно проверять OrderItem
извне, если он может быть уверен, что дочерний объект валиден. Вам же не нужно проверять, что свойство Month типа DateTime
меньше 13. Тип делает эту проверку за вас, поэтому вы можете быть уверены, что месяц будет в допустимом диапазоне, если у вас есть экземпляр типа.Многие разработчики также считают, что правило агрегата, гарантирующее, что весь агрегат является «действительным», требует метода для проверки достоверности. Иногда это полезно, но лучший дизайн — это тот, который изначально не допускает существования недопустимых значений. Снова рассмотрим тип
DateTime
. У него нет метода IsValid()
, который вы вызываете после создания экземпляра, указав год, месяц и день как 2022, 50 и 50. Тип просто не позволит вам установить свои месяц или день в значение 50. Если вам удастся создать экземпляр DateTime
, вы можете быть уверены, что он валиден, а также вы не сможете использовать ни один из его методов, чтобы поместить его в недопустимое состояние. Этот же подход нужно использовать со своими агрегатами и сущностями.Итого
Корень агрегата отвечает за то, чтобы агрегат находился в допустимом состоянии. Но это не означает, что каждая операция, выполняемая над любым элементом агрегата, должна находиться в корне агрегата. Это также не означает, что агрегат должен иметь метод, выполняющий проверку. Использование надлежащего объектно-ориентированного дизайна и обеспечение того, чтобы ваши объекты инкапсулировали и управляли своим собственным состоянием, обеспечивает более чистый дизайн.
См. также Сущности и Объекты-Значения
Источник: https://ardalis.com/aggregate-responsibility-design/
👍11
Audio
День 1255. #Подкаст #Карьера
Сегодня попробую кое-что новое. Решил скачать и выложить здесь эпизод подкаста DotNetRocks, чтобы можно было послушать прямо в телеграме.
В этом эпизоде в гостях у ведущих была Хетер Даунинг. Она рассказала, как она «пришла в айти» и с какими трудностями сталкивалась:
- Как работать в устаревшем стеке и не терять мотивации?
- Как проходить собеседования?
Хороший совет – ходите, даже если не ищете работу. Чтобы поддерживать навык, быть в курсе требований, создавать новые связи. Будет проще, если ваше благополучие не зависит от того, как вы пройдёте это собеседование.
- Как реагировать, когда просят писать код на листочке?
- Как переходить из разработчика в тимлиды и управлять людьми вместо написания кода?
- Как изучать новую технологию, когда в наличии только плохая документация?
- Когда задумываться о пенсии?
Мне разговор понравился (извините, только на английском). Послушайте и скажите, как вам опыт подкастов здесь.
Сегодня попробую кое-что новое. Решил скачать и выложить здесь эпизод подкаста DotNetRocks, чтобы можно было послушать прямо в телеграме.
В этом эпизоде в гостях у ведущих была Хетер Даунинг. Она рассказала, как она «пришла в айти» и с какими трудностями сталкивалась:
- Как работать в устаревшем стеке и не терять мотивации?
- Как проходить собеседования?
Хороший совет – ходите, даже если не ищете работу. Чтобы поддерживать навык, быть в курсе требований, создавать новые связи. Будет проще, если ваше благополучие не зависит от того, как вы пройдёте это собеседование.
- Как реагировать, когда просят писать код на листочке?
- Как переходить из разработчика в тимлиды и управлять людьми вместо написания кода?
- Как изучать новую технологию, когда в наличии только плохая документация?
- Когда задумываться о пенсии?
Мне разговор понравился (извините, только на английском). Послушайте и скажите, как вам опыт подкастов здесь.
👍10
День 1256. #Книги
10 Книг Для Разработчика-Сеньора. Начало
Разработчики - прирождённые читатели, которые получают удовольствие, узнавая о новых вещах. А книги — идеальное средство для глубокого раскрытия сложных идей. Этот список содержит как классические, так и современные публикации, предназначенных для старших разработчиков.
1. Кент Бек «Экстремальное Программирование»
90-е были определяющей эпохой для разработки ПО. Бум доткомов создал огромное давление, заставляющее выпускать продукты раньше и чаще. Никогда прежде производительность не была столь важна для успеха в ИТ-индустрии.
Книга Кента Бека представила и усовершенствовала все agile-практики, которые сегодня считаются само собой разумеющимися: парное программирование, автоматизированное тестирование, разработка через тестирование и непрерывная интеграция.
Второе издание (насколько я знаю, его нет в переводе) уточняет первоначальную идею: быть в курсе, адаптироваться и меняться. Меняться не стыдно. Наоборот, быть готовым к изменениям — хорошая привычка для инженера.
Кент не углубляется в технические детали. Он обсуждает социальные аспекты разработки: взаимодействие с коллегами и руководством, трудовую этику, которой должны следовать программисты, и то, как плоская иерархия помогает всем работать над достижением общей цели.
Зачем читать: эта книга изменит ваше представление о разработке ПО всего на 200 страницах.
2. Джез Хамбл, Дэвид Фарли «Непрерывная Разработка ПО»
В этой книге Фарли и Хамбл выводят принципы непрерывной интеграции, представленные в книге «Экстремальное программирование», на новый уровень. Непрерывная доставка научит вас, как сделать выпуск и развёртывание простыми, как нажатие кнопки.
Посыл Джеза и Дэвида на первый взгляд может показаться нелогичным: «если это больно, делай это чаще и акцентируйся на боли». Заманчиво откладывать сложные части цикла разработки, но это не сделает их проще. Если интеграция болезненна, делайте её при каждом коммите. Если тестирование болезненно, делайте его постоянно, а не только в конце. Акцентируйтесь на боли: сначала делайте сложные вещи, и вам придётся столкнуться с трудностями и найти решения.
В книге очень подробно рассказывается о построении, структурировании и обслуживании конвейера доставки, в том числе о том, какие виды тестов использовать, как обрабатывать данные и как их развивать по мере роста проекта. Хотя некоторые инструменты, использованные в книге, немного устарели, её идеи и принципы вне времени. Это исчерпывающее руководство по DevOps, которое поможет вам перестать беспокоиться о развёртывании.
Зачем читать: любая команда, которая не читала эту книгу, ещё не достигла своего максимального потенциала.
3. Джейсон Фрайд, Дэвид Хайнемайер Хенссон «Remote. Офис не обязателен»
Если пандемия что и продемонстрировала, так это то, что удалённая работа — это не будущее, а настоящее. Мы были вынуждены работать из дома, и у нас было мало времени на адаптацию. Авторы показывают, как Basecamp стала полностью удалённой компанией.
Книга призвана побороть распространённые оправдания против удалённой работы: личное общение не незаменимо, а людям можно (и нужно) доверять, чтобы они продуктивно работали из дома.
Зачем читать: книга покажет руководителю, как выглядит успешная удалённая команда, а работнику - методы, которые помогают работать удалённо, избегая при этом ловушек, которые могут возникнуть в домашних офисах.
Продолжение следует…
Источник: https://semaphoreci.com/blog/books-every-senior-engineer-should-read
10 Книг Для Разработчика-Сеньора. Начало
Разработчики - прирождённые читатели, которые получают удовольствие, узнавая о новых вещах. А книги — идеальное средство для глубокого раскрытия сложных идей. Этот список содержит как классические, так и современные публикации, предназначенных для старших разработчиков.
1. Кент Бек «Экстремальное Программирование»
90-е были определяющей эпохой для разработки ПО. Бум доткомов создал огромное давление, заставляющее выпускать продукты раньше и чаще. Никогда прежде производительность не была столь важна для успеха в ИТ-индустрии.
Книга Кента Бека представила и усовершенствовала все agile-практики, которые сегодня считаются само собой разумеющимися: парное программирование, автоматизированное тестирование, разработка через тестирование и непрерывная интеграция.
Второе издание (насколько я знаю, его нет в переводе) уточняет первоначальную идею: быть в курсе, адаптироваться и меняться. Меняться не стыдно. Наоборот, быть готовым к изменениям — хорошая привычка для инженера.
Кент не углубляется в технические детали. Он обсуждает социальные аспекты разработки: взаимодействие с коллегами и руководством, трудовую этику, которой должны следовать программисты, и то, как плоская иерархия помогает всем работать над достижением общей цели.
Зачем читать: эта книга изменит ваше представление о разработке ПО всего на 200 страницах.
2. Джез Хамбл, Дэвид Фарли «Непрерывная Разработка ПО»
В этой книге Фарли и Хамбл выводят принципы непрерывной интеграции, представленные в книге «Экстремальное программирование», на новый уровень. Непрерывная доставка научит вас, как сделать выпуск и развёртывание простыми, как нажатие кнопки.
Посыл Джеза и Дэвида на первый взгляд может показаться нелогичным: «если это больно, делай это чаще и акцентируйся на боли». Заманчиво откладывать сложные части цикла разработки, но это не сделает их проще. Если интеграция болезненна, делайте её при каждом коммите. Если тестирование болезненно, делайте его постоянно, а не только в конце. Акцентируйтесь на боли: сначала делайте сложные вещи, и вам придётся столкнуться с трудностями и найти решения.
В книге очень подробно рассказывается о построении, структурировании и обслуживании конвейера доставки, в том числе о том, какие виды тестов использовать, как обрабатывать данные и как их развивать по мере роста проекта. Хотя некоторые инструменты, использованные в книге, немного устарели, её идеи и принципы вне времени. Это исчерпывающее руководство по DevOps, которое поможет вам перестать беспокоиться о развёртывании.
Зачем читать: любая команда, которая не читала эту книгу, ещё не достигла своего максимального потенциала.
3. Джейсон Фрайд, Дэвид Хайнемайер Хенссон «Remote. Офис не обязателен»
Если пандемия что и продемонстрировала, так это то, что удалённая работа — это не будущее, а настоящее. Мы были вынуждены работать из дома, и у нас было мало времени на адаптацию. Авторы показывают, как Basecamp стала полностью удалённой компанией.
Книга призвана побороть распространённые оправдания против удалённой работы: личное общение не незаменимо, а людям можно (и нужно) доверять, чтобы они продуктивно работали из дома.
Зачем читать: книга покажет руководителю, как выглядит успешная удалённая команда, а работнику - методы, которые помогают работать удалённо, избегая при этом ловушек, которые могут возникнуть в домашних офисах.
Продолжение следует…
Источник: https://semaphoreci.com/blog/books-every-senior-engineer-should-read
👍12
День 1257. #Книги
10 Книг Для Разработчика-Сеньора. Продолжение
Начало 1-3
4. Фредерик Брукс «Мифический человеко-месяц»
Можно прочитать о десятках историй успеха, а как насчёт историй неудач? Книга Брукса показывает опасности, с которыми приходится сталкиваться всем сложным проектам. Понятие «человеко-месяц» представляет собой ошибочную идею о том, что вы можете ускорить проект, добавляя людей в команду. Будучи менеджером проекта IBM OS/360, автор заметил, что вместо этого дополнительные люди привели к дальнейшей задержке проекта. Закон Брукса гласит, что «добавление рабочей силы к опаздывающему программному проекту задерживает его ещё больше».
Хотя вы можете быстрее вырыть канаву, добавив больше рабочих рук, некоторые задачи не выигрывают от добавления большего количества людей. По сути, чем сложнее задача, тем труднее разделить её на отдельные, распараллеливаемые задачи. Наблюдения автора и его понимание человеческой природы предлагают бесценные уроки по управлению жизненным циклом сложного проекта, управлению общением в команде, планированию и оценке рабочих графиков.
Зачем читать: прошло почти 50 лет с момента публикации этой книги, а мы всё ещё совершаем те же ошибки при управлении программными проектами. Эту поучительную историю должен прочитать хотя бы один раз каждый инженер.
5. Getting Real
Getting Real — бесплатная электронная книга о том, как сделать проекты простыми. Она побуждает пропускать многие этапы проектирования и приступать к созиданию как можно скорее, несмотря на призывы «создавать меньше, создавать проще», «быть минималистом» и «создавать инструмент, который соответствует вашим потребностям».
Книга делает упор на создание единых команд, разрушение разрозненности, доверие к самостоятельной работе людей и избегание собраний. Это набор правил, который сработал для Basecamp и может сработать для вас. Но даже если это не так, основные ценности, лежащие в основе этих принципов, стоит изучить.
Зачем читать: это серьёзная, но краткая книга о создании продуктов с помощью удалённой команды. Ещё и бесплатная!
6. Мартин Клеппман «Высоконагруженные приложения. Программирование, масштабирование, поддержка»
Знаменитая книга с кабанчиком. Данные — это кровь каждого приложения. Знание того, как проектировать большие наборы данных и управлять ими, является жизненно важным навыком для любого старшего инженера, которому рано или поздно придётся масштабировать систему. Книга Клепманна — это подробное руководство, охватывающее всё, начиная от моделей данных и баз данных SQL и NoSQL до очередей сообщений, распределённых систем и больших данных.
Основа книги – теория. Вы не найдёте ни кода, ни примеров. В то же время это практический текст, в котором рассматриваются компромиссы между несколькими типами технологий обработки данных.
Зачем читать: если вы разрабатываете приложения, потребляющие или обрабатывающие данные любого типа, эта книга поможет вам сбалансировать плюсы и минусы доступных технологий.
Окончание следует…
Источник: https://semaphoreci.com/blog/books-every-senior-engineer-should-read
10 Книг Для Разработчика-Сеньора. Продолжение
Начало 1-3
4. Фредерик Брукс «Мифический человеко-месяц»
Можно прочитать о десятках историй успеха, а как насчёт историй неудач? Книга Брукса показывает опасности, с которыми приходится сталкиваться всем сложным проектам. Понятие «человеко-месяц» представляет собой ошибочную идею о том, что вы можете ускорить проект, добавляя людей в команду. Будучи менеджером проекта IBM OS/360, автор заметил, что вместо этого дополнительные люди привели к дальнейшей задержке проекта. Закон Брукса гласит, что «добавление рабочей силы к опаздывающему программному проекту задерживает его ещё больше».
Хотя вы можете быстрее вырыть канаву, добавив больше рабочих рук, некоторые задачи не выигрывают от добавления большего количества людей. По сути, чем сложнее задача, тем труднее разделить её на отдельные, распараллеливаемые задачи. Наблюдения автора и его понимание человеческой природы предлагают бесценные уроки по управлению жизненным циклом сложного проекта, управлению общением в команде, планированию и оценке рабочих графиков.
Зачем читать: прошло почти 50 лет с момента публикации этой книги, а мы всё ещё совершаем те же ошибки при управлении программными проектами. Эту поучительную историю должен прочитать хотя бы один раз каждый инженер.
5. Getting Real
Getting Real — бесплатная электронная книга о том, как сделать проекты простыми. Она побуждает пропускать многие этапы проектирования и приступать к созиданию как можно скорее, несмотря на призывы «создавать меньше, создавать проще», «быть минималистом» и «создавать инструмент, который соответствует вашим потребностям».
Книга делает упор на создание единых команд, разрушение разрозненности, доверие к самостоятельной работе людей и избегание собраний. Это набор правил, который сработал для Basecamp и может сработать для вас. Но даже если это не так, основные ценности, лежащие в основе этих принципов, стоит изучить.
Зачем читать: это серьёзная, но краткая книга о создании продуктов с помощью удалённой команды. Ещё и бесплатная!
6. Мартин Клеппман «Высоконагруженные приложения. Программирование, масштабирование, поддержка»
Знаменитая книга с кабанчиком. Данные — это кровь каждого приложения. Знание того, как проектировать большие наборы данных и управлять ими, является жизненно важным навыком для любого старшего инженера, которому рано или поздно придётся масштабировать систему. Книга Клепманна — это подробное руководство, охватывающее всё, начиная от моделей данных и баз данных SQL и NoSQL до очередей сообщений, распределённых систем и больших данных.
Основа книги – теория. Вы не найдёте ни кода, ни примеров. В то же время это практический текст, в котором рассматриваются компромиссы между несколькими типами технологий обработки данных.
Зачем читать: если вы разрабатываете приложения, потребляющие или обрабатывающие данные любого типа, эта книга поможет вам сбалансировать плюсы и минусы доступных технологий.
Окончание следует…
Источник: https://semaphoreci.com/blog/books-every-senior-engineer-should-read
👍13
День 1258. #Книги
10 Книг Для Разработчика-Сеньора. Окончание
Начало 1-3
Продолжение 4-6
7. Бетси Бейер, Крис Джоунс «Site Reliability Engineering»
У разработки ПО есть скрытая сторона, которую игнорирует большинство технических книг: как поддерживать работоспособность системы после её создания. Эта книга - сборник эссе сотрудников Google, исправляет это упущение.
Инженеры по надёжности обслуживания (SRE) поддерживают работоспособность систем, выявляют проблемы до того, как они возникнут, проводят анализ, когда происходит что-то ужасное, и выполняют всю работу, необходимую для того, чтобы это никогда не повторилось.
Даже если SRE не входит в ваши обязанности, навыки, которые вы можете получить из этой книги, помогут вам создавать более устойчивые продукты. В этой книге приводятся советы, которые со временем помогут обеспечить надёжные сервисы и устойчивые рабочие нагрузки.
Зачем читать: это бесценное руководство о том, как крупнейшая в мире компания-разработчик ПО управляет рисками и поддерживает работу систем.
8. Джин Ким, Кевин Бер «Проект "Феникс"»
Это история вымышленной компании Parts Unlimited и ее пути к agile-практикам. Книга начинается с кризиса. Генеральный директор уходит в отставку после резкого падения курса акций; компания теряет деньги и отстаёт от конкурентов. В условиях этого кризиса Биллу Палмеру (главному герою) поручают заняться проектом, который всё исправит: многообещающей «Программой Феникс». Авторы создали захватывающую историю с занимательными диалогами и удовлетворяющей концовкой.
Зачем читать: это современная ИТ-басня, которая должна найти отклик у любого опытного инженера. Если вы устали читать сухие технические книги, это идеальный выбор.
9. Сэм Ньюмен «Создание микросервисов»
Облачные приложения сделали изучение микросервисов обязательным. Новые проекты начинают широко использовать микросервисы, и монолит часто разбивается на распределённые системы. Книга расскажет вам, как сделать и то, и другое. В ней полно конкретных примеров организаций, использующих микросервисы для масштабирования своей деятельности, рассказывается, как спроектировать, построить, развернуть, защитить и контролировать распределённую систему.
Зачем читать: это всеобъемлющее руководство по микросервисам и распределённым системам, которое не содержит модных словечек, зато раскрывает суть дела.
10. Dave Farley «Modern Software Engineering: Doing What Works to Build Better Software Faster»
Разработка ПО и программирование кажутся взаимозаменяемыми. Реальность такова, что разработка — это гораздо больше, чем просто код. Книга пытается восстановить первоначальное значение этого термина: «применение эмпирического научного подхода к поиску эффективных и экономичных решений практических проблем в ПО».
В книге ставится задача найти рациональную, практичную и устойчивую основу для разработки ПО. Автор использует итеративный экспериментальный подход, напоминающий предложение Фреда Брукса «выбросить прототип». Дэвид показывает, как принимать дизайнерские решения на конкретных примерах. Книга охватывает основные аспекты ремесла, такие как абстракция, разделение задач и модульность для управления сложностью.
Зачем читать: это книга, о которой вы мечтали, когда начинали заниматься разработкой ПО.
Источник: https://semaphoreci.com/blog/books-every-senior-engineer-should-read
10 Книг Для Разработчика-Сеньора. Окончание
Начало 1-3
Продолжение 4-6
7. Бетси Бейер, Крис Джоунс «Site Reliability Engineering»
У разработки ПО есть скрытая сторона, которую игнорирует большинство технических книг: как поддерживать работоспособность системы после её создания. Эта книга - сборник эссе сотрудников Google, исправляет это упущение.
Инженеры по надёжности обслуживания (SRE) поддерживают работоспособность систем, выявляют проблемы до того, как они возникнут, проводят анализ, когда происходит что-то ужасное, и выполняют всю работу, необходимую для того, чтобы это никогда не повторилось.
Даже если SRE не входит в ваши обязанности, навыки, которые вы можете получить из этой книги, помогут вам создавать более устойчивые продукты. В этой книге приводятся советы, которые со временем помогут обеспечить надёжные сервисы и устойчивые рабочие нагрузки.
Зачем читать: это бесценное руководство о том, как крупнейшая в мире компания-разработчик ПО управляет рисками и поддерживает работу систем.
8. Джин Ким, Кевин Бер «Проект "Феникс"»
Это история вымышленной компании Parts Unlimited и ее пути к agile-практикам. Книга начинается с кризиса. Генеральный директор уходит в отставку после резкого падения курса акций; компания теряет деньги и отстаёт от конкурентов. В условиях этого кризиса Биллу Палмеру (главному герою) поручают заняться проектом, который всё исправит: многообещающей «Программой Феникс». Авторы создали захватывающую историю с занимательными диалогами и удовлетворяющей концовкой.
Зачем читать: это современная ИТ-басня, которая должна найти отклик у любого опытного инженера. Если вы устали читать сухие технические книги, это идеальный выбор.
9. Сэм Ньюмен «Создание микросервисов»
Облачные приложения сделали изучение микросервисов обязательным. Новые проекты начинают широко использовать микросервисы, и монолит часто разбивается на распределённые системы. Книга расскажет вам, как сделать и то, и другое. В ней полно конкретных примеров организаций, использующих микросервисы для масштабирования своей деятельности, рассказывается, как спроектировать, построить, развернуть, защитить и контролировать распределённую систему.
Зачем читать: это всеобъемлющее руководство по микросервисам и распределённым системам, которое не содержит модных словечек, зато раскрывает суть дела.
10. Dave Farley «Modern Software Engineering: Doing What Works to Build Better Software Faster»
Разработка ПО и программирование кажутся взаимозаменяемыми. Реальность такова, что разработка — это гораздо больше, чем просто код. Книга пытается восстановить первоначальное значение этого термина: «применение эмпирического научного подхода к поиску эффективных и экономичных решений практических проблем в ПО».
В книге ставится задача найти рациональную, практичную и устойчивую основу для разработки ПО. Автор использует итеративный экспериментальный подход, напоминающий предложение Фреда Брукса «выбросить прототип». Дэвид показывает, как принимать дизайнерские решения на конкретных примерах. Книга охватывает основные аспекты ремесла, такие как абстракция, разделение задач и модульность для управления сложностью.
Зачем читать: это книга, о которой вы мечтали, когда начинали заниматься разработкой ПО.
Источник: https://semaphoreci.com/blog/books-every-senior-engineer-should-read
👍8
День 1259. #Безопасность #СписокУязвимостей
Памятка по Уязвимостям в C# Приложениях. Продолжение
Начало 1-4
Продолжение 5-9
Продолжение 10-13
14. Подделка межсайтовых запросов (Cross-Site Request Forgery – CSRF)
CSRF — это техника атаки на других пользователей веб-приложения, используемая на стороне клиента. С помощью CSRF злоумышленники могут отправлять HTTP-запросы, которые якобы исходят от жертвы, выполняя нежелательные действия от имени жертвы. Например, злоумышленник может изменить ваш пароль или перевести деньги с вашего банковского счета без вашего разрешения. См. пример.
В отличие от открытых перенаправлений, существует надежный способ предотвратить CSRF: использовать комбинацию токенов CSRF и SameSite-куки, а также избегать использования запросов GET для действий по изменению состояния.
15. Подделка запроса на стороне сервера (Server-Side Request Forgery – SSRF)
SSRF — это уязвимость, которая возникает, когда злоумышленник может отправлять запросы от имени сервера. Она позволяет злоумышленникам «подделывать» сигнатуры запросов уязвимого сервера, тем самым занимая привилегированное положение в сети, обходить средства управления брандмауэром и получать доступ к внутренним службам.
В зависимости от разрешений, предоставленных уязвимому серверу, злоумышленник может читать конфиденциальные файлы, выполнять внутренние вызовы API и получать доступ к внутренним службам, таким как скрытые инструменты администратора. Самый простой способ предотвратить уязвимости SSRF — никогда не делать исходящие запросы на основе пользовательского ввода. Если их приходится делать, необходимо проверять эти адреса перед инициированием запроса.
16. Нарушение границ доверия
«Границы доверия» относятся к тому, где ненадёжные пользовательские данные входят в контролируемую среду. Например, HTTP-запрос считается ненадёжными данными до тех пор, пока он не будет проверен сервером.
Должно быть чёткое различие между тем, как вы храните, транспортируете и обрабатываете доверенные и ненадёжные входные данные. Нарушения границ доверия происходят, когда это различие не соблюдается, а надёжные и ненадёжные данные смешиваются друг с другом. Например, если доверенные и недоверенные данные хранятся в одной и той же структуре данных или базе данных, приложение начнёт их путать. В этом случае ненадёжные данные могут быть ошибочно приняты за проверенные.
Хороший способ предотвратить нарушение границ доверия — никогда не записывать ненадёжные входные данные в хранилища, пока они не будут проверены.
17. Удалённое выполнение кода (Remote Code Execution - RCE)
RCE, представляют собой класс уязвимостей, которые возникают, когда злоумышленники могут выполнить свой код на вашем компьютере. Один из способов — уязвимости внедрения команд, когда пользовательский ввод объединяется непосредственно с системной командой. Приложение не может различить, где находится пользовательский ввод, а где системная команда, поэтому приложение выполняет пользовательский ввод как код. Злоумышленник сможет выполнять произвольные команды на машине.
Самый простой способ предотвратить удалённое выполнение кода — убедиться, что код, представленный в виде строки, и предназначенный для исполнения, получен только из надёжных источников, или внедрить надёжную проверку ввода в виде списка разрешений.
Продолжение следует…
Источник: https://dzone.com/articles/c-applications-vulnerability-cheatsheet
Памятка по Уязвимостям в C# Приложениях. Продолжение
Начало 1-4
Продолжение 5-9
Продолжение 10-13
14. Подделка межсайтовых запросов (Cross-Site Request Forgery – CSRF)
CSRF — это техника атаки на других пользователей веб-приложения, используемая на стороне клиента. С помощью CSRF злоумышленники могут отправлять HTTP-запросы, которые якобы исходят от жертвы, выполняя нежелательные действия от имени жертвы. Например, злоумышленник может изменить ваш пароль или перевести деньги с вашего банковского счета без вашего разрешения. См. пример.
В отличие от открытых перенаправлений, существует надежный способ предотвратить CSRF: использовать комбинацию токенов CSRF и SameSite-куки, а также избегать использования запросов GET для действий по изменению состояния.
15. Подделка запроса на стороне сервера (Server-Side Request Forgery – SSRF)
SSRF — это уязвимость, которая возникает, когда злоумышленник может отправлять запросы от имени сервера. Она позволяет злоумышленникам «подделывать» сигнатуры запросов уязвимого сервера, тем самым занимая привилегированное положение в сети, обходить средства управления брандмауэром и получать доступ к внутренним службам.
В зависимости от разрешений, предоставленных уязвимому серверу, злоумышленник может читать конфиденциальные файлы, выполнять внутренние вызовы API и получать доступ к внутренним службам, таким как скрытые инструменты администратора. Самый простой способ предотвратить уязвимости SSRF — никогда не делать исходящие запросы на основе пользовательского ввода. Если их приходится делать, необходимо проверять эти адреса перед инициированием запроса.
16. Нарушение границ доверия
«Границы доверия» относятся к тому, где ненадёжные пользовательские данные входят в контролируемую среду. Например, HTTP-запрос считается ненадёжными данными до тех пор, пока он не будет проверен сервером.
Должно быть чёткое различие между тем, как вы храните, транспортируете и обрабатываете доверенные и ненадёжные входные данные. Нарушения границ доверия происходят, когда это различие не соблюдается, а надёжные и ненадёжные данные смешиваются друг с другом. Например, если доверенные и недоверенные данные хранятся в одной и той же структуре данных или базе данных, приложение начнёт их путать. В этом случае ненадёжные данные могут быть ошибочно приняты за проверенные.
Хороший способ предотвратить нарушение границ доверия — никогда не записывать ненадёжные входные данные в хранилища, пока они не будут проверены.
17. Удалённое выполнение кода (Remote Code Execution - RCE)
RCE, представляют собой класс уязвимостей, которые возникают, когда злоумышленники могут выполнить свой код на вашем компьютере. Один из способов — уязвимости внедрения команд, когда пользовательский ввод объединяется непосредственно с системной командой. Приложение не может различить, где находится пользовательский ввод, а где системная команда, поэтому приложение выполняет пользовательский ввод как код. Злоумышленник сможет выполнять произвольные команды на машине.
Самый простой способ предотвратить удалённое выполнение кода — убедиться, что код, представленный в виде строки, и предназначенный для исполнения, получен только из надёжных источников, или внедрить надёжную проверку ввода в виде списка разрешений.
Продолжение следует…
Источник: https://dzone.com/articles/c-applications-vulnerability-cheatsheet
👍8
День 1260. #TypesAndLanguages
5. Чистые и «Нечистые» Функции
Чистые функции — функции, возвращающие один и тот же результат для одних и тех же входных данных, не полагаясь на внешнее состояние. Некоторые любят их. Некоторые утверждают, что все функции должны быть чистыми. Некоторые языки борются с нечистыми функциями или даже вообще не позволяют вам их создавать. Правильно ли говорить, что чистые функции лучше?
Вся аргументация относительно того, какие функции лучше, сводится к влиянию функций на код в целом. У чистых функций меньше «радиус поражения», что упрощает доказательство гипотез относительно них.
Чистые функции принимают входные параметры
Как
Разница в том, что отследить
Однако мы не можем так просто отследить
Однако до тех пор, пока мы можем поддерживать
А что насчёт изменчивости? В большинстве случаев это не имеет значения. Давайте рассмотрим пример функции
Примечание: на самом деле все функции принимают ещё один параметр
Источник: https://blog.adamfurmanek.pl/2022/07/09/types-and-programming-languages-part-14/
5. Чистые и «Нечистые» Функции
Чистые функции — функции, возвращающие один и тот же результат для одних и тех же входных данных, не полагаясь на внешнее состояние. Некоторые любят их. Некоторые утверждают, что все функции должны быть чистыми. Некоторые языки борются с нечистыми функциями или даже вообще не позволяют вам их создавать. Правильно ли говорить, что чистые функции лучше?
Вся аргументация относительно того, какие функции лучше, сводится к влиянию функций на код в целом. У чистых функций меньше «радиус поражения», что упрощает доказательство гипотез относительно них.
Чистые функции принимают входные параметры
I
и производят выходные данные O
. Нечистые функции принимают входные данные в форме (I, S)
, где I
— входные параметры, а S
представляет внешнее состояние, подобное глобальным переменным. Нечистые функции также производят результат O
, однако при этом O
может влиять на S
(и даже на I
).Как
S
меняет ситуацию? Мы можем утверждать, что S
представляет состояние приложения, которое является неявными входными данными для функции. Имея это в виду, как чистые, так и нечистые функции возвращают один и тот же результат O
для полученных входных данных. Однако чистые функции используют (I, null)
в качестве входных данных, а нечистые используют (I, S)
. С этой точки зрения оба типа функций на самом деле чистые. В чём же разница?Разница в том, что отследить
I
намного проще, чем S
. Обычно нужно просто проанализировать место вызова и место, где I
было задано значение. Нам не нужно смотреть на остальной код. Аналогично мы можем отследить входные данные вызывающей функции, и т.д. вверх по стеку вызовов.Однако мы не можем так просто отследить
S
. Чтобы доказать что-либо об S
, нам нужно не только показать, как было задано значение S
, но также и доказать, что оно не было изменено ничем за пределами стека вызовов. Другими словами, чтобы что-то доказать гипотезу об I
, нам нужно просто показать пример, подтверждающий нашу гипотезу. Например, что Math.Sqrt(4) = 2
. Однако, чтобы доказать что-то об S
, нам нужно показать, что нет никаких «контраргументов» (кода, изменяющего состояние S
неожиданным образом), опровергающих нашу гипотезу. Последнее, как правило, намного сложнее, так как нам нужно проанализировать гораздо больше кода, чтобы доказать это. Кроме того, поиск такого кода может быть нетривиальным, так как это может быть рефлексия, параллельно выполняемый код и т.п. Или код может быть вообще недоступен, как какой-то динамически загружаемый плагин.Однако до тех пор, пока мы можем поддерживать
I
и S
небольшими по размеру, всё остальное не имеет значения. Дело не в том, чистая функция или нет. Всё дело в способности отследить входные данные (I, S)
. Это зависит от ваших когнитивных навыков, опыта и навыков программирования в целом. Некоторые функции могут быть ужасны и с тремя входными параметрами и без глобального состояния, тогда как другие функции могут отлично работать без параметров, но с пятью глобальными переменными.А что насчёт изменчивости? В большинстве случаев это не имеет значения. Давайте рассмотрим пример функции
double.TryParse
. По определению она нечистая, так как 1) изменяет входной параметр и 2) использует глобальное состояние (символ десятичного разделителя). Однако является ли эта функция «неправильной» или «плохой»? Нет, потому что её «радиус поражения» обычно сильно ограничен.Примечание: на самом деле все функции принимают ещё один параметр
E
. Параметр представляет собой среду, такую как память, используемую операционную систему, тип процессора, электрические помехи или даже космические лучи. Разница между S
и E
заключается в том, что мы контролируем. Мы можем контролировать S
, поскольку это состояние выполняемого нами приложения, но мы не можем контролировать E
. Вы можете косвенно повлиять на память, используемую операционной системой, но, скорее всего, вы не сможете повлиять на космический луч.Источник: https://blog.adamfurmanek.pl/2022/07/09/types-and-programming-languages-part-14/
👍10
День 1261. #Testing
E2E-тесты с Помощью Playwright в .NET
Playwright – это система end-to-end тестирования, поддерживающая тесты, написанные на NodeJS, Java, Python и C#. Допустим, нам нужно протестировать следующий сценарий:
- Учитывая, что я на https://www.google.com
- Когда я набираю "netdeveloperdiary" в поле поиска
- И нажимаю кнопку "Поиск в Google"
- Тогда первым результатом будет ссылка https://t.iss.one/NetDeveloperDiary
Очевидно, что результат может не всегда быть одинаковым. Но это простейший пример. Playwright – это просто NuGet пакет, который можно использовать в MSTest, NUnit, XUnit или любой другой тестовой среде. В данном случае используем MSTest и пакет
1. Тестовый класс наследует от PageTest
Пакет
Нам не нужно ожидать запуска браузера и момента, пока элементы отобразятся на экране. Всё это берёт на себя Playwright. Например, когда вы хотите заполнить поле для ввода, Playwright предполагает, что оно должно появиться на странице, и ждёт его появления (по умолчанию 30 секунд). Помимо этого, то, что всё происходит асинхронно означает, что вы не столкнётесь с замиранием экрана во время ожидания следующей операции.
В остальном тесты должны быть понятны. Мы заполняем поле для ввода, нажимаем на кнопку поиска и проверяем первый результат.
Примечание. При первом использовании Playwright на вашей машине, нужно выполнить следующую команду из вашего проекта для установки движков браузеров:
Источник: https://dotnetcoretutorials.com/2022/05/20/using-playwright-e2e-tests-with-c-net/
E2E-тесты с Помощью Playwright в .NET
Playwright – это система end-to-end тестирования, поддерживающая тесты, написанные на NodeJS, Java, Python и C#. Допустим, нам нужно протестировать следующий сценарий:
- Учитывая, что я на https://www.google.com
- Когда я набираю "netdeveloperdiary" в поле поиска
- И нажимаю кнопку "Поиск в Google"
- Тогда первым результатом будет ссылка https://t.iss.one/NetDeveloperDiary
Очевидно, что результат может не всегда быть одинаковым. Но это простейший пример. Playwright – это просто NuGet пакет, который можно использовать в MSTest, NUnit, XUnit или любой другой тестовой среде. В данном случае используем MSTest и пакет
Microsoft.Playwright.MSTest
. Вот тестовый класс:[TestClass]Вот на что стоит обратить внимание.
public class MyUnitTests : PageTest
{
[TestMethod]
public async Task TestGoogleSearch()
{
//Учитывая, что я на https://www.google.com
await Page.GotoAsync("https://www.google.com");
//Когда я набираю "netdeveloperdiary" в поле поиска
await Page.FillAsync("[title=\"Поиск\"]", "netdeveloperdiary");
//И нажимаю кнопку "Поиск в Google"
await Page.ClickAsync("[value=\"Поиск в Google\"] >> nth=1");
//Тогда первым результатом будет https://t.iss.one › NetDeveloperDiary
var firstResult = await Page.Locator("//cite >> nth=0").InnerTextAsync();
Assert.AreEqual("https://t.iss.one › NetDeveloperDiary", firstResult);
}
}
1. Тестовый класс наследует от PageTest
Пакет
PlayWright.MSTest
содержит код настройки объекта браузера, а также поддерживает параллельные тесты. Без использования этого пакета мы могли бы настроить объект браузера сами, и получить большую свободу:IPage Page;2. Мы не используем таймауты и все методы асинхронные.
[TestInitialize]
public async Task TestInitialize()
{
var plwrt = await Playwright.CreateAsync();
var brw = await plwrt.Chromium.LaunchAsync(
new BrowserTypeLaunchOptions
{
Headless = false
});
Page = await brw.NewPageAsync();
}
Нам не нужно ожидать запуска браузера и момента, пока элементы отобразятся на экране. Всё это берёт на себя Playwright. Например, когда вы хотите заполнить поле для ввода, Playwright предполагает, что оно должно появиться на странице, и ждёт его появления (по умолчанию 30 секунд). Помимо этого, то, что всё происходит асинхронно означает, что вы не столкнётесь с замиранием экрана во время ожидания следующей операции.
В остальном тесты должны быть понятны. Мы заполняем поле для ввода, нажимаем на кнопку поиска и проверяем первый результат.
Примечание. При первом использовании Playwright на вашей машине, нужно выполнить следующую команду из вашего проекта для установки движков браузеров:
bin\Debug\net6.0\playwright.ps1 installPlaywright содержит множество методов управления браузером и анализа результатов, а также может выполнять и более сложные действия, вроде снимка экрана, который можно сохранить для последующего анализа или сравнения.
Источник: https://dotnetcoretutorials.com/2022/05/20/using-playwright-e2e-tests-with-c-net/
👍5
День 1262. #Оффтоп
2022й год. Вы всё ещё пишете регулярные выражения из головы или гуглите? Автору этого сайта так надоело это делать, что он заморочился и, с помощью GPT-3 (который используется в Copilot), создал ИИ, генерирующий RegEx за вас на основе человеческого запроса!
Представляю https://www.autoregex.xyz/
Сайт, правда, быстро положили, а чуть позже израсходовали все лимиты доступа к ИИ у автора. Поэтому не могу гарантировать, что он работает в данный момент. Но мне самому удалось немного попробовать, и это очень круто.
2022й год. Вы всё ещё пишете регулярные выражения из головы или гуглите? Автору этого сайта так надоело это делать, что он заморочился и, с помощью GPT-3 (который используется в Copilot), создал ИИ, генерирующий RegEx за вас на основе человеческого запроса!
Представляю https://www.autoregex.xyz/
Сайт, правда, быстро положили, а чуть позже израсходовали все лимиты доступа к ИИ у автора. Поэтому не могу гарантировать, что он работает в данный момент. Но мне самому удалось немного попробовать, и это очень круто.
👍22
Когда член интерфейса реализован явно, как его можно вызвать?
Anonymous Quiz
26%
Как обычный член, через переменную конкретного типа
55%
Через переменную типа интерфейса или приведением её к интерфейсу
3%
Через непрямой вызов (через другой публичный член класса)
9%
Через указатель на интерфейс
8%
Явно реализованный член вызвать нельзя
👍4
День 1263. #Оффтоп
Сегодня посоветую вам интересный доклад Скотта Хансельмана с NDC Conferences, которая прошла в апреле в Порто. Тема доклада – «Перемещение 17-летнего легаси кода и сайтов в облако». Скотт рассказал, как создавал свой веб-сайт в качестве хобби. Как важно иметь свой небольшой проект, работать над ним и пробовать всё, что вы изучаете. Особенно важно попробовать себя в работе с производственной средой и потренироваться в развёртывании. Потому что, будем честны, совсем немногие из нас имеют много такого опыта.
Скотт рассказывает, как создавал свой сайт, как развёртывал его, буквально копируя dllки со своего компьютера на сервер, и как перешёл (точнее вынужден был перейти) в облако с полноценной системой CI/CD.
Помимо этого, он даёт несколько советов по поводу выбора архитектуры и функционала. Например, записи в его блоге – это просто статичные файлы, названные по порядку. А информация о спонсорах, которая меняется очень редко, - вообще в JSON файле.
В общем, много полезных советов и с юмором. Приятного просмотра.
https://youtu.be/mE-DGW0CcAk
Сегодня посоветую вам интересный доклад Скотта Хансельмана с NDC Conferences, которая прошла в апреле в Порто. Тема доклада – «Перемещение 17-летнего легаси кода и сайтов в облако». Скотт рассказал, как создавал свой веб-сайт в качестве хобби. Как важно иметь свой небольшой проект, работать над ним и пробовать всё, что вы изучаете. Особенно важно попробовать себя в работе с производственной средой и потренироваться в развёртывании. Потому что, будем честны, совсем немногие из нас имеют много такого опыта.
Скотт рассказывает, как создавал свой сайт, как развёртывал его, буквально копируя dllки со своего компьютера на сервер, и как перешёл (точнее вынужден был перейти) в облако с полноценной системой CI/CD.
Помимо этого, он даёт несколько советов по поводу выбора архитектуры и функционала. Например, записи в его блоге – это просто статичные файлы, названные по порядку. А информация о спонсорах, которая меняется очень редко, - вообще в JSON файле.
В общем, много полезных советов и с юмором. Приятного просмотра.
https://youtu.be/mE-DGW0CcAk
YouTube
Moving 17 years of old legacy code and sites into the Cloud - Scott Hanselman - NDC Porto 2022
Scott Hanselman has been blogging for 20 years and podcasting for 16 and largely on legacy hardware and operating systems. All of the stuff he’s been doing on the side and like many companies he's created a lot of technical debt. He discovered something very…
👍5
День 1264. #ЗаметкиНаПолях
Используем Span Для Производительности. Начало
Сегодня рассмотрим
Другой реализацией
Ограничения
Реализация
Span-подобный класс можно использовать в асинхронном коде. Это классы
Примеры
Мы можем использовать Span для работы с массивами и другими типами коллекций:
Теперь рассмотрим на аналогичный пример с
Окончание следует…
Источник: https://code-maze.com/csharp-span-to-improve-application-performance/
Используем Span Для Производительности. Начало
Сегодня рассмотрим
Span
в C#, как он реализован и как мы можем использовать его для повышения производительности.Span<T>
— это типобезопасное и безопасное по памяти представление непрерывной области памяти. Span<T>
реализован как ref-структурa (подробнее о ref-структурах), которая содержит ссылку на объект T
и длину для чтения. Т.е. Span в C# всегда будет размещаться на стеке, а не в куче. Рассмотрим упрощённую реализацию Span<T>
:public readonly ref struct Span<T>Использование
{
private readonly ref T _pointer;
private readonly int _length;
}
Span<T>
повышает производительность за счёт размещения на стеке, т.к. сборка мусора не тормозит выполнение приложения. Операции со Span<T>
аналогичны операциям с массивами: индексация в Span
не требует вычислений для определения адреса памяти.Другой реализацией
Span
является ReadOnlySpan<T>
. Его отличие от Span
в том, что индексатор возвращает ссылку на T
только для чтения. Это позволяет использовать ReadOnlySpan<T>
для представления неизменяемых типов данных, таких как string
.Span
может использовать типы значений, такие как int
, byte
, ref struct
, bool
и enum
. Span
не может использовать такие типы, как object
, dynamic
или интерфейсы.Ограничения
Реализация
Span
ограничивает его использование в коде. Объекты ссылочного типа размещаются в куче, поэтому мы не можем использовать Span
в качестве полей в ссылочных типах. Также ref-структуры не могут быть упакованы, и Span
нельзя использовать в лямбда-выражениях и асинхронном коде с await
, а также с yield
. Кроме того, т.к. мы выделяем память в стеке, мы должны помнить, что памяти в стеке меньше, чем в куче.Span-подобный класс можно использовать в асинхронном коде. Это классы
Memory<T>
и ReadOnlyMemory<T>
.Примеры
Мы можем использовать Span для работы с массивами и другими типами коллекций:
int[] arr = new[] { 0, 1, 2, 3 };C# предлагает неявное приведение от
Span<int> intSpan = arr;
var otherSpan = arr.AsSpan();
T[]
к Span<T>
, но мы также можем вызвать AsSpan()
для массивов. Как ReadOnlySpan<T>
, так и Span<T>
предлагают знакомые по работе с массивами функции, не выделяющие дополнительную память.Теперь рассмотрим на аналогичный пример с
List<T>
:List<int> intList = new() { 0, 1, 2, 3 };Использовать
var listSpan = CollectionsMarshal.AsSpan(intList);
Span
с коллекцией не так просто, как с массивами. В этом случае мы должны использовать метод CollectionMarshal.AsSpan()
, чтобы получить коллекцию в виде Span
. Для этого нужно импортировать пространство имён System.Runtime.InteropServices
.Окончание следует…
Источник: https://code-maze.com/csharp-span-to-improve-application-performance/
👍2
День 1265. #ЗаметкиНаПолях
Используем Span Для Производительности. Окончание
Начало
Используем ReadOnlySpan вместо строки
Рассмотрим пример, где нам нужно разобрать строку построчно:
Теперь тот же процесс с использованием Span:
Вспомним, что сборка мусора напрямую влияет на производительность приложения. Используя
Тестирование
Оценим результаты теста производительности двух примеров выше:
ParseWithSpan - 23.55 us, без аллокаций.
ParseWithString - 36.12 us, аллоцировано 70,192 B
Результаты ожидаемы.
Итого
Использование Span повышает производительность. Важно отметить, что команда разработчиков .NET активно использует
Источник: https://code-maze.com/csharp-span-to-improve-application-performance/
Используем Span Для Производительности. Окончание
Начало
Используем ReadOnlySpan вместо строки
Рассмотрим пример, где нам нужно разобрать строку построчно:
public int ParseWithString()В первом примере мы используем строки. Мы пытаемся определить, сколько пустых строк в нашем файле. Текст хранится в строковой переменной
{
var prev = 0;
var curr = 0;
var rows = 0;
foreach (char c in _text)
{
if (c == '\n')
{
curr += 1;
var line = _text[prev..curr];
if (line.Equals(Environment.NewLine))
rows++;
prev = curr;
continue;
}
curr++;
}
return rows;
}
_text
. Мы перебираем каждый символ строке, если находим символ новой строки, с помощью Substring()
проверяем предыдущую строку. Если эта строка пустая, увеличиваем счётчик. Ключевым моментом здесь является то, что Substring()
создаёт строку в куче. Сборщику мусора потребуется время, чтобы уничтожить эти строки.Теперь тот же процесс с использованием Span:
public int ParseWithSpan()Здесь процесс такой же, за исключением того, что мы не создаем дополнительные строки. Мы преобразуем текстовую строку в
{
var textSpan = _text.AsSpan();
var prev = 0;
var curr = 0;
var rows = 0;
foreach (char c in textSpan)
{
if (c == '\n')
{
curr += 1;
var slice = textSpan[prev..curr];
if (slice.Equals(Environment.NewLine, StringComparison.OrdinalIgnoreCase))
rows++;
prev = curr;
continue;
}
curr++;
}
return rows;
}
ReadOnlySpan
, вызывая метод AsSpan()
. Кроме того, вместо Substring()
мы используем метод Slice
, который создаёт ReadOnlySpan
, представляющий подстроку. В этом случае в куче ничего не выделяется.Вспомним, что сборка мусора напрямую влияет на производительность приложения. Используя
ReadOnlySpan
вместо строк везде, где возможно, мы можем сильно повысить производительность приложения. ReadOnlySpan
поддерживает множество функций, знакомых по работе со строками: Contains()
, EndsWith()
, StartsWith()
, IndexOf()
, LastIndexOf()
, ToString()
, Trim()
и т.п. Тестирование
Оценим результаты теста производительности двух примеров выше:
ParseWithSpan - 23.55 us, без аллокаций.
ParseWithString - 36.12 us, аллоцировано 70,192 B
Результаты ожидаемы.
Span
работает быстрее и не выделяет дополнительной памяти (но см. ограничения в предыдущем посте).Итого
Использование Span повышает производительность. Важно отметить, что команда разработчиков .NET активно использует
Span
во внутренних библиотеках и максимально упрощает их использование для разработчиков. Команда .NET уже имеет поддержку Span<T>
для DateTime
, TimeSpan
, Int32
, GUID
, StringBuilder
, System.Random
и многих других типов. Важно понимать, как использовать Span
, потому что они будут больше и больше присутствовать в будущем коде .NET и в некоторых случаях могут стать стандартом.Источник: https://code-maze.com/csharp-span-to-improve-application-performance/
👍10
День 1266. #ЧтоНовенького
AWS Упростили Развёртывание Приложений .NET
Теперь развёртывание в AWS доступно в Visual Studio в виде нового мастера "Publish to AWS" (Опубликовать в AWS), либо через интерфейс командной строки .NET после установки AWS Deploy Tool для .NET.
Одной из основных новых функций являются проекты развёртывания. Эта новая концепция позволяет настраивать развёртывания внутри Visual Studio или CLI и делиться ими с остальными членами вашей команды. Проекты развёртывания позволяют командам разрабатывать собственные сценарии и по-прежнему использовать интерактивные развёртывания или развёртывания с использованием сценариев.
Новый интерфейс развёртывания поддерживает ASP.NET Core, Blazor WebAssembly, консольные приложения и задачи, которые необходимо выполнять по расписанию. В настоящее время функции .NET Lambda не поддерживаются. Существующий мастер развёртывания Lambda и .NET CLI Amazon.Lambda.Tools по-прежнему являются рекомендуемыми вариантами развёртывания для приложений .NET Lambda.
В Visual Studio установите последнюю версию AWS Toolkit для Visual Studio. После установки инструментария и настройки учетных данных AWS можно щелкнуть правой кнопкой мыши на проект в обозревателе решений и выбрать пункт "Publish to AWS…". Новый мастер предложит сервис AWS, который лучше всего подходит для вашего приложения.
В .NET CLI выполните следующую команду для установки инструмента из NuGet:
Подробности о работе инструмента есть в документации AWS.
Источник: https://aws.amazon.com/blogs/developer/aws-announces-a-streamlined-deployment-experience-for-net-applications/
AWS Упростили Развёртывание Приложений .NET
Теперь развёртывание в AWS доступно в Visual Studio в виде нового мастера "Publish to AWS" (Опубликовать в AWS), либо через интерфейс командной строки .NET после установки AWS Deploy Tool для .NET.
Одной из основных новых функций являются проекты развёртывания. Эта новая концепция позволяет настраивать развёртывания внутри Visual Studio или CLI и делиться ими с остальными членами вашей команды. Проекты развёртывания позволяют командам разрабатывать собственные сценарии и по-прежнему использовать интерактивные развёртывания или развёртывания с использованием сценариев.
Новый интерфейс развёртывания поддерживает ASP.NET Core, Blazor WebAssembly, консольные приложения и задачи, которые необходимо выполнять по расписанию. В настоящее время функции .NET Lambda не поддерживаются. Существующий мастер развёртывания Lambda и .NET CLI Amazon.Lambda.Tools по-прежнему являются рекомендуемыми вариантами развёртывания для приложений .NET Lambda.
В Visual Studio установите последнюю версию AWS Toolkit для Visual Studio. После установки инструментария и настройки учетных данных AWS можно щелкнуть правой кнопкой мыши на проект в обозревателе решений и выбрать пункт "Publish to AWS…". Новый мастер предложит сервис AWS, который лучше всего подходит для вашего приложения.
В .NET CLI выполните следующую команду для установки инструмента из NuGet:
dotnet tool install --global Aws.Deploy.ToolsПосле установки можно выполнить следующую команду для начала развёртывания:
dotnet aws deployКоманда
deploy
поможет вам выбрать правильный сервис AWS для развёртывания и настроить параметры. Развёртывание через CLI и через Visual Studio очень похоже, что позволяет развёртывать один и тот же проект из любой среды. Вы также можете составить список своих развёртываний с помощью команды dotnet aws list-deployments
или удалить развёртывание с помощью dotnet aws delete-deployment
. Используйте команду dotnet aws --help
, чтобы найти дополнительные сведения о других доступных командах.Подробности о работе инструмента есть в документации AWS.
Источник: https://aws.amazon.com/blogs/developer/aws-announces-a-streamlined-deployment-experience-for-net-applications/
👍9
День 1267. #ЗаметкиНаПолях #AsyncTips
Выборка в очередях
Задача
Есть очередь «производитель/потребитель», но производители могут работать быстрее потребителей, что может привести к неэффективному использованию памяти. Сохранять все элементы из очереди не обязательно; необходимо отфильтровать элементы очереди так, чтобы более медленные потребители могли ограничиться обработкой самых важных элементов.
Решение
Библиотека
Есть и другие режимы
Библиотека
Если выборка должна выполняться по времени (например, «только 10 элементов в секунду»), используйте
См. также
- Асинхронные очереди
- Блокирующие очереди
- Регулировка очередей
Источник: Стивен Клири “Конкурентность в C#”. 2-е межд. изд. — СПб.: Питер, 2020. Глава 9.
Выборка в очередях
Задача
Есть очередь «производитель/потребитель», но производители могут работать быстрее потребителей, что может привести к неэффективному использованию памяти. Сохранять все элементы из очереди не обязательно; необходимо отфильтровать элементы очереди так, чтобы более медленные потребители могли ограничиться обработкой самых важных элементов.
Решение
Библиотека
Channels
предоставляет самые простые средства применения выборки к элементам ввода. Типичный пример — всегда брать последние n элементов с потерей самых старых элементов при заполнении очереди:var queue = Channel.CreateBounded<int>(Это самый простой механизм контроля входных потоков и предотвращения «затопления» потребителей.
new BoundedChannelOptions(1)
{
FullMode = BoundedChannelFullMode.DropOldest,
});
var writer = queue.Writer;
// Операция записи завершается немедленно.
await writer.WriteAsync(7);
// Операция записи тоже завершается немедленно.
// Элемент 7 теряется, если только он не был
// немедленно извлечен потребителем.
await writer.WriteAsync(13);
Есть и другие режимы
BoundedChannelFullMode
. Например, если вы хотите, чтобы самые старые элементы сохранялись, можно при заполнении канала терять новые элементы:var queue = Channel.CreateBounded<int>(Пояснение
new BoundedChannelOptions(1)
{
FullMode = BoundedChannelFullMode.DropWrite,
});
var writer = queue.Writer;
// Операция записи завершается немедленно
await writer.WriteAsync(7);
// Операция записи тоже завершается немедленно
// Элемент 13 теряется, если только элемент 7 не был
// немедленно извлечен потребителем.
await writer.WriteAsync(13);
Библиотека
Channels
отлично подходит для простой выборки. Во многих ситуациях полезен режим BoundedChannelFullMode.DropOldest
. Более сложная выборка должна выполняться самими потребителями.Если выборка должна выполняться по времени (например, «только 10 элементов в секунду»), используйте
System.Reactive
. В System.Reactive
предусмотрены естественные операторы для работы со временем.См. также
- Асинхронные очереди
- Блокирующие очереди
- Регулировка очередей
Источник: Стивен Клири “Конкурентность в C#”. 2-е межд. изд. — СПб.: Питер, 2020. Глава 9.
👍5