День 1131. #Карьера
Как Быть Продуктивным, Когда Вокруг Столько Отвлекающих Факторов
Мы определённо живем в эпоху постоянного отвлечения внимания. А сейчас ситуация совсем вышла из-под контроля. Неудивительно, что многие из нас чувствуют себя хронически истощёнными. Нужно обрабатывать так много информации и так много вещей, к которым нужно приспособиться. И вдобавок ко всему, большая неопределённость в экономике, здравоохранении и рост стоимости жизни.
Не будем говорить о вещах, которые мы не можем контролировать. Сосредоточимся на единственном, что находится под вашим контролем: вы. Рассмотрим, как адаптировать вашу стратегию продуктивности и как вы можете использовать эти идеи, чтобы улучшить себя.
1. Больше акцента на чётко определённых целях
Мир полон неопределённости и сложности, что может вызывать тревогу. Если вы не знаете, что делать или с чего начать, это зачастую вводит в ступор.
Есть два способа справиться с этим. Отречься от всего и жить как монах. Или поставить чётко определённые цели и усердно работать над ними. Чем более неопределённым и сложным становится мир, тем чётче нужно определять цели. Ваши цели упростят мир и уменьшат неопределённость. Когда нет целей, ты становишься дрейфующим кораблём в море. Ты во власти океана.
В современном мире нужно больше внимания уделять целям. Нужно чётко понимать, к чему стремиться. Нужно работать над целями, не ожидая никакого результата. Это будет продвигать вас вперед, как никакая другая сила, с которой вы когда-либо сталкивались.
2. Постоянство результатов
Когда вы ставите цели, возникает соблазн подумать о ваших желаниях: зарабатывать больше, быть в лучшей форме или путешествовать по красивым местам. Когда мы изо всех сил преследуем одно, мы часто жертвуем другим. Когда мы гонимся за деньгами, это часто происходит за счёт отношений или психического здоровья.
Поскольку жизнь становится всё более конкурентной, возникает соблазн стремиться реализовывать желания. Но погоня за импульсами не приведёт вас к достижению целей. Вместо того, чтобы желать результатов, сосредоточьтесь на постоянстве.
Лучше тренироваться четыре раза в неделю и каждый день ходить на прогулку, чем ежедневно поднимать тяжести, бегать несколько раз в неделю и сгореть через пару недель. Когда вы вынуждены сдаться, потому что больше не можете что-то терпеть ни морально, ни физически, значит, вы не оптимизировали постоянство.
Когда вы сосредотачиваетесь на том, чтобы быть стабильно продуктивным, вы ищете уровень производительности, который подходит именно вам. Это зависит от вашей естественной терпимости к работе и вашего опыта.
3. Меньше потребления контента
Происходит столько всего, что вы просто не можете удержаться от пролистывания ленты новостей. Однако это негативно сказывается на вашем мышлении и продуктивности. Постарайтесь не особо интересоваться новостями. Если произойдёт что-то важное, вы узнаете об этом от семьи или друзей. Это действительно экономит час или два в день. Вместо потребления контента займитесь чем-нибудь активным. Банально говорить что-то вроде: «Проводите больше времени на природе». Но все знают, что это хорошо.
4. Пусть всё, что вы делаете, будет приятным
Не обязательно менять карьеру, чтобы получать больше удовольствия от работы. Можно сделать карьеру и работу более приятной, изменив то, как вы работаете. Вы должны любить то, что делаете. Нужно время, чтобы понять, что вы любите. Не ждите, что сразу же найдёте ответ.
Постановка новых целей — отличный способ для начала. Всё дело в достижении прогресса и выяснении того, какие аспекты этого прогресса вам нравятся. Вы поймёте это, когда начнёте двигаться к цели. Нужно только начать.
Источник: https://dariusforoux.com/productivity-distraction-age/
Как Быть Продуктивным, Когда Вокруг Столько Отвлекающих Факторов
Мы определённо живем в эпоху постоянного отвлечения внимания. А сейчас ситуация совсем вышла из-под контроля. Неудивительно, что многие из нас чувствуют себя хронически истощёнными. Нужно обрабатывать так много информации и так много вещей, к которым нужно приспособиться. И вдобавок ко всему, большая неопределённость в экономике, здравоохранении и рост стоимости жизни.
Не будем говорить о вещах, которые мы не можем контролировать. Сосредоточимся на единственном, что находится под вашим контролем: вы. Рассмотрим, как адаптировать вашу стратегию продуктивности и как вы можете использовать эти идеи, чтобы улучшить себя.
1. Больше акцента на чётко определённых целях
Мир полон неопределённости и сложности, что может вызывать тревогу. Если вы не знаете, что делать или с чего начать, это зачастую вводит в ступор.
Есть два способа справиться с этим. Отречься от всего и жить как монах. Или поставить чётко определённые цели и усердно работать над ними. Чем более неопределённым и сложным становится мир, тем чётче нужно определять цели. Ваши цели упростят мир и уменьшат неопределённость. Когда нет целей, ты становишься дрейфующим кораблём в море. Ты во власти океана.
В современном мире нужно больше внимания уделять целям. Нужно чётко понимать, к чему стремиться. Нужно работать над целями, не ожидая никакого результата. Это будет продвигать вас вперед, как никакая другая сила, с которой вы когда-либо сталкивались.
2. Постоянство результатов
Когда вы ставите цели, возникает соблазн подумать о ваших желаниях: зарабатывать больше, быть в лучшей форме или путешествовать по красивым местам. Когда мы изо всех сил преследуем одно, мы часто жертвуем другим. Когда мы гонимся за деньгами, это часто происходит за счёт отношений или психического здоровья.
Поскольку жизнь становится всё более конкурентной, возникает соблазн стремиться реализовывать желания. Но погоня за импульсами не приведёт вас к достижению целей. Вместо того, чтобы желать результатов, сосредоточьтесь на постоянстве.
Лучше тренироваться четыре раза в неделю и каждый день ходить на прогулку, чем ежедневно поднимать тяжести, бегать несколько раз в неделю и сгореть через пару недель. Когда вы вынуждены сдаться, потому что больше не можете что-то терпеть ни морально, ни физически, значит, вы не оптимизировали постоянство.
Когда вы сосредотачиваетесь на том, чтобы быть стабильно продуктивным, вы ищете уровень производительности, который подходит именно вам. Это зависит от вашей естественной терпимости к работе и вашего опыта.
3. Меньше потребления контента
Происходит столько всего, что вы просто не можете удержаться от пролистывания ленты новостей. Однако это негативно сказывается на вашем мышлении и продуктивности. Постарайтесь не особо интересоваться новостями. Если произойдёт что-то важное, вы узнаете об этом от семьи или друзей. Это действительно экономит час или два в день. Вместо потребления контента займитесь чем-нибудь активным. Банально говорить что-то вроде: «Проводите больше времени на природе». Но все знают, что это хорошо.
4. Пусть всё, что вы делаете, будет приятным
Не обязательно менять карьеру, чтобы получать больше удовольствия от работы. Можно сделать карьеру и работу более приятной, изменив то, как вы работаете. Вы должны любить то, что делаете. Нужно время, чтобы понять, что вы любите. Не ждите, что сразу же найдёте ответ.
Постановка новых целей — отличный способ для начала. Всё дело в достижении прогресса и выяснении того, какие аспекты этого прогресса вам нравятся. Вы поймёте это, когда начнёте двигаться к цели. Нужно только начать.
Источник: https://dariusforoux.com/productivity-distraction-age/
👍15
День 1133. #DDD
Коллекции и Одержимость Примитивными Типами. Начало
Одержимость примитивными типами (Primitive Obsession) — это антипаттерн, который заключается в чрезмерном использовании примитивных типов, особенно для моделирования предметной области.
Этот антипаттерн широко известен как в сообществах DDD, так и в сообществах функционального программирования. В DDD вместо этого есть паттерн объекта-значения, а в функциональном программировании существует культура введения типов-оболочек для любого небольшого понятия из вашей предметной области, прежде всего потому, что эти типы-оболочки очень легко создавать в функциональных языках.
Обычно одержимость примитивными типами проявляется в использовании строк, целых чисел и других простых типов. Распространённые примеры:
- Использование строки для представления адресов электронной почты. Специально созданный объект-значение
- Использование
Конечно, не все концепции в вашей предметной области должны быть представлены как объекты-значения, необходимо провести некоторый анализ, чтобы выяснить, стоит ли создавать новый объект-значение. Но недостаточное использование объектов-значений — гораздо более серьёзная проблема, чем чрезмерное их использование.
Но зачем нам вообще нужны объекты-значения?
Дело в инкапсуляции. Она предназначена для защиты данных от перехода в недопустимое состояние. Гораздо сложнее защитить от этого строку, чем специально созданный класс со всеми необходимыми встроенными проверками.
Действительная строка может быть или не быть действительным адресом электронной почты; концепция строки слишком широка и сама по себе не может учитывать правила валидности электронного адреса.
Другими словами, множество строк больше, чем множество e-mail адресов. Чтобы правильно представить концепцию e-mail адреса, нам нужно создать пользовательский класс, который будет соответствовать множеству действительных e-mail адресов.
Помимо инкапсуляции, есть ещё принцип абстракции. Класс
Окончание следует…
Источник: https://enterprisecraftsmanship.com/posts/collections-primitive-obsession/
Коллекции и Одержимость Примитивными Типами. Начало
Одержимость примитивными типами (Primitive Obsession) — это антипаттерн, который заключается в чрезмерном использовании примитивных типов, особенно для моделирования предметной области.
Этот антипаттерн широко известен как в сообществах DDD, так и в сообществах функционального программирования. В DDD вместо этого есть паттерн объекта-значения, а в функциональном программировании существует культура введения типов-оболочек для любого небольшого понятия из вашей предметной области, прежде всего потому, что эти типы-оболочки очень легко создавать в функциональных языках.
Обычно одержимость примитивными типами проявляется в использовании строк, целых чисел и других простых типов. Распространённые примеры:
- Использование строки для представления адресов электронной почты. Специально созданный объект-значение
Email
был бы здесь намного лучше.- Использование
double
для моделирования концепции денег вместо введения объекта-значения Money
.Конечно, не все концепции в вашей предметной области должны быть представлены как объекты-значения, необходимо провести некоторый анализ, чтобы выяснить, стоит ли создавать новый объект-значение. Но недостаточное использование объектов-значений — гораздо более серьёзная проблема, чем чрезмерное их использование.
Но зачем нам вообще нужны объекты-значения?
Дело в инкапсуляции. Она предназначена для защиты данных от перехода в недопустимое состояние. Гораздо сложнее защитить от этого строку, чем специально созданный класс со всеми необходимыми встроенными проверками.
Действительная строка может быть или не быть действительным адресом электронной почты; концепция строки слишком широка и сама по себе не может учитывать правила валидности электронного адреса.
Другими словами, множество строк больше, чем множество e-mail адресов. Чтобы правильно представить концепцию e-mail адреса, нам нужно создать пользовательский класс, который будет соответствовать множеству действительных e-mail адресов.
Помимо инкапсуляции, есть ещё принцип абстракции. Класс
Email
абстрагирует все бизнес-правила, связанные с e-mail адресами, так что клиентский код может работать с этими объектами, не обращая внимания на детали реализации, связанные с проверкой e-mail.Окончание следует…
Источник: https://enterprisecraftsmanship.com/posts/collections-primitive-obsession/
👍16
День 1134. #DDD
Коллекции и Одержимость Примитивными Типами. Окончание
Начало
Пользовательские классы коллекций
А что насчёт коллекций? Допустим, у нас есть следующий класс:
Рассмотрим примеры выше.
1. Коллекция сущностей
Нам нужно, чтобы свойство
2. Пользовательский класс коллекции
Если коллекция не принадлежит никакой другой сущности, то имеет смысл создать для неё отдельный класс. Например, если вам нужно отслеживать всех пользователей, которые в данный момент находятся в сети, лучше всего представить их в виде пользовательского класса:
Итого
Одержимость примитивными типами — это использование примитивных типов для моделирования предметной области.
Вам может понадобиться или не понадобиться отдельный класс для коллекции. Если коллекция представляет собой набор связанных сущностей, присоединённых к родительской сущности, то эта родительская сущность фактически действует как пользовательский класс. Отдельный класс для самой коллекции не нужен.
Если же коллекция является коллекцией корневого уровня, то для неё нужен пользовательский класс (при условии, что помимо самой коллекции необходимы дополнительные функции).
Источник: https://enterprisecraftsmanship.com/posts/collections-primitive-obsession/
Коллекции и Одержимость Примитивными Типами. Окончание
Начало
Пользовательские классы коллекций
А что насчёт коллекций? Допустим, у нас есть следующий класс:
public class CustomerМожет коллекция должна быть представлена специальным классом, например:
{
public IReadOnlyList<Order> Orders { get; }
}
public class CustomerЭто зависит. Если в коллекции необходимо реализовать дополнительные бизнес-правила или инварианты, может быть хорошей идеей создать пользовательский класс. В противном случае оно того не стоит.
{
public OrderList Orders { get; }
}
Рассмотрим примеры выше.
1. Коллекция сущностей
public IReadOnlyList<Order> Orders { get; }Какие бизнес-правила могут быть реализованы в этой коллекции? Допустим, не может быть повторяющихся заказов. Требует ли это введения нового класса? Нет. Чтобы соблюсти это бизнес-правило, все новые заказы должны проходить валидацию. Но нам не нужен для этого отдельный класс, эту ответственность может взять на себя сам класс
Customer
.Нам нужно, чтобы свойство
Orders
не могло быть изменено напрямую, а это уже сделано путем представления этого свойства как IReadOnlyList
. Значит нужно изменить класс Customer
, добавив метод с необходимой проверкой:public class CustomerВ некотором роде
{
private List<Order> _orders;
public IReadOnlyList<Order> Orders => _orders;
public void AddOrder(Order order)
{
if (_orders.Contains(order))
throw new Exception();
_orders.Add(order);
}
}
Customer
уже представляет собой пользовательский класс, инкапсулирующий коллекцию Orders
.2. Пользовательский класс коллекции
Если коллекция не принадлежит никакой другой сущности, то имеет смысл создать для неё отдельный класс. Например, если вам нужно отслеживать всех пользователей, которые в данный момент находятся в сети, лучше всего представить их в виде пользовательского класса:
public class OnlineUsersЗдесь подразумевается, что, помимо собственно коллекции, необходимы некоторые дополнительные функции (например, описанный выше метод
{
private List<User> _users;
public void ForceLogOff(long userId)
{
// …
}
}
ForceLogOff
), в противном случае класс OnlineUsers
не нужен.Итого
Одержимость примитивными типами — это использование примитивных типов для моделирования предметной области.
Вам может понадобиться или не понадобиться отдельный класс для коллекции. Если коллекция представляет собой набор связанных сущностей, присоединённых к родительской сущности, то эта родительская сущность фактически действует как пользовательский класс. Отдельный класс для самой коллекции не нужен.
Если же коллекция является коллекцией корневого уровня, то для неё нужен пользовательский класс (при условии, что помимо самой коллекции необходимы дополнительные функции).
Источник: https://enterprisecraftsmanship.com/posts/collections-primitive-obsession/
👍14
День 1135. #ЗаметкиНаПолях
Избегаем Проблем с DNS в HttpClient
HttpClient позволяет отправлять HTTP-запросы. Подразумевается, что он создаётся однократно и повторно используется на протяжении всего жизненного цикла приложения. HttpClient имеет пул для повторного использования соединений. Если вы отправите несколько запросов на один и тот же хост, они будут повторно использовать одно и то же соединение. Таким образом, приложение экономит доступные ему сокеты. Кроме того, это повышает производительность приложения, избегая рукопожатий TCP и TLS для каждого запроса к одному и тому же хосту.
Сохранение соединений открытыми - хорошо с точки зрения производительности, но вы должны быть осторожны, чтобы не хранить устаревшие соединения. Если срок жизни DNS истёк, хост может изменить свой IP-адрес. В этом случае открытые соединения должны быть закрыты. HttpClient не делает этого автоматически, поскольку ему ничего не известно о сроке жизни DNS.
Когда происходит изменение DNS?
- При сине-зелёном развёртывании (в Azure, когда вы выполняете развёртывание в промежуточном слоте, а затем переключаете рабочий/промежуточный слоты).
- При изменении настроек в диспетчере трафика Azure.
- В случае отказа основного сервера и перехода на бекап и т.п.
Чтобы исправить эту проблему, вы можете указать время ожидания для автоматического закрытия соединения.
-
-
Эти свойства заставляют
По умолчанию простаивающие соединения закрываются через 1 минуту. Однако активные соединения никогда не закрываются. Вы должны явно установить для
Избегаем Проблем с DNS в HttpClient
HttpClient позволяет отправлять HTTP-запросы. Подразумевается, что он создаётся однократно и повторно используется на протяжении всего жизненного цикла приложения. HttpClient имеет пул для повторного использования соединений. Если вы отправите несколько запросов на один и тот же хост, они будут повторно использовать одно и то же соединение. Таким образом, приложение экономит доступные ему сокеты. Кроме того, это повышает производительность приложения, избегая рукопожатий TCP и TLS для каждого запроса к одному и тому же хосту.
Сохранение соединений открытыми - хорошо с точки зрения производительности, но вы должны быть осторожны, чтобы не хранить устаревшие соединения. Если срок жизни DNS истёк, хост может изменить свой IP-адрес. В этом случае открытые соединения должны быть закрыты. HttpClient не делает этого автоматически, поскольку ему ничего не известно о сроке жизни DNS.
Когда происходит изменение DNS?
- При сине-зелёном развёртывании (в Azure, когда вы выполняете развёртывание в промежуточном слоте, а затем переключаете рабочий/промежуточный слоты).
- При изменении настроек в диспетчере трафика Azure.
- В случае отказа основного сервера и перехода на бекап и т.п.
Чтобы исправить эту проблему, вы можете указать время ожидания для автоматического закрытия соединения.
SocketsHttpHandler
используется для настройки поведения HttpClient
и его пула соединений. Необходимо настроить 2 свойства: -
PooledConnectionIdleTimeout
,-
PooledConnectionLifetime
.Эти свойства заставляют
HttpClient
закрыть соединение через определённое время. Таким образом, следующий запрос к тому же хосту должен будет открыть новое соединение и использовать новый DNS или другие изменения в сети.По умолчанию простаивающие соединения закрываются через 1 минуту. Однако активные соединения никогда не закрываются. Вы должны явно установить для
PooledConnectionLifetime
желаемое значение.using System.Threading;Замечание: Другой способ избежать проблем с изменённым DNS – использовать
using System.Net.Http;
using var handler = new SocketsHttpHandler()
{
// Максимальное время простоя соединения в пуле. Если в течение этого времени нет запросов, соединение разрывается. По умолчанию: 1 минута
PooledConnectionIdleTimeout =
TimeSpan.FromMinutes(1),
// Максимальное время жизни соединения в пуле, независимо от активности. Периодически соединение пересоздаётся для обновления DNS или других сетевых изменений. По умолчанию: никогда.
PooledConnectionLifetime =
TimeSpan.FromMinutes(1)
};
using var client = new HttpClient(handler);
var timer = new PeriodicTimer(
TimeSpan.FromSeconds(10));
while (await timer.WaitForNextTickAsync())
{
_ = await client
.GetStringAsync("https://www.google.com");
}
IHttpClientFactory
:servicesИсточник: https://www.meziantou.net/avoid-dns-issues-with-httpclient-in-dotnet.htm
.AddHttpClient<IMyService, MyService>()
.SetHandlerLifetime(TimeSpan.FromMinutes(1));
👍6
День 1136. #ЗаметкиНаПолях #AsyncTips
Модульное тестирование async-методов
Задача: Имеется async-метод, для которого необходимо провести модульное тестирование.
Решение
Многие современные фреймворки модульного тестирования, включая MSTest, NUnit и xUnit, поддерживают методы модульного тестирования async Task. Пример асинхронного модульного теста в MSTest:
Если ваш фреймворк модульного тестирования не поддерживает модульные тесты с
Имитация (mocking) асинхронных зависимостей на первый взгляд кажется немного неуклюжей. Всегда желательно хотя бы проверить, как ваши методы реагируют на синхронный успех (имитация с
Источник: Стивен Клири “Конкурентность в C#”. 2-е межд. изд. — СПб.: Питер, 2020. Глава 7.
Модульное тестирование async-методов
Задача: Имеется async-метод, для которого необходимо провести модульное тестирование.
Решение
Многие современные фреймворки модульного тестирования, включая MSTest, NUnit и xUnit, поддерживают методы модульного тестирования async Task. Пример асинхронного модульного теста в MSTest:
[TestMethod]Фреймворк модульного тестирования замечает, что метод возвращает
public async Task MethodAsync_False()
{
var sut = …;
var result = await sut.iss.onethodAsync();
Assert.IsFalse(result);
}
Task
, и ожидает завершения задачи перед тем, как сделать отметку о прохождении или отказе теста.Если ваш фреймворк модульного тестирования не поддерживает модульные тесты с
async Task
, то ему придётся помочь с ожиданием тестируемой асинхронной операции. Один из вариантов — использовать GetAwaiter().GetResult()
для синхронного блокирования по задаче. Использование GetAwaiter().GetResult()
вместо Wait()
позволит избежать обёртки в AggregateException
, когда в задаче произойдёт исключение. Имитация (mocking) асинхронных зависимостей на первый взгляд кажется немного неуклюжей. Всегда желательно хотя бы проверить, как ваши методы реагируют на синхронный успех (имитация с
Task.FromResult
), синхронные ошибки (имитация с Task.FromException
) и асинхронный успех (имитация с Task.Yield
и возвратом значения). Task.FromResult
и Task.FromException
рассматривались здесь. Task.Yield
может использоваться для принудительного применения асинхронного поведения и задействуется прежде всего при модульном тестировании:interface IMyInterfaceПри тестировании асинхронного кода взаимоблокировки и состояния гонки могут проявляться чаще, чем при тестировании синхронного кода. Может быть полезным назначение тайм-аута тестам. Тестовому методу можно задать атрибут
{
Task<int> SomeAsync();
}
class SyncSuccess : IMyInterface
{
public Task<int> SomeAsync()
{
return Task.FromResult(42);
}
}
class SyncError : IMyInterface
{
public Task<int> SomeAsync()
{
return Task.FromException<int>(
new InvalidOperationException());
}
}
class AsyncSuccess : IMyInterface
{
public async Task<int> SomeAsync()
{
// Принудительно включаем асинхронное поведение
await Task.Yield();
return 42;
}
}
Timeout(int timeOut)
, передав ему количество миллисекунд таймаута. Значение по умолчанию - TestTimeout.Infinite
("бесконечно").Источник: Стивен Клири “Конкурентность в C#”. 2-е межд. изд. — СПб.: Питер, 2020. Глава 7.
👍8
День 1137.
Развёртывайте Чаще
Если вы ещё не практикуете непрерывное развёртывание, скорее всего, ваша команда и компания выиграют от более частых развёртываний.
Развёртывание (deploy) ПО — это процесс переноса его из среды разработки в производственную (или другую) среду. Развёртывание не то же самое, что выпуск (release). В идеале вы должны иметь возможность часто развёртывать ПО, выпуская новые функции для клиентов только тогда, когда это целесообразно с точки зрения бизнеса.
Считаете ли вы развёртывание стрессовым, болезненным и требующим от членов команды внеурочной работы? Что, если бы вы могли избавиться от этого, развёртывая ПО в любое время, но выпуская его только тогда, когда это удобно для вашей команды и/или пользователей?
Ключевым средством разделения развёртывания и выпуска являются флаги (переключатели) функций. Вы можете развернуть код, который ещё не готов, и «скрыть» его за флагом. Как только функция будет готова, и бизнес определит, что пришло время выпустить её, флаг можно переключить, и функция станет активной. И даже этот процесс можно запланировать.
Клиенты, с которыми я работал, развёртывали ПО нерегулярно, примерно раз в 6-8 недель по решению руководства. Поскольку их клиенты приходили в офис к 8 утра, команда должна была начать развёртывание в 3 часа ночи. Процесс почти никогда не проходил по плану: хотя первоначальное развёртывание занимало всего 10-15 минут, остальное время уходило на тестирование, исправление ошибок и повторное развёртывание, чтобы система заработала к 8 утра. А иногда приходилось откатываться и планировать развёртывание на другой день.
Если вы развёртываете редко, вы почти наверняка внедряете изменения, которые были завершены несколько недель или месяцев назад. Если что-то пойдёт не так с этим кодом, разработчик, который его написал, вероятно, уже забыл о нём к этому моменту, а то и вовсе уволился. При более частом развёртывании все вносимые изменения остаются свежими в памяти команды, поэтому выявление и устранение любых проблем становится намного проще.
Для моих клиентов сначала мы собрали метрики о периодичности развёртываний и их успешности. Успешным считалось развёртывание, которое не пришлось откатывать или немедленно исправлять ошибки в нём. Оказалось, что развёртывания, которые выполнялись спустя неделю после предыдущего, почти никогда не были успешными. Тогда как те, что выполнялись спустя день, в большинстве случаев не требовали исправлений.
«Если больно, делай это чаще».
Мы решили выполнять развёртывание чаще. Команде предложение не понравилось. Дни развертывания никому не нравились. Это были дни сильного стресса, бессонницы, которые мешали работе и личной жизни людей. А их просили делать это чаще.
Однако, мы выяснили, что развёртывания после длинного перерыва были высоким стрессом и полной неопределенностью, тогда как те, что выполнялись сразу после, проходили гораздо легче. Это понятно, ведь изменений было немного. Так почему бы не продолжать в том же духе?
Команда решила проводить развёртывания по вторникам и четвергам. Они планировали выполнить 50 развёртываний в год вместо 10, как было раньше. Однако им удалось сделать 100 и более 90% из них были успешными. Больше никому не приходилось выполнять стрессовое развёртывание в 3 часа ночи.
Итого
Процесс доставки ПО является важной частью успеха вашей команды (и компании). Существует множество причин, по которым вы должны предоставлять функционал клиентам раньше и чаще. Проблемы, которые непропорционально возрастают с размером развёртывания, можно контролировать. Стоимость тестирования и исправления ошибок растёт со временем не линейно, а экспоненциально, поэтому, чаще развёртывая, вы сокращаете время, в течение которого могут возникнуть большие проблемы. А с мелкими, которые успевают возникнуть, справиться гораздо легче.
Источник: https://ardalis.com/deploy-more-often/
Автор оригинала: Steve “Ardalis” Smith
Развёртывайте Чаще
Если вы ещё не практикуете непрерывное развёртывание, скорее всего, ваша команда и компания выиграют от более частых развёртываний.
Развёртывание (deploy) ПО — это процесс переноса его из среды разработки в производственную (или другую) среду. Развёртывание не то же самое, что выпуск (release). В идеале вы должны иметь возможность часто развёртывать ПО, выпуская новые функции для клиентов только тогда, когда это целесообразно с точки зрения бизнеса.
Считаете ли вы развёртывание стрессовым, болезненным и требующим от членов команды внеурочной работы? Что, если бы вы могли избавиться от этого, развёртывая ПО в любое время, но выпуская его только тогда, когда это удобно для вашей команды и/или пользователей?
Ключевым средством разделения развёртывания и выпуска являются флаги (переключатели) функций. Вы можете развернуть код, который ещё не готов, и «скрыть» его за флагом. Как только функция будет готова, и бизнес определит, что пришло время выпустить её, флаг можно переключить, и функция станет активной. И даже этот процесс можно запланировать.
Клиенты, с которыми я работал, развёртывали ПО нерегулярно, примерно раз в 6-8 недель по решению руководства. Поскольку их клиенты приходили в офис к 8 утра, команда должна была начать развёртывание в 3 часа ночи. Процесс почти никогда не проходил по плану: хотя первоначальное развёртывание занимало всего 10-15 минут, остальное время уходило на тестирование, исправление ошибок и повторное развёртывание, чтобы система заработала к 8 утра. А иногда приходилось откатываться и планировать развёртывание на другой день.
Если вы развёртываете редко, вы почти наверняка внедряете изменения, которые были завершены несколько недель или месяцев назад. Если что-то пойдёт не так с этим кодом, разработчик, который его написал, вероятно, уже забыл о нём к этому моменту, а то и вовсе уволился. При более частом развёртывании все вносимые изменения остаются свежими в памяти команды, поэтому выявление и устранение любых проблем становится намного проще.
Для моих клиентов сначала мы собрали метрики о периодичности развёртываний и их успешности. Успешным считалось развёртывание, которое не пришлось откатывать или немедленно исправлять ошибки в нём. Оказалось, что развёртывания, которые выполнялись спустя неделю после предыдущего, почти никогда не были успешными. Тогда как те, что выполнялись спустя день, в большинстве случаев не требовали исправлений.
«Если больно, делай это чаще».
Мы решили выполнять развёртывание чаще. Команде предложение не понравилось. Дни развертывания никому не нравились. Это были дни сильного стресса, бессонницы, которые мешали работе и личной жизни людей. А их просили делать это чаще.
Однако, мы выяснили, что развёртывания после длинного перерыва были высоким стрессом и полной неопределенностью, тогда как те, что выполнялись сразу после, проходили гораздо легче. Это понятно, ведь изменений было немного. Так почему бы не продолжать в том же духе?
Команда решила проводить развёртывания по вторникам и четвергам. Они планировали выполнить 50 развёртываний в год вместо 10, как было раньше. Однако им удалось сделать 100 и более 90% из них были успешными. Больше никому не приходилось выполнять стрессовое развёртывание в 3 часа ночи.
Итого
Процесс доставки ПО является важной частью успеха вашей команды (и компании). Существует множество причин, по которым вы должны предоставлять функционал клиентам раньше и чаще. Проблемы, которые непропорционально возрастают с размером развёртывания, можно контролировать. Стоимость тестирования и исправления ошибок растёт со временем не линейно, а экспоненциально, поэтому, чаще развёртывая, вы сокращаете время, в течение которого могут возникнуть большие проблемы. А с мелкими, которые успевают возникнуть, справиться гораздо легче.
Источник: https://ardalis.com/deploy-more-often/
Автор оригинала: Steve “Ardalis” Smith
👍9
День 1139. #ЗаметкиНаПолях
Выполнение Кода Перед Main
Вообще, я не любитель подобных извращений. Но чисто ради лулзов иногда интересно узнать, что так можно.
Согласно документации, «Метод Main — это точка входа в приложение C#. При запуске приложения метод Main вызывается первым.» На самом деле метод
1. Статический конструктор
Статический конструктор используется для инициализации любых статических данных или для выполнения определённого действия, которое необходимо выполнить только один раз. Он вызывается автоматически перед созданием первого экземпляра или обращением к любым статическим элементам. Поэтому статический конструктор вызовется перед методом Main.
Инициализаторы модулей позволяют библиотекам выполнять однократную инициализацию при загрузке без необходимости явного вызова пользователем чего-либо. Когда среда выполнения загружает модуль (DLL), она вызывает методы инициализации модуля перед выполнением любого кода из этого модуля.
Переменная среды
Выполнение Кода Перед Main
Вообще, я не любитель подобных извращений. Но чисто ради лулзов иногда интересно узнать, что так можно.
Согласно документации, «Метод Main — это точка входа в приложение C#. При запуске приложения метод Main вызывается первым.» На самом деле метод
Main
может быть не первым методом сборки, который будет выполняться при запуске приложения. Существуют различные методы, которые могут выполняться перед методом Main
.1. Статический конструктор
Статический конструктор используется для инициализации любых статических данных или для выполнения определённого действия, которое необходимо выполнить только один раз. Он вызывается автоматически перед созданием первого экземпляра или обращением к любым статическим элементам. Поэтому статический конструктор вызовется перед методом Main.
class Program2. Инициализаторы модулей
{
static Program() =>
Console.WriteLine("Program.cctor");
static void Main() =>
Console.WriteLine("Hello, World!");
}
Инициализаторы модулей позволяют библиотекам выполнять однократную инициализацию при загрузке без необходимости явного вызова пользователем чего-либо. Когда среда выполнения загружает модуль (DLL), она вызывает методы инициализации модуля перед выполнением любого кода из этого модуля.
using System.Runtime.CompilerServices;3. Стартап хуки
class Initializer
{
// Статический конструктор выполняется
// перед инициализаторами модуля
static Initializer()
=> Console.WriteLine("Init.cctor");
[ModuleInitializer]
public static void Initialize1() =>
Console.WriteLine("Module Init 1");
[ModuleInitializer]
public static void Initialize2() =>
Console.WriteLine("Module Init 2");
}
Переменная среды
DOTNET_STARTUP_HOOKS
может использоваться для указания списка управляемых сборок, содержащих тип StartupHook
с публичным статическим методом Initialize()
:class StartupHookКаждый из этих методов будет вызываться в указанном порядке перед точкой входа
{
static StartupHook() =>
Console.WriteLine("StartupHook.cctor");
// Запустите приложение с переменной среды
// DOTNET_STARTUP_HOOKS=<полный путь к сборке с этим классом>
public static void Initialize() =>
Console.WriteLine("Startup hook");
}
Main
:Init.cctorИсточник: https://www.meziantou.net/executing-code-before-main-in-dotnet.htm
Module Init 1
Module Init 2
StartupHook.cctor
Startup hook
program.cctor
Hello, World!
👍9
День 1140. #CodeReview
Про обзоры кода на канале было уже много постов. Найти их можно по тегу в заголовке. А сегодня, пока ютуб окончательно не заблокировали, порекомендую вам очередное видео от Дейва Пламера «The Secret Society of Code Reviewers at Microsoft»
В видео он рассказывает о том, зачем нужны обзоры кода, как они проходили в Майкрософт на заре систем контроля версий, 5 советов, как проводить обзоры кода, и 5 советов, чего не надо делать при обзорах кода.
PS: из-за скорости речи и некоторого акцента автора, понять его иногда довольно трудно. Можете поставить скорость 0,75 и включить субтитры.
Про обзоры кода на канале было уже много постов. Найти их можно по тегу в заголовке. А сегодня, пока ютуб окончательно не заблокировали, порекомендую вам очередное видео от Дейва Пламера «The Secret Society of Code Reviewers at Microsoft»
В видео он рассказывает о том, зачем нужны обзоры кода, как они проходили в Майкрософт на заре систем контроля версий, 5 советов, как проводить обзоры кода, и 5 советов, чего не надо делать при обзорах кода.
PS: из-за скорости речи и некоторого акцента автора, понять его иногда довольно трудно. Можете поставить скорость 0,75 и включить субтитры.
👍5
День 1141. #ЗаметкиНаПолях
Совместное Использование Кода Между ASP.NET и ASP.NET Core
Перенос существующего кода в ASP.NET Core часто кажется серьёзным шагом. Однако уже сегодня можно внести небольшие изменения, которые упростят переход на ASP.NET Core завтра.
Первым шагом является создание нового проекта ASP.NET Core Web App (Model-View-Controller). Этот шаблон добавит поддержку контроллеров и сопоставит маршрут по умолчанию для контроллеров в файле
Контроллеры
Многие команды хотят, чтобы новый веб-сайт работал так же, как текущий. Если вы исправляете ошибку в проекте, важно, чтобы это исправление отображалось на обоих сайтах. Один из самых простых способов обеспечить это — предоставить общий доступ к одному и тому же файлу в обоих проектах. К счастью, ASP.NET Core использует новые файлы проектов в стиле SDK. Это означает, что файл csproj легко открыть и внести некоторые изменения. Нужно создать
Модели
Для этого подойдут те же советы, что и при совместном использовании контроллеров. Также директивы препроцессора можно использовать для атрибутов:
Опять же можно использовать csproj для совместного использования файлов, таких как
Пошаговые инструкции по переносу на примере проекта MvcMusicStore приведены здесь. Там также описано, как можно запускать ASP.NET и ASP.NET Core из одного и того же пула приложений IIS для постепенной миграции вашего веб-приложения по одному контроллеру за раз.
Источник: https://devblogs.microsoft.com/dotnet/sharing-code-between-aspnet-and-aspnetcore/
Совместное Использование Кода Между ASP.NET и ASP.NET Core
Перенос существующего кода в ASP.NET Core часто кажется серьёзным шагом. Однако уже сегодня можно внести небольшие изменения, которые упростят переход на ASP.NET Core завтра.
Первым шагом является создание нового проекта ASP.NET Core Web App (Model-View-Controller). Этот шаблон добавит поддержку контроллеров и сопоставит маршрут по умолчанию для контроллеров в файле
Program.cs
. После этого можно удалить созданные по умолчанию контроллер HomeController
и представления Home/Index
и Home/Privacy
.Контроллеры
Многие команды хотят, чтобы новый веб-сайт работал так же, как текущий. Если вы исправляете ошибку в проекте, важно, чтобы это исправление отображалось на обоих сайтах. Один из самых простых способов обеспечить это — предоставить общий доступ к одному и тому же файлу в обоих проектах. К счастью, ASP.NET Core использует новые файлы проектов в стиле SDK. Это означает, что файл csproj легко открыть и внести некоторые изменения. Нужно создать
<ItemGroup>
и добавить ссылку на существующий класс:<ItemGroup>Теперь проект ASP.NET Core больше не компилируется. В ASP.NET Core класс Controller использует не System.Web.Mvc, а Microsoft.AspNetCore.Mvc. Это можно исправить с помощью директив препроцессора:
<Compile
Include="..HomeController.cs"
LinkBase="Controllers" />
</ItemGroup>
#if NETАналогичный код можно добавить и в других нужных местах, чтобы заставить оба проекта компилироваться. Кроме того, можно создать частичные классы и выделить крупные блоки кода в новые методы, различающиеся в разных проектах, а затем, используя csproj, включать в проект только нужные файлы.
using Microsoft.AspNetCore.Mvc;
#else
using System.Web.Mvc;
#endif
Модели
Для этого подойдут те же советы, что и при совместном использовании контроллеров. Также директивы препроцессора можно использовать для атрибутов:
#if !NETПредставления
[Bind(Exclude="Id")]
#endif
public partial class Order
{
[ScaffoldColumn(false)]
#if NET
[BindNever]
#endif
public int Id { get; set; }
…
Опять же можно использовать csproj для совместного использования файлов, таких как
_Layout.cshtml
. Внутри представления вы можете продолжать использовать директивы препроцессора:@{Аналогично можно совместно использовать статический контент (CSS, JavaScript и изображения). Также обновите все NuGet-пакеты и ваши собственные библиотеки под использование netstandard, чтобы они могли совместно использоваться в обоих проектах.
#if NET
<text>
@await
Component.InvokeAsync("CartSummary")
</text>
#else
@Html.RenderAction(
"CartSummary",
"ShoppingCart");
#endif
}
Пошаговые инструкции по переносу на примере проекта MvcMusicStore приведены здесь. Там также описано, как можно запускать ASP.NET и ASP.NET Core из одного и того же пула приложений IIS для постепенной миграции вашего веб-приложения по одному контроллеру за раз.
Источник: https://devblogs.microsoft.com/dotnet/sharing-code-between-aspnet-and-aspnetcore/
👍5
День 1142.
25 Лет Visual Studio
Сегодня исполняется 25 лет с выпуска Visual Studio в 1997 году, и такая важная веха заслуживает надлежащего празднования. Празднование 25-й годовщины Visual Studio начнётся сегодня, 17 марта, в 19:00 по Москве. Обещают эксклюзивный контент и захватывающие новости, знакомые лица из прошлого и настоящего Visual Studio, которые расскажут закулисные истории и забавные факты, накопившиеся за 25 лет истории.
Также Microsoft призывает всех поделиться своей историей использования Visual Studio в социальных сетях, используя хэштег #MyVSStory.
Источник: https://devblogs.microsoft.com/visualstudio/happy-25th-birthday-visual-studio/
25 Лет Visual Studio
Сегодня исполняется 25 лет с выпуска Visual Studio в 1997 году, и такая важная веха заслуживает надлежащего празднования. Празднование 25-й годовщины Visual Studio начнётся сегодня, 17 марта, в 19:00 по Москве. Обещают эксклюзивный контент и захватывающие новости, знакомые лица из прошлого и настоящего Visual Studio, которые расскажут закулисные истории и забавные факты, накопившиеся за 25 лет истории.
Также Microsoft призывает всех поделиться своей историей использования Visual Studio в социальных сетях, используя хэштег #MyVSStory.
Источник: https://devblogs.microsoft.com/visualstudio/happy-25th-birthday-visual-studio/
👍6
День 1143. #юмор
10x-Инженеры
Рекрутеры, менеджеры и основатели стартапов, если вы когда-нибудь столкнётесь с этой редкой породой инженеров, хватайте их. Если у вас есть 10x-инженер в команде, вы значительно увеличиваете шансы на успех вашего проекта. А теперь сложный вопрос. Как распознать 10x-инженера?
1. 10x-инженеры ненавидят собрания. Они считают, что это пустая трата времени и обсуждаются очевидные вещи. Они посещают эти собрания только потому, что менеджер их позвал.
2. Время работы в офисе у 10x-инженеров ненормированное. Они, как правило, работают, только когда вокруг очень мало людей. Когда вокруг толпа или общее собрание, их не видно. Большинство из них кодят допоздна и поздно приходят в офис.
3. Цвет фона экрана 10x-инженера обычно черный (они всегда меняют цвет по умолчанию). Буквы i, j, x на их клавиатуре обычно больше изношены.
4. Большинство 10x-инженеров — фулл-стеки. Для них код есть код, им всё равно, это клиентская часть, серверная часть, API, база данных или бессерверная функция.
5. 10x-инженеры могут преобразовать «мысль» в «код» в уме и написать его итеративно. Имея характеристику продукта, они могут написать весь код по ней за один или два сеанса по 4-6 часов, не отвлекаясь, питаясь напитком с кофеином.
6. 10x-инженеры редко смотрят в документацию. Они знают всё наизусть и всегда могут вспомнить нужный класс или метод. Они пишут код так же легко, как обычный текст. Без перерывов, без пауз, просто печатают. У некоторых 10x-инженеров 11 пальцев для дополнительной производительности при наборе текста.
7. 10x-инженеры всегда изучают новые фреймворки и языки раньше всех в компании. Они не боятся ничего нового. Если появляется что-то новое, они изучают это, настраивают, экспериментируют, прежде чем кто-либо об этом вообще узнает.
8. 10x-инженеры — плохие наставники. Они не могут научить других что-то делать или делегировать работу, т.к всегда думают, что «обучение или обсуждение с другими занимает слишком много времени, я лучше сделаю это сам». Они также плохие интервьюеры.
9. 10x-инженеры не придумывают костыли. Они пишут качественный код и точно знают, как этот код должен развиваться, и имеют ментальную модель общей структуры кода. Они пишут максимум один проектный документ, а остальное очевидно из кода.
10. 10x-инженеры знают, что великие инженеры на самом деле 8x, иногда 16x, а не 10x.
11. 10x-инженеры знают каждую строчку выпущенного кода. Если QA или сотрудники службы поддержки сообщают о проблеме, они точно знают, где находится ошибка, и могут исправить её в кратчайшее время. Лучшие 10x-инженеры смогут сказать вам строку и позицию ошибки в вашем коде, просто слушая шум процессора, когда он выполняет код.
12. 10x-инженеры редко ищут работу или уходят из компании. Они уходят, только потому что вы делаете их жизнь невыносимой из-за правил, собраний, обучения и других действий, не добавляющих ценности. Если вы встретите их, держитесь за них, любите их.
Источник: https://twitter.com/skirani/status/1149302828420067328
10x-Инженеры
Рекрутеры, менеджеры и основатели стартапов, если вы когда-нибудь столкнётесь с этой редкой породой инженеров, хватайте их. Если у вас есть 10x-инженер в команде, вы значительно увеличиваете шансы на успех вашего проекта. А теперь сложный вопрос. Как распознать 10x-инженера?
1. 10x-инженеры ненавидят собрания. Они считают, что это пустая трата времени и обсуждаются очевидные вещи. Они посещают эти собрания только потому, что менеджер их позвал.
2. Время работы в офисе у 10x-инженеров ненормированное. Они, как правило, работают, только когда вокруг очень мало людей. Когда вокруг толпа или общее собрание, их не видно. Большинство из них кодят допоздна и поздно приходят в офис.
3. Цвет фона экрана 10x-инженера обычно черный (они всегда меняют цвет по умолчанию). Буквы i, j, x на их клавиатуре обычно больше изношены.
4. Большинство 10x-инженеров — фулл-стеки. Для них код есть код, им всё равно, это клиентская часть, серверная часть, API, база данных или бессерверная функция.
5. 10x-инженеры могут преобразовать «мысль» в «код» в уме и написать его итеративно. Имея характеристику продукта, они могут написать весь код по ней за один или два сеанса по 4-6 часов, не отвлекаясь, питаясь напитком с кофеином.
6. 10x-инженеры редко смотрят в документацию. Они знают всё наизусть и всегда могут вспомнить нужный класс или метод. Они пишут код так же легко, как обычный текст. Без перерывов, без пауз, просто печатают. У некоторых 10x-инженеров 11 пальцев для дополнительной производительности при наборе текста.
7. 10x-инженеры всегда изучают новые фреймворки и языки раньше всех в компании. Они не боятся ничего нового. Если появляется что-то новое, они изучают это, настраивают, экспериментируют, прежде чем кто-либо об этом вообще узнает.
8. 10x-инженеры — плохие наставники. Они не могут научить других что-то делать или делегировать работу, т.к всегда думают, что «обучение или обсуждение с другими занимает слишком много времени, я лучше сделаю это сам». Они также плохие интервьюеры.
9. 10x-инженеры не придумывают костыли. Они пишут качественный код и точно знают, как этот код должен развиваться, и имеют ментальную модель общей структуры кода. Они пишут максимум один проектный документ, а остальное очевидно из кода.
10. 10x-инженеры знают, что великие инженеры на самом деле 8x, иногда 16x, а не 10x.
11. 10x-инженеры знают каждую строчку выпущенного кода. Если QA или сотрудники службы поддержки сообщают о проблеме, они точно знают, где находится ошибка, и могут исправить её в кратчайшее время. Лучшие 10x-инженеры смогут сказать вам строку и позицию ошибки в вашем коде, просто слушая шум процессора, когда он выполняет код.
12. 10x-инженеры редко ищут работу или уходят из компании. Они уходят, только потому что вы делаете их жизнь невыносимой из-за правил, собраний, обучения и других действий, не добавляющих ценности. Если вы встретите их, держитесь за них, любите их.
Источник: https://twitter.com/skirani/status/1149302828420067328
👍19
День 1144. #ЗаметкиНаПолях #AsyncTips
Неизменяемые стеки и очереди
Задача
Вам нужна коллекция — стек или очередь, которая изменяется не очень часто и к которой можно безопасно обращаться из нескольких потоков. Например, очередь для представления последовательности выполняемых операций, а стек — для представления последовательности операций отмены.
Решение
Неизменяемые стеки и очереди из пространства имён
Неизменяемый стек
Неизменяемая очередь
- Экземпляр неизменяемой коллекции никогда не изменяется.
- Экземпляр неизменяемой коллекции потокобезопасен по своей природе, но ссылка на него потокобезопасной не является. Переменная, ссылающаяся на неизменяемую коллекцию, нуждается в такой же синхронизационной защите, как и любая другая переменная.
- При вызове изменяющего метода для неизменяемой коллекции возвращается новая измененная коллекция.
Неизменяемые коллекции могут использоваться и в однопоточных приложениях, например для функционального кода, а также при необходимости хранить большое количество снимков коллекции, которые должны по возможности совместно использовать одну память.
Неизменяемые коллекции идеально подходят для хранения общего состояния. С другой стороны, в качестве коммуникационного канала они работают не так хорошо. В частности, неизменяемые очереди не следует использовать для передачи данных между потоками; очереди «производитель/потребитель» подходят для этой цели намного лучше.
Источник: Стивен Клири “Конкурентность в C#”. 2-е межд. изд. — СПб.: Питер, 2020. Глава 9.
Неизменяемые стеки и очереди
Задача
Вам нужна коллекция — стек или очередь, которая изменяется не очень часто и к которой можно безопасно обращаться из нескольких потоков. Например, очередь для представления последовательности выполняемых операций, а стек — для представления последовательности операций отмены.
Решение
Неизменяемые стеки и очереди из пространства имён
System.Collections.Immutable
по поведению очень близки к стандартным коллекциям Stack<T>
и Queue<T>
и обладают практически такой же временной сложностью. Впрочем, в простых сценариях с частым обновлением стандартные стеки и очереди работают быстрее.Неизменяемый стек
var stack = ImmutableStack<int>.Empty;В этом примере многократно перезаписывается локальная переменная stack. Неизменяемые коллекции возвращают обновлённую коллекцию, а ссылка на исходную остаётся без изменений. Это означает, что, если имеется ссылка на экземпляр неизменяемой коллекции, она никогда не изменится:
stack = stack.Push(13);
stack = stack.Push(7);
// Выводит "7", затем "13".
foreach (int item in stack)
Console.WriteLine(item);
stack = stack.Pop(out int last);
// last == 7
var stack = ImmutableStack<int>.Empty;Во внутренней реализации два стека совместно используют память, выделенную для хранения элемента 13. Такая реализация весьма эффективна, к тому же она позволяет легко создавать снимки текущего состояния. Каждый экземпляр неизменяемой коллекции потокобезопасен по своей природе.
stack = stack.Push(13);
var biggerStack = stack.Push(7);
// Выводит "7", затем "13".
foreach (int item in biggerStack)
Console.WriteLine(item);
// Выводит только "13".
foreach (int item in stack)
Console.WriteLine(item);
Неизменяемая очередь
var queue = ImmutableQueue<int>.Empty;Вот некоторые важные принципы проектирования, справедливые для всех неизменяемых коллекций:
queue = queue.Enqueue(13);
queue = queue.Enqueue(7);
// Выводит "13", затем "7".
foreach (int item in queue)
Console.WriteLine(item);
queue = queue.Dequeue(out int next);
// Выводит "13".
Console.WriteLine(next);
- Экземпляр неизменяемой коллекции никогда не изменяется.
- Экземпляр неизменяемой коллекции потокобезопасен по своей природе, но ссылка на него потокобезопасной не является. Переменная, ссылающаяся на неизменяемую коллекцию, нуждается в такой же синхронизационной защите, как и любая другая переменная.
- При вызове изменяющего метода для неизменяемой коллекции возвращается новая измененная коллекция.
Неизменяемые коллекции могут использоваться и в однопоточных приложениях, например для функционального кода, а также при необходимости хранить большое количество снимков коллекции, которые должны по возможности совместно использовать одну память.
Неизменяемые коллекции идеально подходят для хранения общего состояния. С другой стороны, в качестве коммуникационного канала они работают не так хорошо. В частности, неизменяемые очереди не следует использовать для передачи данных между потоками; очереди «производитель/потребитель» подходят для этой цели намного лучше.
Источник: Стивен Клири “Конкурентность в C#”. 2-е межд. изд. — СПб.: Питер, 2020. Глава 9.
👍7
День 1145. #ЗаметкиНаПолях
Использование Встроенных Файлов в dotnet core
Мы хотим прочитать файл JSON с диска. Мы не хотим полагаться на абсолютные пути к файлам, параметрам среды, копировать файлы в выходной каталог и т.п. Файл JSON выглядит следующим образом:
Использование Встроенных Файлов в dotnet core
Мы хотим прочитать файл JSON с диска. Мы не хотим полагаться на абсолютные пути к файлам, параметрам среды, копировать файлы в выходной каталог и т.п. Файл JSON выглядит следующим образом:
file.jsonМожно использовать функцию
{
"data": true
}
EmbeddedResource
. Тогда при сборке проекта файл json будет включён в dll. Чтобы пометить файл как EmbeddedResource
, вы просто добавляете его в свой .csproj следующим образом:<ItemGroup>Теперь посмотрим, как можно прочитать этот файл. При работе со встроенными файлами нам понадобится сборка, в которой мы будем искать встроенные ресурсы. Рассмотрим следующий интерфейс, содержащий методы для чтения встроенных ресурсов тремя различными способами
<EmbeddedResource Include="Data\file.json" />
</ItemGroup>
public interface IEmbeddedResourceQueryДля получения потока для чтения ресурса можно использовать метод
{
// изнутри сборки
Stream? Read<T>(string resource);
// из заданной сборки
Stream? Read(Assembly a, string resource);
// из сборки по имени сборки
Stream? Read(string name, string resource);
}
GetManifestResourceStream
сборки. Ещё одна важная деталь — это то, как строится путь для чтения ресурса. Нам нужно указать имя сборки (MyLibrary
), а затем использовать запись пути через точку: Assembly_name.Folder.FilenameНапример, для файла file.json в папке Data путь будет:
MyLibrary.Data.file.jsonИспользование
public class EmbeddedResourceQuery
: IEmbeddedResourceQuery
{
public Stream? Read<T>(string resource)
{
var a = typeof(T).Assembly;
return ReadInternal(a, resource);
}
public Stream? Read(
Assembly a, string resource)
{
return ReadInternal(a, resource);
}
public Stream? Read(
string name, string resource)
{
var a = Assembly.Load(name);
return ReadInternal(a, resource);
}
internal static Stream? ReadInternal(
Assembly a, string resource)
{
return assembly
.GetManifestResourceStream(
$"{a.GetName().Name}.{resource}");
}
}
var q = new EmbeddedResourceQuery();Источник: https://josef.codes/using-embedded-files-in-dotnet-core/
// изнутри сборки
var s1 = q.Read<MyType>("Data.file.json ");
// из заданной сборки
var a = Assembly.Load("MyLibrary");
var s2 = q.Read(a, "Data.file.json ");
// из сборки по имени сборки
var s3 = q.Read("MyLibrary", "Data.file.json");
👍11
День 1146.
Улучшаем Производительность Сборки в Visual Studio. Начало
Время — ваш самый ценный актив, и медленная сборка занимает первое место в списке убийц продуктивности разработчиков. При медленной сборке теряется не только время на саму сборку, но часто и вы сами отвлекаетесь на другие задачи, такие как проверка почты, кофе, социальные сети… Таким образом, борьба за сокращение времени сборки имеет важное значение.
Измерение
Прежде чем улучшать, нужно сначала измерить. Расширение Visual Studio Build Timer отображает статистику и водопадную диаграмму вашей сборки в Visual Studio. Инструмент доступен в меню View > Other Windows > Build Timer (Вид > Другие окна > Таймер сборки) и позволяет увидеть, какие проекты собираются дольше, а какие быстрее, какие проекты ждут сборки других и т.п.
Фильтры решений
Обычно мы обычно работаем только с несколькими проектами из решения. Поэтому можно вручную выгружать ненужные проекты, чтобы добиться более быстрой компиляции. Процесс выгрузки набора проектов можно значительно улучшить, определив файл фильтра решения (.slnf). Чтобы его создать, просто выгрузите несколько проектов, щёлкните правой кнопкой мыши на решении и выберите в меню Save as Solution Filter (Сохранить как фильтр решения).
VS рассматривает файлы фильтров решений (.slnf) как файлы решений (.sln). Файл фильтра представляет собой текстовый файл, который можно легко редактировать. Загрузка фильтра решения загружает целевые проекты и полностью игнорирует другие: они даже не отображаются как выгруженные. Выгрузка/загрузка проектов в открытом фильтре вызывает подсказку, предлагающую обновить фильтр.
Имейте в виду, что у выгрузки проектов есть и обратная сторона: изменения, сделанные в публичных API ваших проектов не будут отражены в выгруженных клиентских проектах.
Инкрементная сборка
В контексте VS MSBuild проверяет актуальность выходных данных проекта, чтобы определить, нужно ли его компилировать. Эта функция называется Incremental Build и необходима для значительного сокращения количества компилирующихся проектов для ускорения сборки.
Основные причины неактуальности проекта:
- Один из файлов, используемых в качестве входных данных проекта (исходный файл, файл ресурсов…), имеет более новую временную метку, чем временная метка выходного файла проекта (.dll, .pdb, .xml…).
- Проект зависит как минимум от одного устаревшего проекта.
Инкрементальные проверки сборки не могут быть идеальными, особенно когда используются некоторые нетривиальные функции. Например, если в одном из файлов проекта для свойства Copy to Output Directory (Копировать в выходной каталог) установлено значение Copy Always (Копировать всегда), проект никогда не будет считаться актуальным. Такая причина не очевидна. Чтобы это обнаружить перейдите в Options > Projects and Solutions > SDK-Style Projects (Параметры > Проекты и решения > Проекты SDK) измените для параметра Logging Level значение с None на Minimal. Теперь в окне Output при сборке можно заметить строку:
Чтобы узнать, есть ли у вашего решения такая проблема: сначала выполните Build > Rebuild Solution, а затем Build > Build Solution. Если какие-то проекты перекомпилируются второй раз, исследуйте проблему.
Окончание следует…
Источник: https://blog.ndepend.com/improve-visual-studio-build-performance/
Улучшаем Производительность Сборки в Visual Studio. Начало
Время — ваш самый ценный актив, и медленная сборка занимает первое место в списке убийц продуктивности разработчиков. При медленной сборке теряется не только время на саму сборку, но часто и вы сами отвлекаетесь на другие задачи, такие как проверка почты, кофе, социальные сети… Таким образом, борьба за сокращение времени сборки имеет важное значение.
Измерение
Прежде чем улучшать, нужно сначала измерить. Расширение Visual Studio Build Timer отображает статистику и водопадную диаграмму вашей сборки в Visual Studio. Инструмент доступен в меню View > Other Windows > Build Timer (Вид > Другие окна > Таймер сборки) и позволяет увидеть, какие проекты собираются дольше, а какие быстрее, какие проекты ждут сборки других и т.п.
Фильтры решений
Обычно мы обычно работаем только с несколькими проектами из решения. Поэтому можно вручную выгружать ненужные проекты, чтобы добиться более быстрой компиляции. Процесс выгрузки набора проектов можно значительно улучшить, определив файл фильтра решения (.slnf). Чтобы его создать, просто выгрузите несколько проектов, щёлкните правой кнопкой мыши на решении и выберите в меню Save as Solution Filter (Сохранить как фильтр решения).
VS рассматривает файлы фильтров решений (.slnf) как файлы решений (.sln). Файл фильтра представляет собой текстовый файл, который можно легко редактировать. Загрузка фильтра решения загружает целевые проекты и полностью игнорирует другие: они даже не отображаются как выгруженные. Выгрузка/загрузка проектов в открытом фильтре вызывает подсказку, предлагающую обновить фильтр.
Имейте в виду, что у выгрузки проектов есть и обратная сторона: изменения, сделанные в публичных API ваших проектов не будут отражены в выгруженных клиентских проектах.
Инкрементная сборка
В контексте VS MSBuild проверяет актуальность выходных данных проекта, чтобы определить, нужно ли его компилировать. Эта функция называется Incremental Build и необходима для значительного сокращения количества компилирующихся проектов для ускорения сборки.
Основные причины неактуальности проекта:
- Один из файлов, используемых в качестве входных данных проекта (исходный файл, файл ресурсов…), имеет более новую временную метку, чем временная метка выходного файла проекта (.dll, .pdb, .xml…).
- Проект зависит как минимум от одного устаревшего проекта.
Инкрементальные проверки сборки не могут быть идеальными, особенно когда используются некоторые нетривиальные функции. Например, если в одном из файлов проекта для свойства Copy to Output Directory (Копировать в выходной каталог) установлено значение Copy Always (Копировать всегда), проект никогда не будет считаться актуальным. Такая причина не очевидна. Чтобы это обнаружить перейдите в Options > Projects and Solutions > SDK-Style Projects (Параметры > Проекты и решения > Проекты SDK) измените для параметра Logging Level значение с None на Minimal. Теперь в окне Output при сборке можно заметить строку:
1>FastUpToDate: Item … has CopyToOutputDirectory set to 'Always', not up to date.Это поможет понять, что заставляет проект перекомпилироваться каждый раз. Чтобы избавиться от этого, просто установите Copy to Output Directory на Copy if Newer (Копировать, если новее).
Чтобы узнать, есть ли у вашего решения такая проблема: сначала выполните Build > Rebuild Solution, а затем Build > Build Solution. Если какие-то проекты перекомпилируются второй раз, исследуйте проблему.
Окончание следует…
Источник: https://blog.ndepend.com/improve-visual-studio-build-performance/
👍10
День 1147.
Улучшаем Производительность Сборки в Visual Studio. Окончание
Начало
Другие советы
1. Это может показаться очевидным, но такие вещи, как антивирус или запуск под виртуальной машиной, могут значительно замедлить все задачи разработки, особенно сборки.
2. В окне Options > Projects and Solutions > Build and Run (Параметры > Проекты и решения > Сборка и запуск):
- Убедитесь, что вы используете параллельные сборки.
- Убедитесь, что отмечен флажок Only Build Startup and Dependencies on Run (Собирать только стартовый проект и зависимости при запуске).
3. По умолчанию Visual Studio компилирует каждый проект в отдельный каталог
Горячая перезагрузка
Благодаря новой функции горячей перезагрузки .NET (ранее известной как Edit and Continue) цикл
При горячей перезагрузке изменения исходного кода отслеживаются, компилируются и внедряются в исполняемые двоичные файлы. Внесение изменений с помощью горячей перезагрузки выполняется значительно быстрее, чем пересборка соответствующего проекта.
Большую часть времени модификации исходного кода между двумя сборками представляют собой крошечную часть пересобираемого кода. Можно ожидать, что в будущем конвейер сборки сможет повысить производительность инкрементной сборки за счет внедрения модификаций кода в двоичный файл вместо пересборки всего файла. Но уже в Visual Studio 2022 можно включить горячую перезагрузку, чтобы ускорить выполнение тестов, пропуская дорогостоящие этапы сборки для поддерживаемых типов изменений. Обратите внимание, что эта функция все ещё является экспериментальной и работает только для .NET 6.
Источник: https://blog.ndepend.com/improve-visual-studio-build-performance/
Улучшаем Производительность Сборки в Visual Studio. Окончание
Начало
Другие советы
1. Это может показаться очевидным, но такие вещи, как антивирус или запуск под виртуальной машиной, могут значительно замедлить все задачи разработки, особенно сборки.
2. В окне Options > Projects and Solutions > Build and Run (Параметры > Проекты и решения > Сборка и запуск):
- Убедитесь, что вы используете параллельные сборки.
- Убедитесь, что отмечен флажок Only Build Startup and Dependencies on Run (Собирать только стартовый проект и зависимости при запуске).
3. По умолчанию Visual Studio компилирует каждый проект в отдельный каталог
.\bin\Debug
и копирует туда все сборки, на которые ссылается проект. Это было настоящим убийцей производительности сборки в старых версиях VS. Надеюсь, это было исправлено. Тем не менее, если на проект P ссылаются N других проектов, существует N+1 файлов сборки P. Мало того, что это трата ресурсов, но также может быть, что версии станут рассинхронизированы, например, из-за того, что некоторые проекты были выгружены в обозревателе решений. Это может привести к неожиданному поведению во время выполнения, например к возникновению MissingMethodException
. Поэтому лучше установить, чтобы все проекты решения (кроме тестовых) использовали один и тот же выходной каталог ..\bin\Debug
. Таким образом, каждая сборка будет существовать в единственной версии.Горячая перезагрузка
Благодаря новой функции горячей перезагрузки .NET (ранее известной как Edit and Continue) цикл
[написание кода — сборка — запуск — достижение состояния для тестирования — тестирование]
сокращается, т.к. шаги [сборка — запуск — достижение состояния для тестирования]
могут быть пропущены в многих сценариях редактирования (но не всегда).При горячей перезагрузке изменения исходного кода отслеживаются, компилируются и внедряются в исполняемые двоичные файлы. Внесение изменений с помощью горячей перезагрузки выполняется значительно быстрее, чем пересборка соответствующего проекта.
Большую часть времени модификации исходного кода между двумя сборками представляют собой крошечную часть пересобираемого кода. Можно ожидать, что в будущем конвейер сборки сможет повысить производительность инкрементной сборки за счет внедрения модификаций кода в двоичный файл вместо пересборки всего файла. Но уже в Visual Studio 2022 можно включить горячую перезагрузку, чтобы ускорить выполнение тестов, пропуская дорогостоящие этапы сборки для поддерживаемых типов изменений. Обратите внимание, что эта функция все ещё является экспериментальной и работает только для .NET 6.
Источник: https://blog.ndepend.com/improve-visual-studio-build-performance/
👍2
День 1148.
Как Настроить Git для Улучшения Процесса Разработки
1. Выбор редактора по умолчанию
Git по умолчанию открывает редактор vi. Он может быть сложен в использовании. Однако вы можете использовать предпочитаемый вами редактор для написания коммитов. В файл .gitconfig добавьте:
2. prune при fetch
Если вы удалили ветку, например, после слияния её с основной, команда prune удалит устаревшие ссылки на удалённые ветки в вашем каталоге .git. Для этого вы можете выполнить
В файле конфигурации Git вы можете добавить псевдонимы для тех длинных команд, которыми вы постоянно пользуетесь: commit, stash и т.п.
Допустим, вы хотите добавить псевдоним для добавления пустого коммита. В файле конфигурации:
4. Ветка по умолчанию
При инициализации репозитория (
Как Настроить Git для Улучшения Процесса Разработки
git config
— мощная команда. Также вы можете использовать файл конфигурации. Он существует на уровне проекта, где инициализируется Git (/project/.git/config
), или в корне (~/.gitconfig
). Если конфигурация не указана, Git использует настройки по умолчанию. Рассмотрим некоторые полезные настройки, которые могут улучшить ваш процесс разработки.1. Выбор редактора по умолчанию
Git по умолчанию открывает редактор vi. Он может быть сложен в использовании. Однако вы можете использовать предпочитаемый вами редактор для написания коммитов. В файл .gitconfig добавьте:
[core]либо используйте команду:
editor = code --wait
git config --global core.editor "code --wait"Это откроет редактор VSCode. Настройки для других редакторов можно посмотреть здесь.
2. prune при fetch
Если вы удалили ветку, например, после слияния её с основной, команда prune удалит устаревшие ссылки на удалённые ветки в вашем каталоге .git. Для этого вы можете выполнить
git fetch –pruneЛибо задать это поведение по умолчанию в настройках. В файле конфигурации:
[fetch]либо командой:
prune = true
git config --global fetch.prune true3. Git-псевдонимы
В файле конфигурации Git вы можете добавить псевдонимы для тех длинных команд, которыми вы постоянно пользуетесь: commit, stash и т.п.
Допустим, вы хотите добавить псевдоним для добавления пустого коммита. В файле конфигурации:
[alias]либо командой:
empty = git commit --allow-empty
git config --global alias.empty "git commit --allow-empty"Теперь вы можете использовать такую команду:
git empty "Empty commit"В псевдонимах вы можете использовать не только команды Git, но и любые другие команды терминала. Git просто выполнит всё, что указано в команде. Для этого добавьте ! в начало команды:
this = !git init && git add . && git commit -m \"Initial commit.\"Теперь
git this
инициализирует репозиторий в папке, добавит все файлы под контроль git и выполнит первый коммит.4. Ветка по умолчанию
При инициализации репозитория (
git init
) веткой по умолчанию является main (или master). Не обязательно использовать это имя. В файле конфигурации Git вы можете установить ветку по умолчанию при инициализации:[init]Источник: https://www.freecodecamp.org/news/git-config-how-to-configure-git-settings/
defaultBranch = default
👍5
День 1149. #Карьера
Чем Больше Ты Знаешь, Тем Больше Знаешь, Что Не Знаешь
На изображении ниже вы можете увидеть, как рост опыта влияет на уверенность. Первоначально ваша уверенность низка, так как вы знаете, что вы неопытны. Однако через некоторое время вы начинаете «что-то понимать» и попадаете в зону комфорта. В зависимости от того, насколько требовательна ваша среда, вы можете оставаться там в течение очень долгого времени, но, если вас подталкивают вперёд, вы, скорее всего, быстро упадёте в «долину отчаяния», когда поймёте, что есть гораздо больше того, чего вы не умеете делать или ещё не освоили. С этой точки, как правило, ваша уверенность растёт по мере увеличения вашего опыта. Это известно как эффект Даннинга-Крюгера.
Его можно сравнить с синдромом самозванца, при котором уверенность человека намного ниже, чем следует, учитывая его опыт. Эффект Даннинга-Крюгера в основном проявляется, когда у вас ограниченный опыт и вы слишком самоуверенны. Синдром самозванца проявляется, когда у вас есть опыт и навыки, но вы чувствуете себя недостойным по сравнению с другими. Это две стороны одной медали, и лучший способ справиться с обоими — окружить себя коллегами с разным уровнем опыта, ставить себя в ситуации, когда ваши способности могут быть измерены в той или иной форме и реагировать на реальную обратную связь, а не просто слушать своё подсознание.
Я где-то слышал, как взаимосвязь между опытом и уверенностью описывалась, используя метафору расширяющегося круга. Ваши знания представлены внутри круга, а всё, чего вы ещё не знаете, находится снаружи. По мере того, как вы узнаёте больше, вы расширяете круг, увеличивая его площадь. Но вы также увеличиваете окружность круга, тем самым увеличивая свой контакт с вещами, которых вы ещё не знаете.
Можно расширить это представление, применив известную цитату Дональда Рамсфельда о «неизвестных неизвестных». Чем больше у вас опыта, тем больше вещей вы знаете. Также становится больше вещей, о которых вы знаете, что вы их не знаете. Но, кроме этого, есть множество вещей, о которых вы не знаете, что не знаете их. И несмотря ни на что, всегда будет большое (возможно, бесконечное) количество «неизвестных неизвестных».
Когда вы на самом деле приобретёте опыт, постарайтесь осмыслить его. Возможно, теперь у вас есть более глубокие познания в той или иной теме или технологии. Вероятно, есть вещи, о которых вы даже не догадывались, но теперь вы, по крайней мере, осознаёте их. Постарайтесь иметь в виду, что большинство вещей, о которых вы имеете поверхностное знание, но которые на самом деле известные вам неизвестные, вероятно, похожи в том, что, если бы вы действительно погрузились в них, вы бы обнаружили, что в них есть гораздо больше нюансов, чем вы представляете сейчас.
Это имеет несколько преимуществ:
1. Помогает держать своё эго под контролем.
2. Помогает сохранить ваше любопытство и желание учиться.
3. Помогает вам развивать и поддерживать уважение к другим, которые, возможно, нашли время, чтобы узнать больше о теме, которую вы прошли мимо.
Источник: https://ardalis.com/the-more-you-know-the-more-you-realize-you-dont-know/
Чем Больше Ты Знаешь, Тем Больше Знаешь, Что Не Знаешь
На изображении ниже вы можете увидеть, как рост опыта влияет на уверенность. Первоначально ваша уверенность низка, так как вы знаете, что вы неопытны. Однако через некоторое время вы начинаете «что-то понимать» и попадаете в зону комфорта. В зависимости от того, насколько требовательна ваша среда, вы можете оставаться там в течение очень долгого времени, но, если вас подталкивают вперёд, вы, скорее всего, быстро упадёте в «долину отчаяния», когда поймёте, что есть гораздо больше того, чего вы не умеете делать или ещё не освоили. С этой точки, как правило, ваша уверенность растёт по мере увеличения вашего опыта. Это известно как эффект Даннинга-Крюгера.
Его можно сравнить с синдромом самозванца, при котором уверенность человека намного ниже, чем следует, учитывая его опыт. Эффект Даннинга-Крюгера в основном проявляется, когда у вас ограниченный опыт и вы слишком самоуверенны. Синдром самозванца проявляется, когда у вас есть опыт и навыки, но вы чувствуете себя недостойным по сравнению с другими. Это две стороны одной медали, и лучший способ справиться с обоими — окружить себя коллегами с разным уровнем опыта, ставить себя в ситуации, когда ваши способности могут быть измерены в той или иной форме и реагировать на реальную обратную связь, а не просто слушать своё подсознание.
Я где-то слышал, как взаимосвязь между опытом и уверенностью описывалась, используя метафору расширяющегося круга. Ваши знания представлены внутри круга, а всё, чего вы ещё не знаете, находится снаружи. По мере того, как вы узнаёте больше, вы расширяете круг, увеличивая его площадь. Но вы также увеличиваете окружность круга, тем самым увеличивая свой контакт с вещами, которых вы ещё не знаете.
Можно расширить это представление, применив известную цитату Дональда Рамсфельда о «неизвестных неизвестных». Чем больше у вас опыта, тем больше вещей вы знаете. Также становится больше вещей, о которых вы знаете, что вы их не знаете. Но, кроме этого, есть множество вещей, о которых вы не знаете, что не знаете их. И несмотря ни на что, всегда будет большое (возможно, бесконечное) количество «неизвестных неизвестных».
Когда вы на самом деле приобретёте опыт, постарайтесь осмыслить его. Возможно, теперь у вас есть более глубокие познания в той или иной теме или технологии. Вероятно, есть вещи, о которых вы даже не догадывались, но теперь вы, по крайней мере, осознаёте их. Постарайтесь иметь в виду, что большинство вещей, о которых вы имеете поверхностное знание, но которые на самом деле известные вам неизвестные, вероятно, похожи в том, что, если бы вы действительно погрузились в них, вы бы обнаружили, что в них есть гораздо больше нюансов, чем вы представляете сейчас.
Это имеет несколько преимуществ:
1. Помогает держать своё эго под контролем.
2. Помогает сохранить ваше любопытство и желание учиться.
3. Помогает вам развивать и поддерживать уважение к другим, которые, возможно, нашли время, чтобы узнать больше о теме, которую вы прошли мимо.
Источник: https://ardalis.com/the-more-you-know-the-more-you-realize-you-dont-know/
👍9
День 1150. #Оффтоп
Сегодня будет полнейший оффтоп. На него меня вдохновил очередной твит одного из коллег программистов. Вопрос в нём был следующий:
Какая область (кроме ИТ) вдохновляет вас больше всего?
Это не обязательно может быть ваше личное хобби, может просто что-то, что вам интересно изучать или узнавать новости.
Расскажу о себе.
Для меня это авиация. Я сам, конечно, не летаю. Но я обожаю смотреть видео как об устройстве самолётов, так и о расследовании инцидентов и катастроф. Сотни и тысячи людей трудятся над тем, чтобы сделать этот вид транспорта более комфортным, более быстрым и более безопасным. Я больше воспринимаю визуальную информацию, поэтому у меня в приоритете видео.
Вот несколько каналов, которые я смотрю.
Mentour Pilot
Практикующий лётчик рассказывает об устройстве самолётов, аэропортов, о том, как составляется расписание, как работают пилоты, а также разбирает некоторые самые известные авиапроисшествия на основе официальных отчётов.
74 Gear
Канал второго пилота Боинга-747. Тематика похожая, но более неформальная. Он разбирает вирусные видео на тему авиации, смешные переговоры пилотов с диспетчерами, а также рассказывает байки из своей (и не только своей) практики.
Помимо этого, постоянно смотрю пару автомобильных каналов. На этот раз русскоязычных.
ИЛЬДАР АВТО-ПОДБОР
Ребята рассказывают, как ремонтируют, подбирают, а иногда дарят машины в рамках благотворительного проекта. Интересно, грамотно, с юмором.
Асафьев Стас
Эта, без преувеличения, выдающаяся команда, помимо регулярных новостей авторынка и обзоров автомобилей, выпускает просто потрясающие документалки про историю автомобилизации Японии, Франции или про развитие систем безопасности в автомобилях. Яркая картинка и искромётный юмор. Только осторожно, 18+.
Поделитесь в комментариях, что вас вдохновляет из не-ИТ мира? Не обязательно со ссылками на видео, может это книги, блоги или подкасты. То, что вы изучаете в свободное от программирования время.
Сегодня будет полнейший оффтоп. На него меня вдохновил очередной твит одного из коллег программистов. Вопрос в нём был следующий:
Какая область (кроме ИТ) вдохновляет вас больше всего?
Это не обязательно может быть ваше личное хобби, может просто что-то, что вам интересно изучать или узнавать новости.
Расскажу о себе.
Для меня это авиация. Я сам, конечно, не летаю. Но я обожаю смотреть видео как об устройстве самолётов, так и о расследовании инцидентов и катастроф. Сотни и тысячи людей трудятся над тем, чтобы сделать этот вид транспорта более комфортным, более быстрым и более безопасным. Я больше воспринимаю визуальную информацию, поэтому у меня в приоритете видео.
Вот несколько каналов, которые я смотрю.
Mentour Pilot
Практикующий лётчик рассказывает об устройстве самолётов, аэропортов, о том, как составляется расписание, как работают пилоты, а также разбирает некоторые самые известные авиапроисшествия на основе официальных отчётов.
74 Gear
Канал второго пилота Боинга-747. Тематика похожая, но более неформальная. Он разбирает вирусные видео на тему авиации, смешные переговоры пилотов с диспетчерами, а также рассказывает байки из своей (и не только своей) практики.
Помимо этого, постоянно смотрю пару автомобильных каналов. На этот раз русскоязычных.
ИЛЬДАР АВТО-ПОДБОР
Ребята рассказывают, как ремонтируют, подбирают, а иногда дарят машины в рамках благотворительного проекта. Интересно, грамотно, с юмором.
Асафьев Стас
Эта, без преувеличения, выдающаяся команда, помимо регулярных новостей авторынка и обзоров автомобилей, выпускает просто потрясающие документалки про историю автомобилизации Японии, Франции или про развитие систем безопасности в автомобилях. Яркая картинка и искромётный юмор. Только осторожно, 18+.
Поделитесь в комментариях, что вас вдохновляет из не-ИТ мира? Не обязательно со ссылками на видео, может это книги, блоги или подкасты. То, что вы изучаете в свободное от программирования время.
👍3