День 1720. #ЧтоНовенького
Доступна Бета-Версия Чата Github Copilot
Чат GitHub Copilot — это интерфейс чата, который позволяет разработчикам задавать вопросы о написании кода и получать ответы непосредственно в IDE. В настоящее время он находится в открытой бета-версии и доступен для всех индивидуальных пользователей GitHub Copilot в Visual Studio и VS Code.
Чат GitHub Copilot был представлен в виде общедоступной бета-версии как расширение для разработки ПО на базе искусственного интеллекта для всех пользователей GitHub Copilot для бизнеса. Теперь он доступен бесплатно для всех индивидуальных пользователей Copilot и поддерживается как в редакторах Visual Studio, так и в VS Code. Он использует расширенную обработку естественного языка (natural language processing, NLP), чтобы предлагать помощь и ответы на естественном языке непосредственно в поддерживаемых редакторах. Это избавляет разработчиков от необходимости обращаться к документации или искать на интернет-форумах. Уменьшая необходимость переключения контекста, он оптимизирует процесс разработки, что помогает разработчикам сохранять концентрацию и динамику.
Также у отдельных контрибуторов есть возможность предлагать исправления безопасности, тем самым повышая общую безопасность проектов с открытым исходным кодом.
Другие функции включают:
- Индивидуальные предложения в режиме реального времени с лучшими практиками, советами и решениями.
- Разбор сложных понятий с пояснениями фрагментов кода
- Рекомендации по устранению и уменьшению количества уязвимостей, обнаруженных во время сканирования безопасности.
- Выявление проблем во время отладки с помощью советов, объяснений и альтернативных подходов.
Чтобы использовать чат Copilot, пользователи должны иметь активную подписку на GitHub Copilot, а пользователи VS Code должны иметь последнее обновление и войти в VS Code с тем же идентификатором GitHub, который имеет доступ к GitHub Copilot.
Источник: https://www.infoq.com/news/2023/10/github-copilot-chat-open-beta/
Доступна Бета-Версия Чата Github Copilot
Чат GitHub Copilot — это интерфейс чата, который позволяет разработчикам задавать вопросы о написании кода и получать ответы непосредственно в IDE. В настоящее время он находится в открытой бета-версии и доступен для всех индивидуальных пользователей GitHub Copilot в Visual Studio и VS Code.
Чат GitHub Copilot был представлен в виде общедоступной бета-версии как расширение для разработки ПО на базе искусственного интеллекта для всех пользователей GitHub Copilot для бизнеса. Теперь он доступен бесплатно для всех индивидуальных пользователей Copilot и поддерживается как в редакторах Visual Studio, так и в VS Code. Он использует расширенную обработку естественного языка (natural language processing, NLP), чтобы предлагать помощь и ответы на естественном языке непосредственно в поддерживаемых редакторах. Это избавляет разработчиков от необходимости обращаться к документации или искать на интернет-форумах. Уменьшая необходимость переключения контекста, он оптимизирует процесс разработки, что помогает разработчикам сохранять концентрацию и динамику.
Также у отдельных контрибуторов есть возможность предлагать исправления безопасности, тем самым повышая общую безопасность проектов с открытым исходным кодом.
Другие функции включают:
- Индивидуальные предложения в режиме реального времени с лучшими практиками, советами и решениями.
- Разбор сложных понятий с пояснениями фрагментов кода
- Рекомендации по устранению и уменьшению количества уязвимостей, обнаруженных во время сканирования безопасности.
- Выявление проблем во время отладки с помощью советов, объяснений и альтернативных подходов.
Чтобы использовать чат Copilot, пользователи должны иметь активную подписку на GitHub Copilot, а пользователи VS Code должны иметь последнее обновление и войти в VS Code с тем же идентификатором GitHub, который имеет доступ к GitHub Copilot.
Источник: https://www.infoq.com/news/2023/10/github-copilot-chat-open-beta/
👍4👎2
Вы используете Copilot?
Anonymous Poll
11%
Да
61%
Нет
23%
Планирую попробовать
4%
Пробовал и отказался от него
👍2👎1
День 1721. #Книги
«Код, который умещается в голове» (Симан М. — СПб.: Питер, 2023).
От создателя «Внедрения зависимостей на платформе .NET». Для тех, кто не осилил «Совершенный код»)))
На самом деле, очень интересная книга. Разработчикам с большим опытом она вряд ли откроет что-то новое, но поможет напомнить некоторые лучшие практики. Марк Симан проделал огромную работу, перелопатив более 100 источников по разработке, написанию кода, работе в команде и т.п., среди которых «Совершенный код», «Программист-прагматик», «Экстремальное программирование», «Чистый код», «Шаблоны корпоративных приложений», «Разработка через тестирование», «Непрерывное развёртывание ПО»… В общем, всё, что должен прочитать каждый уважающий себя разработчик, собрано в одном месте. Как организовать проект, как писать читабельный код без ошибок, как работать в команде, как искать и исправлять ошибки, как организовать рабочий процесс и многое другое. Везде по тексту есть ссылки на источники, так что в любую тему можно углубиться, прочитав источник.
Книга не без косяков, конечно, но претензий к автору и содержанию никаких. Вообще в книгах и статьях Симана придраться к чему-то очень сложно. Здесь все косяки исключительно на совести переводчиков. Например, по какой-то неведомой причине ВЕЗДЕ в примерах создания приложения для ресторана столики (tables) переведены как таблицы))) При чтении не сразу понимаешь о каком «резервировании таблиц» идёт речь, но потом просто мысленно заменяешь все таблицы на столы, и всё становится на свои места.
Короче, отнесу книгу к категории «мастрид». Особенно для начинающих свою карьеру в разработке (в .NET то точно, потому что в книге неплохо разобран пример создания .NET веб-API).
«Код, который умещается в голове» (Симан М. — СПб.: Питер, 2023).
От создателя «Внедрения зависимостей на платформе .NET». Для тех, кто не осилил «Совершенный код»)))
На самом деле, очень интересная книга. Разработчикам с большим опытом она вряд ли откроет что-то новое, но поможет напомнить некоторые лучшие практики. Марк Симан проделал огромную работу, перелопатив более 100 источников по разработке, написанию кода, работе в команде и т.п., среди которых «Совершенный код», «Программист-прагматик», «Экстремальное программирование», «Чистый код», «Шаблоны корпоративных приложений», «Разработка через тестирование», «Непрерывное развёртывание ПО»… В общем, всё, что должен прочитать каждый уважающий себя разработчик, собрано в одном месте. Как организовать проект, как писать читабельный код без ошибок, как работать в команде, как искать и исправлять ошибки, как организовать рабочий процесс и многое другое. Везде по тексту есть ссылки на источники, так что в любую тему можно углубиться, прочитав источник.
Книга не без косяков, конечно, но претензий к автору и содержанию никаких. Вообще в книгах и статьях Симана придраться к чему-то очень сложно. Здесь все косяки исключительно на совести переводчиков. Например, по какой-то неведомой причине ВЕЗДЕ в примерах создания приложения для ресторана столики (tables) переведены как таблицы))) При чтении не сразу понимаешь о каком «резервировании таблиц» идёт речь, но потом просто мысленно заменяешь все таблицы на столы, и всё становится на свои места.
Короче, отнесу книгу к категории «мастрид». Особенно для начинающих свою карьеру в разработке (в .NET то точно, потому что в книге неплохо разобран пример создания .NET веб-API).
👍35
День 1722. #ЗаметкиНаПолях #Debugging
Правила Отладки: Ведите Журнал Аудита
Отладка - сложная задача, часто занимающая много времени. Поэтому наша цель - минимизация времени отладки. Каждая ошибка даёт возможность освоить методы предотвращения аналогичных проблем в будущем или быстрого их выявления, если они возникнут снова.
Ведите учёт выполненных действий, их последовательность и конечные результаты. Не полагайтесь на свою память, запишите всё. Иначе вы неизбежно упустите детали, которые казались несущественными, но по иронии судьбы окажутся ключевыми. Либо детали, которые не имели значения для вас, но могли бы помочь другим, решающим другие проблемы позже. Выберите простой и удобный цифровой формат, чтобы облегчить создание резервных копий, прикрепление к отчётам об ошибках и распространение среди команды.
Часто программисты при отладке заходят в тупик из-за чрезмерного погружения в бесплодные маршруты. Составьте список стратегий, которые можно попробовать, и, если один метод окажется неэффективным, перейдите к следующему. Но сохраните все ваши гипотезы и возможные решения.
Ведение журнала аудита во время отладки даёт несколько преимуществ:
1) Комплексное отслеживание.
Журнал фиксирует действия по расследованию, позволяя вам перепроверять ваши действия и решения.
2) Эффективное сотрудничество.
Коллеги могут понять ваш мыслительный процесс, что поможет им быстрее решить проблемы и свести к минимуму дублирование усилий.
3) Точное воспроизведение.
Следуя описанным шагам, вы увеличиваете вероятность точного воспроизведения проблемы, что приводит к более эффективному устранению неполадок.
4) Диагностика коренных причин.
Анализ журнала помогает определить момент или последовательность событий, вызвавших ошибку, что важно для выявления первопричин проблемы и формулирования точных решений.
5) Целостное понимание.
Маршрут воспроизведения ошибки фиксирует не только действия, но и контекст и состояние системы. Это полезно для понимания более широкой картины проблемы.
6) Обучение и совершенствование.
Анализ прошлых записей журнала позволяет учиться на предыдущем опыте и может помочь избежать подобных ошибок в будущем.
7) Адаптируемое решение проблем.
Благодаря журналу аудита вы можете переключаться между различными подходами, не теряя при этом прогресса. Если один из способов окажется неудачным, вы можете повторить свои шаги и поискать альтернативные решения.
8) Эффективная документация.
Журнал служит документацией усилий по отладке. Его можно использовать в дальнейшем для обучения новых членов команды и создания базы знаний.
9) Оптимизация времени.
Вместо бесцельного повторения своих шагов раз за разом вы можете обратиться к журналу, чтобы быстро возобновить расследование.
10) Аналитика на основе данных.
Записывая наблюдения, гипотезы и результаты, вы собираете данные, которые могут дать представление о повторяющихся проблемах, закономерностях и потенциальных улучшениях процесса разработки.
Итого
Если процесс поиска ошибки затягивается, сложно запомнить все попытки решения и полученные знания. Документируя процедуры и результаты тестов, вы снижаете вероятность упустить важные детали или ошибочно предположить, что вы уже изучили определённый путь. Запись своих мыслей поможет лучше запомнить проблему, когда вы столкнётесь с аналогичной ситуацией в будущем, а также будет полезна при изложении проблемы другому человеку.
Источник: https://dev.to/rajasegar/debugging-rules-keep-an-audit-trail-3he9
Правила Отладки: Ведите Журнал Аудита
Отладка - сложная задача, часто занимающая много времени. Поэтому наша цель - минимизация времени отладки. Каждая ошибка даёт возможность освоить методы предотвращения аналогичных проблем в будущем или быстрого их выявления, если они возникнут снова.
Ведите учёт выполненных действий, их последовательность и конечные результаты. Не полагайтесь на свою память, запишите всё. Иначе вы неизбежно упустите детали, которые казались несущественными, но по иронии судьбы окажутся ключевыми. Либо детали, которые не имели значения для вас, но могли бы помочь другим, решающим другие проблемы позже. Выберите простой и удобный цифровой формат, чтобы облегчить создание резервных копий, прикрепление к отчётам об ошибках и распространение среди команды.
Часто программисты при отладке заходят в тупик из-за чрезмерного погружения в бесплодные маршруты. Составьте список стратегий, которые можно попробовать, и, если один метод окажется неэффективным, перейдите к следующему. Но сохраните все ваши гипотезы и возможные решения.
Ведение журнала аудита во время отладки даёт несколько преимуществ:
1) Комплексное отслеживание.
Журнал фиксирует действия по расследованию, позволяя вам перепроверять ваши действия и решения.
2) Эффективное сотрудничество.
Коллеги могут понять ваш мыслительный процесс, что поможет им быстрее решить проблемы и свести к минимуму дублирование усилий.
3) Точное воспроизведение.
Следуя описанным шагам, вы увеличиваете вероятность точного воспроизведения проблемы, что приводит к более эффективному устранению неполадок.
4) Диагностика коренных причин.
Анализ журнала помогает определить момент или последовательность событий, вызвавших ошибку, что важно для выявления первопричин проблемы и формулирования точных решений.
5) Целостное понимание.
Маршрут воспроизведения ошибки фиксирует не только действия, но и контекст и состояние системы. Это полезно для понимания более широкой картины проблемы.
6) Обучение и совершенствование.
Анализ прошлых записей журнала позволяет учиться на предыдущем опыте и может помочь избежать подобных ошибок в будущем.
7) Адаптируемое решение проблем.
Благодаря журналу аудита вы можете переключаться между различными подходами, не теряя при этом прогресса. Если один из способов окажется неудачным, вы можете повторить свои шаги и поискать альтернативные решения.
8) Эффективная документация.
Журнал служит документацией усилий по отладке. Его можно использовать в дальнейшем для обучения новых членов команды и создания базы знаний.
9) Оптимизация времени.
Вместо бесцельного повторения своих шагов раз за разом вы можете обратиться к журналу, чтобы быстро возобновить расследование.
10) Аналитика на основе данных.
Записывая наблюдения, гипотезы и результаты, вы собираете данные, которые могут дать представление о повторяющихся проблемах, закономерностях и потенциальных улучшениях процесса разработки.
Итого
Если процесс поиска ошибки затягивается, сложно запомнить все попытки решения и полученные знания. Документируя процедуры и результаты тестов, вы снижаете вероятность упустить важные детали или ошибочно предположить, что вы уже изучили определённый путь. Запись своих мыслей поможет лучше запомнить проблему, когда вы столкнётесь с аналогичной ситуацией в будущем, а также будет полезна при изложении проблемы другому человеку.
Источник: https://dev.to/rajasegar/debugging-rules-keep-an-audit-trail-3he9
👍9
День 1723. #ЗаметкиНаПолях
Заменяем Разрывы Строк в C#
Замена разрывов строк в тексте - довольно распространённая задача. Иногда нужно сделать текст в одну строку, либо заменить разрыв строки HTML-элементом
В C# используются два основных типа разрывов строк:
-
-
Рекомендуемый способ записи разрыва строки — использовать Environment.Newline, который преобразуется в
1. Замена старым способом
Используем метод Replace() класса String:
Метод ReplaceLineEndings(), представленный в .NET 6, является более специализированным инструментом для замены разрывов строк и это рекомендуемый подход. Требуется один аргумент: любая строка для строки замены (по умолчанию - Environment.NewLine)
3. Регулярные выражения
Аналогично методу Replace() класса String, можно использовать метод Regex.Replace():
Производительность
Я протестировал производительность всех трёх способов в трёх версиях: .NET6, .NET7 и .NET8.
- string.Replace() примерно постоянен (~30-40нс).
- ReplaceLineEndings() примерно в 3 раза медленнее в .NET6 и .NET7 (~100-130нс), но в .NET8 он стал наоборот быстрее - ~25нс.
- Regex.Replace() примерно в 7 раз медленнее string.Replace() (~240-270нс) в .NET6 и .NET7, в .NET8 стал немного быстрее - ~200нс.
Однако, в .NET7+ для регулярных выражений мы можем использовать кодогенерацию (это даже предлагает сделать IDE):
Памяти все методы используют одинаково – 96 байт.
Источник: https://code-maze.com/csharp-replace-line-breaks-in-a-string/
Заменяем Разрывы Строк в C#
Замена разрывов строк в тексте - довольно распространённая задача. Иногда нужно сделать текст в одну строку, либо заменить разрыв строки HTML-элементом
<br />
для отображения на веб-сайте. Посмотрим, как это можно сделать.В C# используются два основных типа разрывов строк:
-
\n
: символ новой строки, используемый в системах Unix и Linux.-
\r\n
: символ возврата каретки в сочетании с символом новой строки, используется в системах Windows.Рекомендуемый способ записи разрыва строки — использовать Environment.Newline, который преобразуется в
\n
или \r\n
в зависимости от системы.1. Замена старым способом
Используем метод Replace() класса String:
const string text =Результат:
"This is a line.\rThis is another line.";
var newText = text
.Replace("\r\n", "\n")
.Replace("\r", "\n");
This is a line.\nThis is another line.2. Новый способ
Метод ReplaceLineEndings(), представленный в .NET 6, является более специализированным инструментом для замены разрывов строк и это рекомендуемый подход. Требуется один аргумент: любая строка для строки замены (по умолчанию - Environment.NewLine)
var newText = text.ReplaceLineEndings("\n");Результат будет таким же, как и в предыдущем способе.
3. Регулярные выражения
Аналогично методу Replace() класса String, можно использовать метод Regex.Replace():
var newText = RegexИ снова, результат будет тем же.
.Replace(text, @"(\r\n|\r)", "\n");
Производительность
Я протестировал производительность всех трёх способов в трёх версиях: .NET6, .NET7 и .NET8.
- string.Replace() примерно постоянен (~30-40нс).
- ReplaceLineEndings() примерно в 3 раза медленнее в .NET6 и .NET7 (~100-130нс), но в .NET8 он стал наоборот быстрее - ~25нс.
- Regex.Replace() примерно в 7 раз медленнее string.Replace() (~240-270нс) в .NET6 и .NET7, в .NET8 стал немного быстрее - ~200нс.
Однако, в .NET7+ для регулярных выражений мы можем использовать кодогенерацию (это даже предлагает сделать IDE):
var newText = MyRegex().Replace(text, "\n");Тогда метод Regex станет быстрее: ~180нс в .NET7 и ~130нс в .NET8.
[GeneratedRegex(@"(\r\n|\r)")]
private static partial Regex MyRegex();
Памяти все методы используют одинаково – 96 байт.
Источник: https://code-maze.com/csharp-replace-line-breaks-in-a-string/
👍17
День 1724. #ЗаметкиНаПолях
Структурированный Параллелизм в C#
Структурированный параллелизм — это концепция, которая помогает писать более надёжный и удобный в обслуживании асинхронный код. Она не нова, но не так широко известна. Идея состоит в том, чтобы иметь возможность группировать асинхронные операции и гарантировать, что все операции завершатся до завершения группы. Это делается с помощью специальной конструкции, называемой областью задачи (Task Scope). Область задачи — это конструкция, похожая на блок try-catch-finally. Она используется для группировки асинхронных операций и обеспечения завершения всех операций до завершения группы.
Рассмотрим пример:
Идея в том, что мы определяем области в методе Create. Всё внутри Create будет выполняться в определённой области. Таким образом, задачи логически связаны друг с другом: если в одной выбрасывается исключение, мы отменяем все задачи вместе.
Использование:
Источник: https://steven-giesel.com/blogPost/59e57336-7c73-472f-a781-b0b79f0d47ad
Структурированный Параллелизм в C#
Структурированный параллелизм — это концепция, которая помогает писать более надёжный и удобный в обслуживании асинхронный код. Она не нова, но не так широко известна. Идея состоит в том, чтобы иметь возможность группировать асинхронные операции и гарантировать, что все операции завершатся до завершения группы. Это делается с помощью специальной конструкции, называемой областью задачи (Task Scope). Область задачи — это конструкция, похожая на блок try-catch-finally. Она используется для группировки асинхронных операций и обеспечения завершения всех операций до завершения группы.
Рассмотрим пример:
public class TaskScopeИзвините за много кода, но это только упрощённая реализация.
{
private CancellationTokenSource _cts = new();
private ConcurrentBag<Task> _tasks = new();
private TaskScope() { }
public static async Task Create(
Func<TaskScope, Task> act)
{
await using var ts = new TaskScope();
await act(ts);
await ts.WaitForAll();
}
public static async Task Create(
Action<TaskScope> act)
{
await using var ts = new TaskScope();
act(ts);
await ts.WaitForAll();
}
public async ValueTask DisposeAsync()
{
_cts.Cancel();
await WaitForAll();
}
public Task Run(
Func<CancellationToken, Task> act)
{
var task = Task.Run(async () =>
{
try
{
await act(_cts.Token);
}
catch (Exception ex) when (
ex is not OperationCanceledException)
{
_cts.Cancel();
throw;
}
});
_tasks.Add(task);
return task;
}
private async Task WaitForAll()
{
try
{
await Task.WhenAll(_tasks.ToArray());
}
catch (Exception ex) when (
ex is not OperationCanceledException)
{
throw;
}
}
}
Идея в том, что мы определяем области в методе Create. Всё внутри Create будет выполняться в определённой области. Таким образом, задачи логически связаны друг с другом: если в одной выбрасывается исключение, мы отменяем все задачи вместе.
Использование:
var tasks = TaskScope.Create(group =>Как видите, мы можем сгруппировать задачи и убедиться, что все они выполнены до того, как будет завершена область действия. Если одна из задач завершается сбоем, все остальные задачи отменяются и появляется исключение. Это очень мощная концепция, которая помогает писать более надёжный и удобный в обслуживании асинхронный код. Более сложную реализацию можно найти здесь.
{
group.Run(async token =>
{
await Task.Delay(100, token);
throw new Exception("Boom!!!");
});
group.Run(async token =>
await Task.Delay(1000, token));
});
// Выполняется 100мс
// после ошибки в 1й задаче отменяются все.
// Исключение поднимается наверх
try
{
await tasks;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
// True
Console.WriteLine(tasks.IsFaulted);
Источник: https://steven-giesel.com/blogPost/59e57336-7c73-472f-a781-b0b79f0d47ad
👍25
День 1725. #Оффтоп #Обучение
Запертые Двери, Головные Боли и Интеллектуальные Потребности
Есть ли такие вещи, узнав о которых, вы начинали их видеть повсюду? Это «проблема очерёдности проблемы и решения». Сегодня поговорим о ней.
Игры
Новичок начинает игру с тщательно продуманного учебного уровня. Уровень приводит его к ключу, который он берёт, а затем к запертой двери, которую он успешно открывает. Далее в игре он натыкается на вторую запертую дверь… и оказывается в тупике. Он уже однажды решал эту проблему – почему ему так трудно решить её снова?
Здесь мы имеем дело с проблемой очерёдности проблемы и решения. Поскольку игрок сначала получил ключ, а потом наткнулся на запертую дверь, он так и не понял причинно-следственной связи между «получить ключ» и «открыть дверь». Он получил ключ, потом произошло ещё что-то, а потом он достиг двери, которую смог открыть. Если бы игрок сначала столкнулся с запертой дверью, попытался открыть её, но не смог, а затем нашёл ключ и использовал его, чтобы открыть дверь, причинно-следственная связь была бы очевидной. Вы используете ключ, чтобы открыть запертую дверь, потому что вы не можете открыть запертую дверь без ключа.
Математика
Помните, как на уроке математики вам давали концепцию, потом ещё более сложную концепцию, а вам всё это казалась совершенно бессмысленным? Проблема в том, что, прежде чем предлагать вам новую, более сложную концепцию, вам не дали возможности испытать ограничения старой. Другими словами: если вам представят решение (новую концепцию) до того, как представят тип задач, которые оно должно решить, решение, скорее всего, покажется бессмысленным и произвольным.
Представьте себя человеком, который продаёт аспирин. Лучший покупатель вашего аспирина — тот, у кого болит голова. Худшее, что вы можете сделать, — заставить людей, которые не чувствуют боли, принимать ваш аспирин. Они могут это сделать, но аспирин покажется им бессмысленным.
Программирование
В функциональном программировании есть понятие монады. Они очень абстрактны, и новичкам часто сложно их понять. Но монады на самом деле не так уж и сложны. Большинство опытных функциональных программистов считают их простыми. Очевидно, всему виной проблема очерёдности проблемы и решения.
Монады — это решение конкретной проблемы: повторяющегося кода. Если вы пишете достаточно кода на функциональном языке, вы начинаете замечать, что пишете много подозрительно похожего кода для решения множества внешне разных задач. Было бы здорово, просто написать этот код один раз, а затем использовать его повторно, вместо того чтобы каждый раз переписывать его немного по-другому. То есть опытные функциональные программисты почувствовали головную боль, для которой монады являются аспирином. А новички ещё не заметили никаких повторяющихся закономерностей; или повторение их ещё не беспокоит. Головной боли просто нет.
Худшее, что вы можете сделать, — это заставить людей, которые не чувствуют боли, принимать аспирин. Точно так же попытка «обучить монадам» начинающих функциональных программистов, которые ещё не понимают необходимости в монадах, скорее всего, принесёт больше вреда, чем пользы, создавая дополнительную ненужную путаницу и увековечивая миф о том, что монады по своей сути сложны для понимания.
Итого
Строгая очерёдность проблем и решений является одним из определяющих фактором для эффективного понимания. Хорошо продуманный материал сразу же предлагает читателю поиграть с первоначальным расположением элементов и тем самым самостоятельно обнаружить потенциальные проблемы. Непосредственный опыт решения проблемы вызывает интеллектуальную потребность (или, если хотите, «головную боль») и создаёт основу для последующего внедрения решения. Поэтому лучшие обучающие материалы начинают с постановки проблемы, а не предлагают решение сразу. Но даже если это не так, изучая новую концепцию, придумайте (или погуглите), какую проблему она призвана решить. Это очень поможет пониманию и запоминанию.
Источник: https://mkremins.github.io/blog/doors-headaches-intellectual-need/
Запертые Двери, Головные Боли и Интеллектуальные Потребности
Есть ли такие вещи, узнав о которых, вы начинали их видеть повсюду? Это «проблема очерёдности проблемы и решения». Сегодня поговорим о ней.
Игры
Новичок начинает игру с тщательно продуманного учебного уровня. Уровень приводит его к ключу, который он берёт, а затем к запертой двери, которую он успешно открывает. Далее в игре он натыкается на вторую запертую дверь… и оказывается в тупике. Он уже однажды решал эту проблему – почему ему так трудно решить её снова?
Здесь мы имеем дело с проблемой очерёдности проблемы и решения. Поскольку игрок сначала получил ключ, а потом наткнулся на запертую дверь, он так и не понял причинно-следственной связи между «получить ключ» и «открыть дверь». Он получил ключ, потом произошло ещё что-то, а потом он достиг двери, которую смог открыть. Если бы игрок сначала столкнулся с запертой дверью, попытался открыть её, но не смог, а затем нашёл ключ и использовал его, чтобы открыть дверь, причинно-следственная связь была бы очевидной. Вы используете ключ, чтобы открыть запертую дверь, потому что вы не можете открыть запертую дверь без ключа.
Математика
Помните, как на уроке математики вам давали концепцию, потом ещё более сложную концепцию, а вам всё это казалась совершенно бессмысленным? Проблема в том, что, прежде чем предлагать вам новую, более сложную концепцию, вам не дали возможности испытать ограничения старой. Другими словами: если вам представят решение (новую концепцию) до того, как представят тип задач, которые оно должно решить, решение, скорее всего, покажется бессмысленным и произвольным.
Представьте себя человеком, который продаёт аспирин. Лучший покупатель вашего аспирина — тот, у кого болит голова. Худшее, что вы можете сделать, — заставить людей, которые не чувствуют боли, принимать ваш аспирин. Они могут это сделать, но аспирин покажется им бессмысленным.
Программирование
В функциональном программировании есть понятие монады. Они очень абстрактны, и новичкам часто сложно их понять. Но монады на самом деле не так уж и сложны. Большинство опытных функциональных программистов считают их простыми. Очевидно, всему виной проблема очерёдности проблемы и решения.
Монады — это решение конкретной проблемы: повторяющегося кода. Если вы пишете достаточно кода на функциональном языке, вы начинаете замечать, что пишете много подозрительно похожего кода для решения множества внешне разных задач. Было бы здорово, просто написать этот код один раз, а затем использовать его повторно, вместо того чтобы каждый раз переписывать его немного по-другому. То есть опытные функциональные программисты почувствовали головную боль, для которой монады являются аспирином. А новички ещё не заметили никаких повторяющихся закономерностей; или повторение их ещё не беспокоит. Головной боли просто нет.
Худшее, что вы можете сделать, — это заставить людей, которые не чувствуют боли, принимать аспирин. Точно так же попытка «обучить монадам» начинающих функциональных программистов, которые ещё не понимают необходимости в монадах, скорее всего, принесёт больше вреда, чем пользы, создавая дополнительную ненужную путаницу и увековечивая миф о том, что монады по своей сути сложны для понимания.
Итого
Строгая очерёдность проблем и решений является одним из определяющих фактором для эффективного понимания. Хорошо продуманный материал сразу же предлагает читателю поиграть с первоначальным расположением элементов и тем самым самостоятельно обнаружить потенциальные проблемы. Непосредственный опыт решения проблемы вызывает интеллектуальную потребность (или, если хотите, «головную боль») и создаёт основу для последующего внедрения решения. Поэтому лучшие обучающие материалы начинают с постановки проблемы, а не предлагают решение сразу. Но даже если это не так, изучая новую концепцию, придумайте (или погуглите), какую проблему она призвана решить. Это очень поможет пониманию и запоминанию.
Источник: https://mkremins.github.io/blog/doors-headaches-intellectual-need/
👍28
День 1726. #ЗаметкиНаПолях
Изменяем Имена Встроенных Ресурсов в .NET
Когда вы используете встроенные ресурсы (embedded resources) в проекте .NET, имя ресурса вычисляется на основе пути к файлу. По умолчанию используется формат, вроде <Имя сборки>.<Путь к файлу>. Но путь к файлу не содержит разделителя пути (/ или \). Вместо этого разделитель пути заменяется точкой. Например, для файла resources/index.html:
Можно изменить имена встроенных ресурсов, используя LogicalName:
Источник: https://www.meziantou.net/customizing-the-embedded-resource-name-in-dotnet.htm
Изменяем Имена Встроенных Ресурсов в .NET
Когда вы используете встроенные ресурсы (embedded resources) в проекте .NET, имя ресурса вычисляется на основе пути к файлу. По умолчанию используется формат, вроде <Имя сборки>.<Путь к файлу>. Но путь к файлу не содержит разделителя пути (/ или \). Вместо этого разделитель пути заменяется точкой. Например, для файла resources/index.html:
<Project>имя ресурса будет
<ItemGroup>
<EmbeddedResource Include="resources\index.html" />
</ItemGroup>
</project>
MyProject.resources.index.htmlВы можете вывести список встроенных ресурсов, используя метод GetManifestResourceNames класса Assembly.
foreach(var name inПример вывода:
Assembly.GetExecutingAssembly()
.GetManifestResourceNames())
{
Console.WriteLine(name);
}
MyProject.resources.favicon.icoОднако вы не можете быть на 100% уверены, как читать встроенные ресурсы, поскольку такое именование может вызывать конфликты.
MyProject.resources.img.background.png
MyProject.resources.index.html
Можно изменить имена встроенных ресурсов, используя LogicalName:
<Project>Если добавить это в проект и снова выполнить код выше, получится что-то вроде этого:
<ItemGroup>
<EmbeddedResource Include="Resources/**/*">
<LogicalName>
$([System.String]::new('%(RelativeDir)').Replace('\','/'))%(FileName)%(Extension)
</LogicalName>
</EmbeddedResource>
</ItemGroup>
</Project>
Resources/favicon.icoИспользуя такое сопоставление, гораздо проще создать виртуальную файловую систему из встроенных ресурсов, поскольку имена файлов соответствуют фактической файловой иерархии.
Resources/img/background.png
Resources/index.html
Источник: https://www.meziantou.net/customizing-the-embedded-resource-name-in-dotnet.htm
👍13
День 1727. #Testing
Тестирование на Основе Свойств. Теория
В этой серии рассмотрим, что такое тестирование на основе свойств, почему оно полезно и как оно может помочь писать лучший код.
Примечание: это сложно! Оно рекомендуется для критических частей вашей кодовой базы, но вряд ли стоит его использовать везде.
Тестирование на основе свойств было введено в 2000 году Коэном Классеном и Джоном Хьюзом через библиотеку Haskell QuickCheck. Марк Симанн использует следующее определение в своем курсе Pluralsight по тестированию на основе свойств:
Тестирование на основе свойств — это метод автоматического тестирования, при котором вы постепенно концентрируетесь на правильном поведении системы, описывая её свойства или качества в общих чертах, а затем используете случайно сгенерированные тестовые данные для выполнения детерминированных тестов.
Оно довольно запутанное. Давайте разбираться.
Большинство тестов, которые пишут разработчики, — это тесты на основе примеров. Мы пытаемся подумать о том, какие входные данные будут репрезентативными для функций, которые мы хотим протестировать, и используем эти примеры для создания модульных тестов. Лучшие разработчики думают не только о счастливом пути, но и пытаются понять, что может быть неправильным вводом, чтобы увидеть, корректно ли функции обрабатывают условия сбоя.
Проблема в том, что, когда ваши функции достигают определённого уровня сложности, становится довольно трудно продумывать все возможные варианты (примеры). И хотя тестовое покрытие может составлять 100%, вы всё равно не на 100% уверены, что тесты охватывают все крайние случаи.
Тестирование на основе свойств может помочь справиться с недостатками тестов на основе примеров. Вместо того, чтобы находить подходящие примеры, мы пытаемся понять и представить взаимосвязь между нашими входными и выходными данными. Мы ищем правила, спецификации, «свойства», которые позволяют нам описать эту связь в общем виде, не уточняя, каким именно должен быть вход или выход.
Например:
1) Не имеет значения, в каком порядке мы вводим входные данные x и y, выходные данные одинаковы. 1+7 = 7+1
2) Ноль вместо x или y равносилен пустой операции (вывод не меняется). 7+0 = 0+7 = 7.
3) Если вызывать Add несколько раз, порядок вызовов не имеет значения. 7+(4+5) = (7+4)+5
Это прекрасно согласуется с математическим описанием операции сложения.
Пока это всё теория. Завтра рассмотрим тесты на основе свойств в C#.
Продолжение следует…
Источник: https://bartwullems.blogspot.com/2023/01/property-based-testing-in-cpart-1.html
Тестирование на Основе Свойств. Теория
В этой серии рассмотрим, что такое тестирование на основе свойств, почему оно полезно и как оно может помочь писать лучший код.
Примечание: это сложно! Оно рекомендуется для критических частей вашей кодовой базы, но вряд ли стоит его использовать везде.
Тестирование на основе свойств было введено в 2000 году Коэном Классеном и Джоном Хьюзом через библиотеку Haskell QuickCheck. Марк Симанн использует следующее определение в своем курсе Pluralsight по тестированию на основе свойств:
Тестирование на основе свойств — это метод автоматического тестирования, при котором вы постепенно концентрируетесь на правильном поведении системы, описывая её свойства или качества в общих чертах, а затем используете случайно сгенерированные тестовые данные для выполнения детерминированных тестов.
Оно довольно запутанное. Давайте разбираться.
Большинство тестов, которые пишут разработчики, — это тесты на основе примеров. Мы пытаемся подумать о том, какие входные данные будут репрезентативными для функций, которые мы хотим протестировать, и используем эти примеры для создания модульных тестов. Лучшие разработчики думают не только о счастливом пути, но и пытаются понять, что может быть неправильным вводом, чтобы увидеть, корректно ли функции обрабатывают условия сбоя.
Проблема в том, что, когда ваши функции достигают определённого уровня сложности, становится довольно трудно продумывать все возможные варианты (примеры). И хотя тестовое покрытие может составлять 100%, вы всё равно не на 100% уверены, что тесты охватывают все крайние случаи.
Тестирование на основе свойств может помочь справиться с недостатками тестов на основе примеров. Вместо того, чтобы находить подходящие примеры, мы пытаемся понять и представить взаимосвязь между нашими входными и выходными данными. Мы ищем правила, спецификации, «свойства», которые позволяют нам описать эту связь в общем виде, не уточняя, каким именно должен быть вход или выход.
Например:
int Add(int x, int y) => x+y;Чтобы протестировать метод Add, мы можем попытаться придумать репрезентативные примеры, но существует бесконечный список возможных комбинаций. Вместо этого попробуем описать метод Add как связь между входными и выходными данными:
1) Не имеет значения, в каком порядке мы вводим входные данные x и y, выходные данные одинаковы. 1+7 = 7+1
2) Ноль вместо x или y равносилен пустой операции (вывод не меняется). 7+0 = 0+7 = 7.
3) Если вызывать Add несколько раз, порядок вызовов не имеет значения. 7+(4+5) = (7+4)+5
Это прекрасно согласуется с математическим описанием операции сложения.
Пока это всё теория. Завтра рассмотрим тесты на основе свойств в C#.
Продолжение следует…
Источник: https://bartwullems.blogspot.com/2023/01/property-based-testing-in-cpart-1.html
👍14
День 1728. #Testing
Тестирование на Основе Свойств. Простой пример
Теория
Итак, напишем тесты согласно свойствам, которые мы определили.
FsCheck — это платформа тестирования на основе свойств, созданная для F#, но её можно использовать и в C#. Программист предоставляет спецификацию программы в виде свойств, которым должны удовлетворять функции, методы или объекты, а FsCheck проверяет, сохраняются ли эти свойства на большом количестве случайно сгенерированных случаев. Вы фактически пишете тестируемую спецификацию вашей программы. Спецификации выражаются на F#, C# или VB с использованием комбинаторов, определённых в библиотеке FsCheck. FsCheck предоставляет комбинаторы для определения свойств, наблюдения за распределением тестовых данных и определения генераторов тестовых данных. При сбое свойства FsCheck автоматически отображает минимальный контрпример.
Есть плагины FsCheck для всех популярных тестовых сред. Всё, что нам нужно, - это установить NuGet пакет и заменить атрибуты
Тесты по-прежнему будут проходить. По умолчанию FsCheck останавливается после 100 попыток. Если вы хотите знать протестированные значения, задайте свойству Verbose атрибута Property значение true:
Продолжение следует…
Источник: https://bartwullems.blogspot.com/2023/01/property-based-testing-in-cpart-2.html
Тестирование на Основе Свойств. Простой пример
Теория
Итак, напишем тесты согласно свойствам, которые мы определили.
int Add(int x, int y) => x+y;У нас должно получиться 3 теста:
public class AddTwoNumbersTestsПока это не сильно отличается от обычных тестов на основе примеров. Теперь задача состоит в том, чтобы сгенерировать правильные псевдослучайные значения, которые можно использовать в качестве входных данных. В этом нам поможет FsCheck.
{
int Add(int x, int y) => x + y;
[Theory]
public void NoOrderOfParameters(int x, int y)
{
var res1 = Add(x, y);
var res2 = Add(y, x);
Assert.Equal(res1, res2);
}
[Theory]
public void ZeroDoesNothing(int x)
{
var res1 = Add(x, 0);
var res2 = x;
Assert.Equal(res1, res2);
}
[Theory]
public void OrderDoesntMatter(int x, int y, int z)
{
var res1 = Add(Add(x, y), z);
var res2 = Add(x, Add(y, z));
Assert.Equal(res1, res2);
}
}
FsCheck — это платформа тестирования на основе свойств, созданная для F#, но её можно использовать и в C#. Программист предоставляет спецификацию программы в виде свойств, которым должны удовлетворять функции, методы или объекты, а FsCheck проверяет, сохраняются ли эти свойства на большом количестве случайно сгенерированных случаев. Вы фактически пишете тестируемую спецификацию вашей программы. Спецификации выражаются на F#, C# или VB с использованием комбинаторов, определённых в библиотеке FsCheck. FsCheck предоставляет комбинаторы для определения свойств, наблюдения за распределением тестовых данных и определения генераторов тестовых данных. При сбое свойства FsCheck автоматически отображает минимальный контрпример.
Есть плагины FsCheck для всех популярных тестовых сред. Всё, что нам нужно, - это установить NuGet пакет и заменить атрибуты
[Theory]
на [Property]
.Тесты по-прежнему будут проходить. По умолчанию FsCheck останавливается после 100 попыток. Если вы хотите знать протестированные значения, задайте свойству Verbose атрибута Property значение true:
[Property(Verbose = true)]Вот пример вывода:
NoOrderOfParametersКонечно, это очень простой пример. Далее рассмотрим что-то более реалистичное.
Standard Output:
0:
(0, 0)
1:
(-1, 1)
2:
(1, 1)
…
Продолжение следует…
Источник: https://bartwullems.blogspot.com/2023/01/property-based-testing-in-cpart-2.html
👍13
День 1729. #Testing
Тестирование на Основе Свойств. Реальный пример
Теория
Простой пример
Сегодня рассмотрим более реалистичный пример и функции, которые предоставляет FsCkeck. Допустим, нам нужно проверить номер кредитной карты.
Если у нас есть метод
Используем FsCheck:
Произвольные значения (Arbitraties)
FsCheck использует комбинацию генераторов (generator) и сокращателей (shrinker) для создания тестовых данных. Генераторы производят случайный набор значений из интервала с равномерным распределением. Сокращатели ограничивают (фильтруют) этот набор по заданному условию. В FsCheck определены произвольные значения по умолчанию для некоторых часто используемых типов:
- NegativeInt
- NonNegativeInt
- NonEmptyString
- IntWithMinMax
- NonEmptyArray
и т.п.
Используем альтернативную форму записи тестового метода с использованием предопределённых произвольных значений:
Продолжение следует…
Источник: https://bartwullems.blogspot.com/2023/01/property-based-testing-in-cpart-3.html
Тестирование на Основе Свойств. Реальный пример
Теория
Простой пример
Сегодня рассмотрим более реалистичный пример и функции, которые предоставляет FsCkeck. Допустим, нам нужно проверить номер кредитной карты.
Если у нас есть метод
CardNumber.IsValid()
, проверяющий валидность номера кредитной карты, мы можем добавить тесты, вроде следующих:[TestCase("12345678910")]Как видите, это вполне типичные примеры тестов. Некоторые магические значения использовались для проверки теста, но уверены ли мы, что охватили все крайние случаи?
[TestCase("12345621748")]
[TestCase("12345621777")]
[TestCase("Test")]
[TestCase("00000000000")]
[TestCase("99999999999")]
[TestCase("!@#!@%^@^@$^&@$^sdfasdf")]
[TestCase("$^@#^@##$44")]
[TestCase("15435#$%4354dfsg")]
[TestCase("90022742192")]
public void ValidationShouldFail(string num)
{
var result = CardNumber.IsValid(num);
result.Should().BeFalse();
}
Используем FsCheck:
[Property]Также можно использовать альтернативную форму записи теста:
public bool ValidationShouldFail(string num)
{
return !CardNumber.IsValid(num);
}
[Property]Тест проходит, но если посмотреть расшифровку (
public void ValidationShouldFail()
{
Prop.ForAll<string>(
x => !CardNumber.IsValid(x)
)
.VerboseCheck();
}
[Property(Verbose = true)]
), мы можем заметить, что проверяются случайные строки, и вряд ли хотя бы одна из них будет валидным номером карты. Мы можем заменить строку на long, но это тоже вряд ли сильно ограничит варианты.Произвольные значения (Arbitraties)
FsCheck использует комбинацию генераторов (generator) и сокращателей (shrinker) для создания тестовых данных. Генераторы производят случайный набор значений из интервала с равномерным распределением. Сокращатели ограничивают (фильтруют) этот набор по заданному условию. В FsCheck определены произвольные значения по умолчанию для некоторых часто используемых типов:
- NegativeInt
- NonNegativeInt
- NonEmptyString
- IntWithMinMax
- NonEmptyArray
и т.п.
Используем альтернативную форму записи тестового метода с использованием предопределённых произвольных значений:
[Property(Verbose = true)]Здесь мы использовали произвольные значения для long и функцию-сокращатель (x > 100). Заметьте, что FsCheck сначала генерирует случайные значения, а затем проверяет их на соответствие условию сокращателя. В примере выше при попытке задать большое значение в функции Filter, тесты могут выполняться очень долго.
public Property ValidationShouldFail()
{
var arb = Arb
.Default
.Int64()
.Filter(x => x > 100);
return Prop.ForAll<Int64>(
arb,
x => !CardNumber.IsValid(x.ToString()));
}
Продолжение следует…
Источник: https://bartwullems.blogspot.com/2023/01/property-based-testing-in-cpart-3.html
👍4
День 1730. #Testing
Тестирование на Основе Свойств. Собственный генератор
Теория
Простой пример
Реальный пример
Сегодня рассмотрим, как писать собственные генераторы.
В предыдущем примере мы использовали Filter(), чтобы возвращать только нужные числа.
Для создания генератора нужен публичный статический класс с публичным статическим методом, возвращающим Arbitrary<T>.
Например, так можно создать генератор месяца в определённом году:
В этом же классе можно создать свой сокращатель:
Источник: https://bartwullems.blogspot.com/2023/01/property-based-testing-in-cpart-4.html
Тестирование на Основе Свойств. Собственный генератор
Теория
Простой пример
Реальный пример
Сегодня рассмотрим, как писать собственные генераторы.
В предыдущем примере мы использовали Filter(), чтобы возвращать только нужные числа.
Для создания генератора нужен публичный статический класс с публичным статическим методом, возвращающим Arbitrary<T>.
public static class CCNumberGeneratorТеперь его можно использовать в качестве типа генератора в атрибуте Property:
{
public static Arbitrary<Int64> Generate()
{
return Arb.Default
.Int64()
.Filter(x => x > 100);
}
}
[Property(Arbitrary = new[] {В примере выше мы использовали существующий генератор. Но можно и создать его с нуля. Одной из наиболее часто используемых функций является
typeof(CCNumberGenerator) },
Verbose = true)]
public bool ValidateShouldFail(long num)
{
return !CardNumber.IsValid(num.ToString());
}
Gen.Choose()
, которая осуществляет случайный выбор значения из интервала с равномерным распределением.Например, так можно создать генератор месяца в определённом году:
public static class MonthOfYearGeneratorНа самом деле, вспомогательных функций для генератора очень много, и можно создавать генераторы любой сложности.
{
public static Gen<MonthOfYear> Generator =
from month in Gen.Choose(1, 12)
from year in Gen.Choose(1982, 2023)
select new MonthOfYear()
{
Month = month,
Year = year
};
public static Arbitrary<MonthOfYear> Generate() =>
Arb.From(Generator);
}
В этом же классе можно создать свой сокращатель:
public static IEnumerable<MonthOfYear>А затем использовать перегрузку метода Generate, принимающую и генератор, и сокращатель:
Shrinker(MonthOfYear moy)
{
yield return new MonthOfYear() {
Month = moy.Month,
Year = moy.Year - 1
};
yield return new MonthOfYear() {
Month = moy.Month,
Year = moy.Year + 1
};
}
public static Arbitrary<MonthOfYear> Generate() =>Окончание следует…
Arb.From(Generator, Shrinker);
Источник: https://bartwullems.blogspot.com/2023/01/property-based-testing-in-cpart-4.html
👍5
День 1731. #Testing
Тестирование на Основе Свойств. Воспроизведение
Теория
Простой пример
Реальный пример
Собственный генератор
Для каждого тестируемого свойства FsCheck генерирует случайные входные значения. Эти значения могут быть разными для каждого запуска теста, что означает, что каждый запуск может закончиться разными результатами. Поэтому, если у вас было неправильное входное значение, которое не прошло тест в предыдущий раз, вполне возможно, что при следующем запуске теста вы больше не увидите этот неправильный вход. Для простых входных значений это не должно быть проблемой. Но если вы используете более сложные входные данные, повторить неудачный тест может быть трудно.
Если посмотреть на выходные данные неудавшегося теста, можно заметить строку вроде
Ещё одна область, где могут пригодиться тесты на основе свойств, — это случаи, когда вам нужен своего рода приёмочный тест для какого-то кода. Например, у вас есть некоторый метод, в правильности которого вы уверены, но необходимо провести его рефакторинг, либо он недостаточно быстр. Вы можете написать тест на основе свойств, в котором свойство, которое должно соблюдаться, заключается в том, что для любых входных данных результат изначального метода должен совпадать с результатом нового. Затем увеличьте количество случайных входных данных настолько, чтобы можно было быть уверенным в правильности. И если тесты проходят, значит новый метод работает правильно.
Итого
Тесты на основе свойств полезны, но не являются панацеей. Их может быть сложнее читать другим разработчикам, которые не привыкли проводить тестирование на основе свойств. Когда вы решаете реализовать свои собственные произвольные алгоритмы и ограничиваете возможные произвольные значения, вы рискуете упустить важные случаи из-за излишней строгости, как и при написании обычных тестов. Тесты на основе свойств также выполняются медленнее: по умолчанию они генерируют 100 случайных входных данных и проверяют их. Поскольку вы имеете дело со случайностью, это также означает, что два прогона теста не идентичны. У вас может быть удачный, а затем неудачный прогон. Если второй запуск выявит реальную проблему, то всё в порядке. Следует написать специальный модульный тест для этого случая, а затем исправить проблему. Однако если это связано с тем, что один из ваших генераторов случайно генерирует значения, которые сильно отличаются от ожидаемых входных данных, выявить и устранить проблему может быть сложнее. Это связано с тем, что сначала вам нужно идентифицировать генератор, дающий неожиданные значения, и обернуть его механизмом фильтрации. И, хотя это возможно сделать, это всё же больше работы, чем простое изменение постоянного значения, определённого в модульном тесте.
Тестирование на основе свойств – очень мощный инструмент, о котором часто забывают. Оно действительно может выявить скрытые и неочевидные ошибки в самых сложных участках кода.
Источники:
- https://bartwullems.blogspot.com/2023/01/property-based-testing-in-cpart-5.html
- https://rasmus-feldthaus.medium.com/supercharge-your-testing-with-property-based-tests-bc3a7b75ca9f
Тестирование на Основе Свойств. Воспроизведение
Теория
Простой пример
Реальный пример
Собственный генератор
Для каждого тестируемого свойства FsCheck генерирует случайные входные значения. Эти значения могут быть разными для каждого запуска теста, что означает, что каждый запуск может закончиться разными результатами. Поэтому, если у вас было неправильное входное значение, которое не прошло тест в предыдущий раз, вполне возможно, что при следующем запуске теста вы больше не увидите этот неправильный вход. Для простых входных значений это не должно быть проблемой. Но если вы используете более сложные входные данные, повторить неудачный тест может быть трудно.
Если посмотреть на выходные данные неудавшегося теста, можно заметить строку вроде
Falsifiable, after 3 tests (4241 shrinks) (StdGen(318823861,297138967)).StdGen – это начальные значения, которые FsCheck использовал для генерации входных данных. Если вы хотите использовать в своём тесте точно такие же входные данные, используйте это значение в свойстве Replay атрибута Property:
[Property(Replay="318823861,297138967")]Приёмочные тесты на основе свойств
public bool ValidationShouldFail(long num)
{
…
}
Ещё одна область, где могут пригодиться тесты на основе свойств, — это случаи, когда вам нужен своего рода приёмочный тест для какого-то кода. Например, у вас есть некоторый метод, в правильности которого вы уверены, но необходимо провести его рефакторинг, либо он недостаточно быстр. Вы можете написать тест на основе свойств, в котором свойство, которое должно соблюдаться, заключается в том, что для любых входных данных результат изначального метода должен совпадать с результатом нового. Затем увеличьте количество случайных входных данных настолько, чтобы можно было быть уверенным в правильности. И если тесты проходят, значит новый метод работает правильно.
Итого
Тесты на основе свойств полезны, но не являются панацеей. Их может быть сложнее читать другим разработчикам, которые не привыкли проводить тестирование на основе свойств. Когда вы решаете реализовать свои собственные произвольные алгоритмы и ограничиваете возможные произвольные значения, вы рискуете упустить важные случаи из-за излишней строгости, как и при написании обычных тестов. Тесты на основе свойств также выполняются медленнее: по умолчанию они генерируют 100 случайных входных данных и проверяют их. Поскольку вы имеете дело со случайностью, это также означает, что два прогона теста не идентичны. У вас может быть удачный, а затем неудачный прогон. Если второй запуск выявит реальную проблему, то всё в порядке. Следует написать специальный модульный тест для этого случая, а затем исправить проблему. Однако если это связано с тем, что один из ваших генераторов случайно генерирует значения, которые сильно отличаются от ожидаемых входных данных, выявить и устранить проблему может быть сложнее. Это связано с тем, что сначала вам нужно идентифицировать генератор, дающий неожиданные значения, и обернуть его механизмом фильтрации. И, хотя это возможно сделать, это всё же больше работы, чем простое изменение постоянного значения, определённого в модульном тесте.
Тестирование на основе свойств – очень мощный инструмент, о котором часто забывают. Оно действительно может выявить скрытые и неочевидные ошибки в самых сложных участках кода.
Источники:
- https://bartwullems.blogspot.com/2023/01/property-based-testing-in-cpart-5.html
- https://rasmus-feldthaus.medium.com/supercharge-your-testing-with-property-based-tests-bc3a7b75ca9f
👍4
День 1732. #ЗаметкиНаПолях
Оптимизация памяти с помощью ArrayPool в C#
В C# пул массивов представлен классом ArrayPool<T>. Это потокобезопасный класс, предоставляющий структурированный механизм для эффективного управления и повторного использования массивов типа T.
Также можно использовать метод расширения Create():
Использование:
Здесь следует отметить, что фактический размер массива, который мы получаем из ArrayPool, как минимум равен размеру, который мы запрашиваем. Т.е. полученный массив может иметь большую длину. ArrayPool состоит из массивов с размерами, равными степени 2, начиная с длины 16. Таким образом, когда мы запрашиваем массив определённого размера, мы получаем ближайший доступный массив как минимум этого размера. В примере выше размер массива будет 16, а не 10.
Использование ArrayPool не только значительно быстрее, но и эффективно использует память. ArrayPool не выделяет память (кроме изначальной инициализации). Поэтому при интенсивном переиспользовании массивов разница между pool.Rent() и new становится огромной.
Итого
ArrayPool — отличный выбор, когда нужно оптимизировать память и уменьшить её фрагментацию, особенно в сценариях, где производительность критична. Он позволяет повторно использовать существующие блоки памяти посредством переиспользования массива. Однако придётся явно возвращать взятые массивы в пул с помощью метода Return(). Кроме того, арендованный массив может иметь размер, превышающий тот, который нам действительно нужен, что потребует специальных манипуляций для соответствия нашему конкретному сценарию использования. В приложениях, где производительность критична, и где часто используются и инициализируются массивы, предпочтительным вариантом является ArrayPool, тогда как для более простых случаев использования с менее частым созданием массивов предпочтительнее будет new.
Источник: https://code-maze.com/csharp-arraypool-memory-optimization/
Оптимизация памяти с помощью ArrayPool в C#
В C# пул массивов представлен классом ArrayPool<T>. Это потокобезопасный класс, предоставляющий структурированный механизм для эффективного управления и повторного использования массивов типа T.
var arrPool = ArrayPool<int>.Shared;Здесь мы создаём пул целочисленных массивов, который используется во всём приложении. Он имеет максимальную длину массива по умолчанию, равную 2^20 (1024*1024 = 1.048.576) байт.
Также можно использовать метод расширения Create():
var arrPool = ArrayPool<int>.Create(100, 10);Здесь первый аргумент метода Create() устанавливает максимальную длину массива в ArrayPool. Второй аргумент определяет количество массивов в сегменте. Пул группирует массивы одинаковой длины в эти сегменты, чтобы мы могли быстрее получить к ним доступ. Однако ограничивать пулы массивов этими параметрами нужно с осторожностью. Если мы превысим лимиты, произойдёт выделение памяти для нового массива.
Использование:
var pool = ArrayPool<int>.Shared;Сначала мы инициализируем пул, затем используем метод Rent() для получения массива длиной size из пула.
var size = 10;
var arr = pool.Rent(size);
for (var i = 0; i < size; i++)
arr[i] = i * 2;
Console.WriteLine("Элементы:");
for (var i = 0; i < size; i++)
Console.Write(arr[i] + " ");
pool.Return(arr);
// ВыводВ конце мы должны использовать метод Return(), чтобы отправить массив обратно в пул. Таким образом, он снова доступен для следующего использования.
Элементы:
0 2 4 6 8 10 12 14 16 18
Здесь следует отметить, что фактический размер массива, который мы получаем из ArrayPool, как минимум равен размеру, который мы запрашиваем. Т.е. полученный массив может иметь большую длину. ArrayPool состоит из массивов с размерами, равными степени 2, начиная с длины 16. Таким образом, когда мы запрашиваем массив определённого размера, мы получаем ближайший доступный массив как минимум этого размера. В примере выше размер массива будет 16, а не 10.
Использование ArrayPool не только значительно быстрее, но и эффективно использует память. ArrayPool не выделяет память (кроме изначальной инициализации). Поэтому при интенсивном переиспользовании массивов разница между pool.Rent() и new становится огромной.
Итого
ArrayPool — отличный выбор, когда нужно оптимизировать память и уменьшить её фрагментацию, особенно в сценариях, где производительность критична. Он позволяет повторно использовать существующие блоки памяти посредством переиспользования массива. Однако придётся явно возвращать взятые массивы в пул с помощью метода Return(). Кроме того, арендованный массив может иметь размер, превышающий тот, который нам действительно нужен, что потребует специальных манипуляций для соответствия нашему конкретному сценарию использования. В приложениях, где производительность критична, и где часто используются и инициализируются массивы, предпочтительным вариантом является ArrayPool, тогда как для более простых случаев использования с менее частым созданием массивов предпочтительнее будет new.
Источник: https://code-maze.com/csharp-arraypool-memory-optimization/
👍20
День 1733. #BestPractices #ProjectManagement
Принципы Бережливой Разработки ПО
Бережливая Разработка ПО (Lean Software Development) — это гибкая система управления проектами и разработки продуктов, основанная на принципах бережливого производства. Основное внимание уделяется обеспечению ценности для клиента путём оптимизации ресурсов, рабочих потоков и процессов. Ниже рассмотрим основные принципы бережливой разработки.
1. Устранение потерь
Эта концепция заимствована из мира бережливого производства, где она известна как «муда» (от японского бесполезность, расточительность). В разработке ПО потерями может быть что угодно: от написания ненужного кода до чрезмерных совещаний, которые не приносят никакой пользы. Цель состоит в том, чтобы оптимизировать рабочий процесс, выявляя и удаляя всё, что не помогает конечному продукту или не удовлетворяет потребностям клиента.
2. Усиленное обучение
Обучение является неотъемлемой частью разработки. Принцип усиленного обучения подчёркивает, что команда всегда должна находиться в состоянии непрерывного обучения. Будь то проверка кода, обратная связь или изучение новых материалов, этот принцип предполагает, что более информированная команда производит продукт более высокого качества. Такие практики, как предметно-ориентированное проектирование (DDD), помогают команде сосредоточиться на изучении и правильном моделировании предметной области.
3. Принятие решения как можно позже
Слишком раннее принятие решений может привести к переработке, если эти решения окажутся неправильными. Этот принцип советует отложить принятие решения до последнего ответственного момента. Это позволит команде получить максимальное количество информации и контекста перед принятием решения, тем самым снижая вероятность дорогостоящих ошибок.
4. Максимально быстрая поставка
Скорость и эффективность являются ключевыми факторами в бережливой разработке программного обеспечения. Этот принцип направлен на максимально быструю поставку функционального продукта покупателю. Речь идет не о спешке, а о поиске оптимального потока, который позволит выполнить быструю поставку без ущерба для качества. Важными показателями, которые команды могут отслеживать, чтобы определить скорость поставки готовых продуктов, являются
- время цикла (cycle time) - время, которое нужно команде, чтобы создать продукт,
- время поставки (lead time) – время между выставлением заказа клиентом и исполнением заказа.
5. Расширение возможностей команды
В рамках бережливой разработки ПО мотивированная и самостоятельная команда считается более эффективной и гибкой. Расширение прав и возможностей команды предполагает предоставление им автономии в принятии решений и ответственности за выполнение своих задач. Это создаёт чувство ответственности среди членов команды, повышая их производительность и продуктивность.
6. Обеспечение целостности
Качество не должно быть второстепенным вопросом; оно должно быть интегрировано в продукт с самого начала. Обеспечение целостности означает создание надёжной, удобной в обслуживании и адаптируемой системы с самого начала. Это требует стремления к совершенству от каждого члена команды на каждом этапе процесса разработки.
7. Оптимизация всего
Принципы бережливого производства подчеркивают важность рассмотрения процесса разработки как единого целого. Вместо того, чтобы сосредотачиваться исключительно на отдельных задачах или модулях, важно понять, как каждый элемент вписывается в общую картину. Оптимизируя всю систему, а не её части, вы можете обеспечить максимальную эффективность всего процесса.
Помните: «система, порождающая дефекты, является дефектной системой» - Джеффри Палермо. Обеспечьте качество всего процесса и выявляйте проблемы до того, как они покинут процесс.
Источник: https://ardalis.com/principles-lean-software-development/
Принципы Бережливой Разработки ПО
Бережливая Разработка ПО (Lean Software Development) — это гибкая система управления проектами и разработки продуктов, основанная на принципах бережливого производства. Основное внимание уделяется обеспечению ценности для клиента путём оптимизации ресурсов, рабочих потоков и процессов. Ниже рассмотрим основные принципы бережливой разработки.
1. Устранение потерь
Эта концепция заимствована из мира бережливого производства, где она известна как «муда» (от японского бесполезность, расточительность). В разработке ПО потерями может быть что угодно: от написания ненужного кода до чрезмерных совещаний, которые не приносят никакой пользы. Цель состоит в том, чтобы оптимизировать рабочий процесс, выявляя и удаляя всё, что не помогает конечному продукту или не удовлетворяет потребностям клиента.
2. Усиленное обучение
Обучение является неотъемлемой частью разработки. Принцип усиленного обучения подчёркивает, что команда всегда должна находиться в состоянии непрерывного обучения. Будь то проверка кода, обратная связь или изучение новых материалов, этот принцип предполагает, что более информированная команда производит продукт более высокого качества. Такие практики, как предметно-ориентированное проектирование (DDD), помогают команде сосредоточиться на изучении и правильном моделировании предметной области.
3. Принятие решения как можно позже
Слишком раннее принятие решений может привести к переработке, если эти решения окажутся неправильными. Этот принцип советует отложить принятие решения до последнего ответственного момента. Это позволит команде получить максимальное количество информации и контекста перед принятием решения, тем самым снижая вероятность дорогостоящих ошибок.
4. Максимально быстрая поставка
Скорость и эффективность являются ключевыми факторами в бережливой разработке программного обеспечения. Этот принцип направлен на максимально быструю поставку функционального продукта покупателю. Речь идет не о спешке, а о поиске оптимального потока, который позволит выполнить быструю поставку без ущерба для качества. Важными показателями, которые команды могут отслеживать, чтобы определить скорость поставки готовых продуктов, являются
- время цикла (cycle time) - время, которое нужно команде, чтобы создать продукт,
- время поставки (lead time) – время между выставлением заказа клиентом и исполнением заказа.
5. Расширение возможностей команды
В рамках бережливой разработки ПО мотивированная и самостоятельная команда считается более эффективной и гибкой. Расширение прав и возможностей команды предполагает предоставление им автономии в принятии решений и ответственности за выполнение своих задач. Это создаёт чувство ответственности среди членов команды, повышая их производительность и продуктивность.
6. Обеспечение целостности
Качество не должно быть второстепенным вопросом; оно должно быть интегрировано в продукт с самого начала. Обеспечение целостности означает создание надёжной, удобной в обслуживании и адаптируемой системы с самого начала. Это требует стремления к совершенству от каждого члена команды на каждом этапе процесса разработки.
7. Оптимизация всего
Принципы бережливого производства подчеркивают важность рассмотрения процесса разработки как единого целого. Вместо того, чтобы сосредотачиваться исключительно на отдельных задачах или модулях, важно понять, как каждый элемент вписывается в общую картину. Оптимизируя всю систему, а не её части, вы можете обеспечить максимальную эффективность всего процесса.
Помните: «система, порождающая дефекты, является дефектной системой» - Джеффри Палермо. Обеспечьте качество всего процесса и выявляйте проблемы до того, как они покинут процесс.
Источник: https://ardalis.com/principles-lean-software-development/
👍11
День 1734. #ЗаметкиНаПолях
Фоновые Задачи и Как Их Использовать. Начало
В .NET фоновые задачи — это асинхронные операции, которые выполняются независимо от основного потока приложения. Они используются для выполнения задач, которые не должны блокировать основной поток, например длительных вычислений, операций ввода-вывода или задач, которые могут выполняться одновременно.
Одной из распространённых реализаций является использование async/await:
Варианты использования в реальных приложениях
1. Уведомления по email:
Отправка уведомлений по email может занимать много времени и вызывать задержки в сети. Вы не хотите, чтобы основной поток приложения ждал завершения доставки email.
2. Обработка изображений и файлов:
Такие задачи, как изменение размера изображения, загрузка файлов или перекодирование видео, могут требовать больших ресурсов и времени.
3. Очистка и обслуживание базы данных:
В приложениях с БД рутинные задачи обслуживания, такие как архивирование, очистка старых данных или переиндексация, могут быть критически важными, но отнимать много времени. Такие задачи можно реализовать в фоновом процессе и запланировать на время минимальной нагрузки основного приложения.
4. Обслуживание кэша:
Со временем в кэшах могут накапливаться устаревшие данные, что приводит к неэффективности и увеличению использования памяти.
Завтра рассмотрим пример, как реализовать фоновую задачу очистки кэша.
Окончание следует…
Источник: https://stefandjokic.tech/posts/background-tasks-how-to-use-them
Фоновые Задачи и Как Их Использовать. Начало
В .NET фоновые задачи — это асинхронные операции, которые выполняются независимо от основного потока приложения. Они используются для выполнения задач, которые не должны блокировать основной поток, например длительных вычислений, операций ввода-вывода или задач, которые могут выполняться одновременно.
Одной из распространённых реализаций является использование async/await:
Console.WriteLine("Основной поток: старт");
var bgTask = Task.Run(() => DoBgWork());
// продолжаем работу в основном потоке
for (int i = 0; i < 5; i++)
{
Console.WriteLine($"Основной поток: {i}...");
await Task.Delay(1000);
}
// ждём завершения фоновой задачи
await bgTask;
Console.WriteLine("Основной поток: завершено.");
static void DoBgWork()
{
Console.WriteLine("Фоновый поток: старт");
// какая-то длительная работа
for (int i = 0; i < 5; i++)
{
Console.WriteLine($"Фоновый поток: {i}...");
Task.Delay(1000).Wait();
}
Console.WriteLine("Фоновый поток: завершено.");
}
Варианты использования в реальных приложениях
1. Уведомления по email:
Отправка уведомлений по email может занимать много времени и вызывать задержки в сети. Вы не хотите, чтобы основной поток приложения ждал завершения доставки email.
2. Обработка изображений и файлов:
Такие задачи, как изменение размера изображения, загрузка файлов или перекодирование видео, могут требовать больших ресурсов и времени.
3. Очистка и обслуживание базы данных:
В приложениях с БД рутинные задачи обслуживания, такие как архивирование, очистка старых данных или переиндексация, могут быть критически важными, но отнимать много времени. Такие задачи можно реализовать в фоновом процессе и запланировать на время минимальной нагрузки основного приложения.
4. Обслуживание кэша:
Со временем в кэшах могут накапливаться устаревшие данные, что приводит к неэффективности и увеличению использования памяти.
Завтра рассмотрим пример, как реализовать фоновую задачу очистки кэша.
Окончание следует…
Источник: https://stefandjokic.tech/posts/background-tasks-how-to-use-them
👍23
День 1735. #ЗаметкиНаПолях
Фоновые Задачи и Как Их Использовать. Окончание
Начало
Очистка кэша с помощью фоновой задачи
Вы можете создать фоновую задачу, которая запускается через регулярные промежутки времени, например раз в час или раз в день, чтобы проверять срок действия кэшированных элементов. Каждый кэшированный элемент может иметь метку времени или значение времени жизни (TTL), связанное с ним, чтобы указать, когда его следует считать устаревшим.
Вот как будет выглядеть упрощённое управление кэшем в приложении:
В этом примере CacheManager управляет кэшем и имеет фоновую задачу (StartCleanup), которая периодически удаляет устаревшие элементы в зависимости от их меток TTL. Это гарантирует, что кэш будет оставаться актуальным и не будет расти бесконечно:
Вывод:
Итого
Фоновые задачи – полезный инструмент для приложений .NET.
- Фоновые задачи предотвращают блокировку основного потока приложения длительными операциями, сохраняя отзывчивость UI и предотвращая зависание приложения.
- Выполняя ресурсоемкие задачи в фоновом режиме, приложения могут более эффективно использовать системные ресурсы, что приводит к повышению производительности и масштабируемости.
- Фоновые задачи обеспечивают параллельное выполнение задач, позволяя приложениям одновременно обрабатывать несколько операций, что важно для обработки больших рабочих нагрузок.
- Они идеально подходят для автоматизации рутинных задач, таких как очистка кэша, синхронизация данных и обслуживание баз данных, сокращая количество ручного вмешательства и обеспечивая точность данных.
- Фоновые задачи помогают эффективно управлять ресурсоёмкими операциями, такими как обработка изображений или доставка электронной почты, предотвращая истощение ресурсов.
- Они способствуют масштабируемости приложения, позволяя ему справляться с возросшей нагрузкой и требованиями без значительного снижения производительности.
Источник: https://stefandjokic.tech/posts/background-tasks-how-to-use-them
Фоновые Задачи и Как Их Использовать. Окончание
Начало
Очистка кэша с помощью фоновой задачи
Вы можете создать фоновую задачу, которая запускается через регулярные промежутки времени, например раз в час или раз в день, чтобы проверять срок действия кэшированных элементов. Каждый кэшированный элемент может иметь метку времени или значение времени жизни (TTL), связанное с ним, чтобы указать, когда его следует считать устаревшим.
Вот как будет выглядеть упрощённое управление кэшем в приложении:
var cache = new CacheManager();
// Добавляем элементы в кэш
cache.AddItem("item1", "value1",
TimeSpan.FromSeconds(30));
cache.AddItem("item2", "value2",
TimeSpan.FromMinutes(1));
// Начинаем очистку кэша
_ = Task.Run(() => cache.StartCleanup(
TimeSpan.FromSeconds(15)));
// Продолжаем работу приложения
Console.WriteLine("Приложение работает...");
Console.ReadLine();
В этом примере CacheManager управляет кэшем и имеет фоновую задачу (StartCleanup), которая периодически удаляет устаревшие элементы в зависимости от их меток TTL. Это гарантирует, что кэш будет оставаться актуальным и не будет расти бесконечно:
class CacheManager
{
private Dictionary<string, CacheItem>
cache = new();
public void AddItem(
string key,
object value,
TimeSpan expiration)
{
var item = new CacheItem(
value,
DateTime.Now.Add(expiration));
cache[key] = item;
}
public async Task StartCleanup(
TimeSpan interval)
{
while (true)
{
await Task.Delay(interval);
var now = DateTime.Now;
var toRemove = new List<string>();
foreach (var kvp in cache)
{
if (kvp.Value.Expiration < now)
toRemove.Add(kvp.Key);
}
foreach (var key in toRemove)
{
Console.WriteLine($"{key} удалён");
cache.Remove(key);
}
}
}
}
class CacheItem
{
public object Value { get; }
public DateTime Expiration { get; }
public CacheItem(object value,
DateTime expiration)
{
Value = value;
Expiration = expiration;
}
}
Вывод:
Приложение работает…Фоновые задачи по очистке кэша помогают поддерживать производительность приложений, обеспечивая эффективность кэша и избегая использования устаревших данных.
// через 30 секунд
item1 удалён
// через 1 минуту
item2 удалён
Итого
Фоновые задачи – полезный инструмент для приложений .NET.
- Фоновые задачи предотвращают блокировку основного потока приложения длительными операциями, сохраняя отзывчивость UI и предотвращая зависание приложения.
- Выполняя ресурсоемкие задачи в фоновом режиме, приложения могут более эффективно использовать системные ресурсы, что приводит к повышению производительности и масштабируемости.
- Фоновые задачи обеспечивают параллельное выполнение задач, позволяя приложениям одновременно обрабатывать несколько операций, что важно для обработки больших рабочих нагрузок.
- Они идеально подходят для автоматизации рутинных задач, таких как очистка кэша, синхронизация данных и обслуживание баз данных, сокращая количество ручного вмешательства и обеспечивая точность данных.
- Фоновые задачи помогают эффективно управлять ресурсоёмкими операциями, такими как обработка изображений или доставка электронной почты, предотвращая истощение ресурсов.
- Они способствуют масштабируемости приложения, позволяя ему справляться с возросшей нагрузкой и требованиями без значительного снижения производительности.
Источник: https://stefandjokic.tech/posts/background-tasks-how-to-use-them
👍7
День 1736. #ЧтоНовенького #Курсы
Microsoft Applied Skills
Applied Skills — новая, заверенная Microsoft, грамота, подтверждающая наличие у вас целевых навыков, необходимых для реализации важных проектов, соответствующих целям и задачам бизнеса. Программа Applied Skills даёт вам возможность продемонстрировать, на что вы способны и что вы можете привнести в ключевые проекты организации.
«Организации ищут таланты, которые смогут возглавить их проекты в области облачных вычислений», — отмечает Ким Акерс, корпоративный вице-президент по поддержке и эксплуатации решений для клиентов и партнёров Microsoft. - «Microsoft Applied Skills предлагает упрощённый способ проверки навыков кандидата. Когда вы видите навыки, заверенные Microsoft, вы знаете, что можете доверить этому человеку выполнение поставленной задачи».
На данный момент бесплатно в течение ограниченного времени предлагаются следующие грамоты (пока процесс только на английском языке):
- Secure storage for Azure Files and Azure Blob Storage
- Configure secure access to your workloads using Azure networking
- Deploy and configure Azure Monitor
- Deploy containers by using Azure Kubernetes Service
- Develop an ASP.NET Core web app that consumes an API
- Secure Azure services and workloads with Microsoft Defender for Cloud regulatory compliance controls
- Configure SIEM security operations using Microsoft Sentinel
- Create and manage automated processes by using Power Automate
Как получить грамоту Microsoft Applied Skills
1. Подготовьтесь самостоятельно, например, используя бесплатные курсы на Microsoft Learn.
2. Получите грамоту, пройдя онлайн интерактивную лабораторную работу, которая проведёт вас через ряд задач на основе сценариев в таких продуктах, как Microsoft Azure или Microsoft Power Platform. Лабораторную оценку можно получить непосредственно на Microsoft Learn.
3. Поделитесь своими новыми навыками. Вы получите грамоту, заверенную Microsoft, которую можно опубликовать в своём профиле.
Сертификат, грамота или то и другое?
Более 30 лет сертификаты служат доказательством технического мастерства мирового класса. В сегодняшней постоянно меняющейся бизнес-среде бывают случаи, когда необходимы подтверждённые навыки работы с конкретным проектом, предлагаемые грамотами Applied Skills. Вот ключевые отличия:
1. Цель
- Сертификат: проверяет общие технические знания
- Грамота: проверяет один конкретный навык
2. Контекст
- Сертификат: для определённой роли в компании
- Грамота: для определённого проекта
3. Охват
- Сертификат: широта навыков
- Грамота: специализированные для конкретного сценария навыки
4. Формат оценки
- Сертификат: экзамен с интерактивными элементами
- Грамота: лабораторная работа
5. Гибкость сдачи
- Сертификат: назначенное время
- Грамота: любое желаемое время
Источник: https://techcommunity.microsoft.com/t5/microsoft-learn-blog/announcing-microsoft-applied-skills-the-new-credentials-to/ba-p/3775645
Microsoft Applied Skills
Applied Skills — новая, заверенная Microsoft, грамота, подтверждающая наличие у вас целевых навыков, необходимых для реализации важных проектов, соответствующих целям и задачам бизнеса. Программа Applied Skills даёт вам возможность продемонстрировать, на что вы способны и что вы можете привнести в ключевые проекты организации.
«Организации ищут таланты, которые смогут возглавить их проекты в области облачных вычислений», — отмечает Ким Акерс, корпоративный вице-президент по поддержке и эксплуатации решений для клиентов и партнёров Microsoft. - «Microsoft Applied Skills предлагает упрощённый способ проверки навыков кандидата. Когда вы видите навыки, заверенные Microsoft, вы знаете, что можете доверить этому человеку выполнение поставленной задачи».
На данный момент бесплатно в течение ограниченного времени предлагаются следующие грамоты (пока процесс только на английском языке):
- Secure storage for Azure Files and Azure Blob Storage
- Configure secure access to your workloads using Azure networking
- Deploy and configure Azure Monitor
- Deploy containers by using Azure Kubernetes Service
- Develop an ASP.NET Core web app that consumes an API
- Secure Azure services and workloads with Microsoft Defender for Cloud regulatory compliance controls
- Configure SIEM security operations using Microsoft Sentinel
- Create and manage automated processes by using Power Automate
Как получить грамоту Microsoft Applied Skills
1. Подготовьтесь самостоятельно, например, используя бесплатные курсы на Microsoft Learn.
2. Получите грамоту, пройдя онлайн интерактивную лабораторную работу, которая проведёт вас через ряд задач на основе сценариев в таких продуктах, как Microsoft Azure или Microsoft Power Platform. Лабораторную оценку можно получить непосредственно на Microsoft Learn.
3. Поделитесь своими новыми навыками. Вы получите грамоту, заверенную Microsoft, которую можно опубликовать в своём профиле.
Сертификат, грамота или то и другое?
Более 30 лет сертификаты служат доказательством технического мастерства мирового класса. В сегодняшней постоянно меняющейся бизнес-среде бывают случаи, когда необходимы подтверждённые навыки работы с конкретным проектом, предлагаемые грамотами Applied Skills. Вот ключевые отличия:
1. Цель
- Сертификат: проверяет общие технические знания
- Грамота: проверяет один конкретный навык
2. Контекст
- Сертификат: для определённой роли в компании
- Грамота: для определённого проекта
3. Охват
- Сертификат: широта навыков
- Грамота: специализированные для конкретного сценария навыки
4. Формат оценки
- Сертификат: экзамен с интерактивными элементами
- Грамота: лабораторная работа
5. Гибкость сдачи
- Сертификат: назначенное время
- Грамота: любое желаемое время
Источник: https://techcommunity.microsoft.com/t5/microsoft-learn-blog/announcing-microsoft-applied-skills-the-new-credentials-to/ba-p/3775645
👍7👎1
День 1737. #ЗаметкиНаПолях #Git
Организация Нескольких Идентичностей в Git
Короткий совет, как управлять несколькими идентичностями в Git. Например, личными проектами, рабочими, и раздельно для каждого клиента.
Я организую свои репозитории Git в три уровня. Мои личные проекты находятся в каталоге
Уровень 2 — это клиент, например,
Уровень 3 — это репозиторий проекта, например,
Вот как организован рабочий каталог:
Теперь предположим, что client2 требует, чтобы мы делали коммиты с идентичностью, отличной от нашей рабочей электронной почты по умолчанию. Кроме того, у вас, вероятно, также есть личный адрес электронной почты для ваших проектов.
Одна из замечательных особенностей файла .gitconfig заключается в том, что вы можете условно включать в него другие файлы конфигурации, и в этом вся суть:
По умолчанию мое имя и адрес электронной почты всегда соответствуют моей личной информации. Я также храню здесь некоторые другие глобальные настройки, но они нам сейчас не важны. Если репозиторий расположен внутри каталога
Надеюсь, идея понятна. Для каждой идентичности вы сохраняете отдельный файл gitconfig и включаете его в основной файл
Этот трюк немного упростил адаптацию моего проекта. Больше никаких запросов от клиентов «Вы забыли обновить свой email»!
Источник: https://garrit.xyz/posts/2023-10-13-organizing-multiple-git-identities
Автор оригинала: Garrit Franke
Организация Нескольких Идентичностей в Git
Короткий совет, как управлять несколькими идентичностями в Git. Например, личными проектами, рабочими, и раздельно для каждого клиента.
Я организую свои репозитории Git в три уровня. Мои личные проекты находятся в каталоге
~/sources
. Все рабочие проекты находятся в ~/work
. Это первый уровень.Уровень 2 — это клиент, например,
~/work/client1
. Уровень 3 — это репозиторий проекта, например,
~/work/client1/foo-api
.Вот как организован рабочий каталог:
/Users/garrit/work
├── client1
│ ├── foo-api
│ ├── foo-ios
│ └── foo-android
└── client2
├── bar-ios
└── bar-middleware
Теперь предположим, что client2 требует, чтобы мы делали коммиты с идентичностью, отличной от нашей рабочей электронной почты по умолчанию. Кроме того, у вас, вероятно, также есть личный адрес электронной почты для ваших проектов.
.gitconfig
– это глобальный файл конфигурации Git, расположенный в корневом каталоге. Если вы когда-либо задавали такой параметр, как git config user.name «Foo Bar»: именно здесь он и сохранялся.Одна из замечательных особенностей файла .gitconfig заключается в том, что вы можете условно включать в него другие файлы конфигурации, и в этом вся суть:
[user]
name = Garrit Franke
email = [email protected]
[includeIf "gitdir:~/work/"]
path = ~/.gitconfig-work
[includeIf "gitdir:~/work/client2/"]
path = ~/.gitconfig-client2
[includeIf "gitdir:~/sources/"]
path = ~/.gitconfig-personal
# ...
По умолчанию мое имя и адрес электронной почты всегда соответствуют моей личной информации. Я также храню здесь некоторые другие глобальные настройки, но они нам сейчас не важны. Если репозиторий расположен внутри каталога
~/work
, в него включается файл с именем ~/.gitconfig-work
. Это просто ещё один файл gitconfig. Вот как он выглядит в моём случае:[user]
name = Garrit Franke
signingkey = 12345678
email = [email protected]
[commit]
gpgsign = true
Надеюсь, идея понятна. Для каждой идентичности вы сохраняете отдельный файл gitconfig и включаете его в основной файл
~/.gitconfig
. Важно отметить, что для этого вам необходимо организовать ваши репозитории, сгруппировав их по клиентам.Этот трюк немного упростил адаптацию моего проекта. Больше никаких запросов от клиентов «Вы забыли обновить свой email»!
Источник: https://garrit.xyz/posts/2023-10-13-organizing-multiple-git-identities
Автор оригинала: Garrit Franke
👍27