Рубрика: задачи, которые не дают на собесах.
❓ Вот вам задача: Есть сайт, на котором люди пишут код на C#, решая заданные алгоритмические задачи. Ваша задача, компилировать этот код на сервере, запускать на нем тесты и выдавать результат компиляции и прогона тестов. Как вы будете это делать? Как будете хранить условия задач? Как будете проверят результат выполнения?
➕ Ответили? Немного усложним задачу: что, если появился еще один язык программирования? Как будете строить архитектуру такого решения?
🗣 Я, как матерый веб-программист, конечно взял бы шину данных, поднял бы инстансы с компиляторами, которые принимают сырой код, передают его в нужный компилятор-запускатор и возвращают результат ну и так бы и расширял. Надо новый компилятор, просто добавляем новый адаптер и все. Сами задачки хранил бы в базе данных, вместе с юнит-тестами для них.
😵💫 Но ребята из Хекслета сделали все грациознее, показав, кто тут батя, и, где раки зимуют:
1. Они сохраняют файлы с кодом на сервак, как есть.
2. Потом эту папку подтягивает к докер-образу, в котором лежит компилятор, рантайм и прочее. Также там внутри лежат юнит тесты, которые проверяют решение
3. Докер-образ запускает все вышеозначенное на пользовательской папке и выдает ответ!
4. Сами задачи хранятся в обычном гитхаб-репозитории (вот в этом https://github.com/hexlet-basics), что избавляет нас от необходимости вообще создавать админку для менеджмента задач для платформы!
🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥О-ХУ-ЕТЬ! 🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥
Вот как можно было такое придумать? Бывалые может скажут: "Ну и что тут такого?" А я просто испытаю радость неофита при виде такого решения!
Вот тут есть статья Жени Васильева, нашего супер-техлида, из которой я достал эту информацию: https://habr.com/ru/company/hexlet/blog/652773/
Ну и, разумеется, ссылка на сорцы
https://github.com/hexlet-basics/hexlet-basics/tree/b32b228be35bed12615553515b1df05195d88e4b
❓ Вот вам задача: Есть сайт, на котором люди пишут код на C#, решая заданные алгоритмические задачи. Ваша задача, компилировать этот код на сервере, запускать на нем тесты и выдавать результат компиляции и прогона тестов. Как вы будете это делать? Как будете хранить условия задач? Как будете проверят результат выполнения?
➕ Ответили? Немного усложним задачу: что, если появился еще один язык программирования? Как будете строить архитектуру такого решения?
🗣 Я, как матерый веб-программист, конечно взял бы шину данных, поднял бы инстансы с компиляторами, которые принимают сырой код, передают его в нужный компилятор-запускатор и возвращают результат ну и так бы и расширял. Надо новый компилятор, просто добавляем новый адаптер и все. Сами задачки хранил бы в базе данных, вместе с юнит-тестами для них.
😵💫 Но ребята из Хекслета сделали все грациознее, показав, кто тут батя, и, где раки зимуют:
1. Они сохраняют файлы с кодом на сервак, как есть.
2. Потом эту папку подтягивает к докер-образу, в котором лежит компилятор, рантайм и прочее. Также там внутри лежат юнит тесты, которые проверяют решение
3. Докер-образ запускает все вышеозначенное на пользовательской папке и выдает ответ!
4. Сами задачи хранятся в обычном гитхаб-репозитории (вот в этом https://github.com/hexlet-basics), что избавляет нас от необходимости вообще создавать админку для менеджмента задач для платформы!
🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥О-ХУ-ЕТЬ! 🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥
Вот как можно было такое придумать? Бывалые может скажут: "Ну и что тут такого?" А я просто испытаю радость неофита при виде такого решения!
Вот тут есть статья Жени Васильева, нашего супер-техлида, из которой я достал эту информацию: https://habr.com/ru/company/hexlet/blog/652773/
Ну и, разумеется, ссылка на сорцы
https://github.com/hexlet-basics/hexlet-basics/tree/b32b228be35bed12615553515b1df05195d88e4b
GitHub
Hexlet Basics
Hexlet Basics has 61 repositories available. Follow their code on GitHub.
😁1
Мутантное тестирование! Протестируй свои тесты, детка.
Блин, меня просто распирает от крутости этой фичи. В общем, если вы пишете по TDD, то знаете, что там самое главное – написать в итоге такие тесты, чтобы они были точно корректными.
❓А как, блин, понять, что они корректные? Раньше так мог только гуру разработки. Так сказать, “с высоты своего опыта”. А сейчас появился инструмент под названием Stryker.
Очень забавное название, учитывая что это тулза для мутантного тестирования 😊
Для непосвященных Страйкер – это чувак, который заделал Росомаху. Не в смысле, как батя сына, а в смысле, как ученый мутанта с металлическими костями.
Ладно, я как всегда растекаюсь мыслей по древу (пиздобольствую), вот суть.
✅ Эта штука берет код ваших тестов, видит метод, который ваши тесты тестируют и начинает этот метод ломать разными способами. Если при поломке кода все ваши тесты упали, то все ок, значит вы учли все сценарии. Но если нет… Значит вы дятел 🦆Шучу, не дятел 😎
Рассмотрим пример. У вас есть вот такой метод:
Вы написали вот такой тест для него:
Ну очевидно, что тут не все тест-кейсы предусмотрены, но давайте посмотрим, что скажет страйкер.
1. Ставим его себе на тачку: dotnet tool install dotnet-stryker --global
2. Запускаем в папке с .csproj файлом теста: dotnet stryker
3. Видим отчет, в котором нам говорят о том, что мы покрыли 50 % всех тест-кейсов. Ну и там даже показано, как он мутировал строку, чтобы тест по идее сломать, но ваш тест не сломался.
4. Понимаем, что нужно накинуть еще один тест-кейс
5. Профит! 💸
Важная ремарка: чтобы все заработало, тестируемый класс и сами тесты должны быть в разных проектах, а то иначе страйкер не умеет найти класс который лежит рядом с тестами.
Короче, попробуйте запустить у себя на проекте Страйкера и посмотрите, что произойдет. Всего две строки и вы знаете, где маленько проебались!
Блин, меня просто распирает от крутости этой фичи. В общем, если вы пишете по TDD, то знаете, что там самое главное – написать в итоге такие тесты, чтобы они были точно корректными.
❓А как, блин, понять, что они корректные? Раньше так мог только гуру разработки. Так сказать, “с высоты своего опыта”. А сейчас появился инструмент под названием Stryker.
Очень забавное название, учитывая что это тулза для мутантного тестирования 😊
Для непосвященных Страйкер – это чувак, который заделал Росомаху. Не в смысле, как батя сына, а в смысле, как ученый мутанта с металлическими костями.
Ладно, я как всегда растекаюсь мыслей по древу (пиздобольствую), вот суть.
✅ Эта штука берет код ваших тестов, видит метод, который ваши тесты тестируют и начинает этот метод ломать разными способами. Если при поломке кода все ваши тесты упали, то все ок, значит вы учли все сценарии. Но если нет… Значит вы дятел 🦆Шучу, не дятел 😎
Рассмотрим пример. У вас есть вот такой метод:
public static int Subtract(int a, int b)
{
return a - b;
}
Вы написали вот такой тест для него:
[Test]
[TestCase(5,5,0)]
public void Test1(int a, int b, int expected)
{
var result = TryStrykerCalc.Subtract(a, b);
Assert.AreEqual(expected, result);
}
Ну очевидно, что тут не все тест-кейсы предусмотрены, но давайте посмотрим, что скажет страйкер.
1. Ставим его себе на тачку: dotnet tool install dotnet-stryker --global
2. Запускаем в папке с .csproj файлом теста: dotnet stryker
3. Видим отчет, в котором нам говорят о том, что мы покрыли 50 % всех тест-кейсов. Ну и там даже показано, как он мутировал строку, чтобы тест по идее сломать, но ваш тест не сломался.
4. Понимаем, что нужно накинуть еще один тест-кейс
5. Профит! 💸
Важная ремарка: чтобы все заработало, тестируемый класс и сами тесты должны быть в разных проектах, а то иначе страйкер не умеет найти класс который лежит рядом с тестами.
Короче, попробуйте запустить у себя на проекте Страйкера и посмотрите, что произойдет. Всего две строки и вы знаете, где маленько проебались!
Убойный релиз: MediatR теперь могет в AsyncEnumerable
Не особо давно у MediatR случился релизец, в котором библиотеку научили работать с AsyncEnumerable и это довольно охуенно, друзья.
https://jimmybogard.com/mediatr-10-0-released/
Вообще я фан IAsyncEnumerable и всей этой фичи, поскольку она реально улучшает работу вашего приложения с потоками.
👎А еще всегда удобно делать не вот это говно:
👍А просто и лаконично написать красоту:
Но перейдем к сути релиза.
❌ Раньше вы не могли вернуть IAsyncEnumerable в хэндлере, то есть сделать так:
✅Но после 6-го января 2022 года (видать на новогодних Джимми Боггарт не оливьеху наворачивал! 🥗) Вы можете делать асинхронные энумераторы в хэндлерах! Выглядит оно вот так. Вид от лица хэндлера, так сказать:
А вот как это выглядит в контроллере:
Не знаю по каким причинам, но меня трясет от страха, при виде слова Stream. Ни малейшего понятия, почему так. Возможно из-за собесов (ставь лайк если тоже заебали заумные собесы). Но тут можно не бояться, ибо метод CreateStream это тот же Send, только с другим возвращаемым типом. Думаю, не нужно пояснять с каким (IAsyncEnumerable ).
🅰️ Итого: Вы спросите меня, а что делать-то, Димас? А вот что! Если у вас в приложении есть MediatR и где-то вы собираете рузльтат, прежде чем отдать его, то выпиливайте эту срань к чертям и меняйте на прекрасный AsyncEnumerable!
PS. А ты поставил, кстати, звезду ⭐ медиатру на гитхабе? Если нет, то помни, Джимми старался на новогодних ради тебя, возможно не ел оливьеху. Поставь ему звезду, не постесняйся, а он тебе еще апдейтов накидает 🤩 https://github.com/jbogard/MediatR
Не особо давно у MediatR случился релизец, в котором библиотеку научили работать с AsyncEnumerable и это довольно охуенно, друзья.
https://jimmybogard.com/mediatr-10-0-released/
Вообще я фан IAsyncEnumerable и всей этой фичи, поскольку она реально улучшает работу вашего приложения с потоками.
👎А еще всегда удобно делать не вот это говно:
List<object> result = new List<object>();
foreach (var value in someCrazyList)
{
var shit = await RequestShitFromDB(value);
result.Add(shit);
}
return result;
👍А просто и лаконично написать красоту:
foreach (var value in someCrazyList)
{
yield return await RequestShitFromDB(value);
}
Но перейдем к сути релиза.
❌ Раньше вы не могли вернуть IAsyncEnumerable в хэндлере, то есть сделать так:
public async IAsyncEnumerable<WeatherResponse> Handle(WeatherRequest request, CancellationToken cancellationToken)
✅Но после 6-го января 2022 года (видать на новогодних Джимми Боггарт не оливьеху наворачивал! 🥗) Вы можете делать асинхронные энумераторы в хэндлерах! Выглядит оно вот так. Вид от лица хэндлера, так сказать:
public async IAsyncEnumerable<WeatherResponse> Handle(WeatherRequest request, CancellationToken cancellationToken)
{
for (int i = 0; i < request.DaysCount; i++)
{
// imitation of DB
await Task.Delay(100, cancellationToken);
yield return new WeatherResponse
{
Date = DateTime.Now.AddDays(i),
TemperatureC = Random.Shared.Next(-20, 55)
};
}
}
А вот как это выглядит в контроллере:
[HttpGet(Name = "GetWeatherForecast")]
public IAsyncEnumerable<WeatherResponse> Get([FromQuery]WeatherRequest request)
{
return _mediator.CreateStream(request);
}
Не знаю по каким причинам, но меня трясет от страха, при виде слова Stream. Ни малейшего понятия, почему так. Возможно из-за собесов (ставь лайк если тоже заебали заумные собесы). Но тут можно не бояться, ибо метод CreateStream это тот же Send, только с другим возвращаемым типом. Думаю, не нужно пояснять с каким (
🅰️ Итого: Вы спросите меня, а что делать-то, Димас? А вот что! Если у вас в приложении есть MediatR и где-то вы собираете рузльтат, прежде чем отдать его, то выпиливайте эту срань к чертям и меняйте на прекрасный AsyncEnumerable!
PS. А ты поставил, кстати, звезду ⭐ медиатру на гитхабе? Если нет, то помни, Джимми старался на новогодних ради тебя, возможно не ел оливьеху. Поставь ему звезду, не постесняйся, а он тебе еще апдейтов накидает 🤩 https://github.com/jbogard/MediatR
Jimmy Bogard
MediatR 10.0 Released
MediatR 10.0.0 released today: Release notesMigration GuideMediatR.Extensions.Microsoft.DependencyInjection release notesNuGetThis release adds support for IAsyncEnumerable<T> with separate types for this separate kind of request/response: IStreamRequest…
Вопросы из зала: Могу ли я использовать record’ы для описания конфигурации?
🩳 Коротко: да, но не так просто, ибо у них нет конструктора по умолчанию.
Когда видишь рекорды в первый раз (да и во второй), то задаешься вопросом, а могу ли я использовать для конфигурации?
🤟Это, детектив, правильный вопрос, ведь написать вот так:
💩Гораздо удобнее, чем вот так:
Но вот неудобная правда. Если просто попробовать зарегать такую конфигурацию в ASP.NET:
То при попытке достать конфигурацию:
😬 Рантайм (угадай заблюренное слово)опиздюлит вас ошибкой:
System.InvalidOperationException: Cannot create instance of type 'TestRec.BotConfiguration' because it is missing a public parameterless constructor.
И в принципе будет прав. Но! Кого вообще устроит такая ситуация? Меня точно не устроит! Поэтому я полез искать самые извращенные решения этой проблемы и нашел, пожалуй не самое извращенное, но доступное только с версии .NET 6.0
Для этого вам понадобится пакет DevTrends.ConfigurationExtensions, у которого всего три звезды на гитхабе (включая мою, разумеется): https://github.com/devtrends-org/configuration-extensions
✅Этот пакет позволяет сделать такой финт ушами. Зарегать конфигурацию как синглтон:
И использовать как синглтон:
И я проверил – все работает. Все параметры конфигурации учитываются, то есть, если запустите с параметром Development сборку, то подтянутся Development конфиги.
🅰️Итого: я бы сказал, что пока говорить о конфигах на рекордах скорее рановато, но для пет-проектов под пиво 🍻 попрёт.
P.S. Ну и, разумеется, по старой-доброй традиции, я предложу вам втащить ⭐ репозиторию. Для вас это клик, а для Paul Hiles это приятная неожиданность.
🩳 Коротко: да, но не так просто, ибо у них нет конструктора по умолчанию.
Когда видишь рекорды в первый раз (да и во второй), то задаешься вопросом, а могу ли я использовать для конфигурации?
🤟Это, детектив, правильный вопрос, ведь написать вот так:
public record BotConfiguration(string BotToken, string HostAddress);
💩Гораздо удобнее, чем вот так:
public class BotConfiguration
{
public string BotToken { get; set; }
public string HostAddress { get; set; }
}
Но вот неудобная правда. Если просто попробовать зарегать такую конфигурацию в ASP.NET:
builder.Services.Configure<BotConfiguration>(
builder.Configuration.GetSection("BotConfiguration"));
То при попытке достать конфигурацию:
var botConfig = builder.Configuration
.GetSection("BotConfiguration")
.Get<BotConfiguration>();
😬 Рантайм (угадай заблюренное слово)
System.InvalidOperationException: Cannot create instance of type 'TestRec.BotConfiguration' because it is missing a public parameterless constructor.
И в принципе будет прав. Но! Кого вообще устроит такая ситуация? Меня точно не устроит! Поэтому я полез искать самые извращенные решения этой проблемы и нашел, пожалуй не самое извращенное, но доступное только с версии .NET 6.0
Для этого вам понадобится пакет DevTrends.ConfigurationExtensions, у которого всего три звезды на гитхабе (включая мою, разумеется): https://github.com/devtrends-org/configuration-extensions
✅Этот пакет позволяет сделать такой финт ушами. Зарегать конфигурацию как синглтон:
builder.Services.AddSingleton(builder.Configuration.Bind<BotConfiguration>());
И использовать как синглтон:
var service = app.Services.GetRequiredService<BotConfiguration>();
И я проверил – все работает. Все параметры конфигурации учитываются, то есть, если запустите с параметром Development сборку, то подтянутся Development конфиги.
🅰️Итого: я бы сказал, что пока говорить о конфигах на рекордах скорее рановато, но для пет-проектов под пиво 🍻 попрёт.
P.S. Ну и, разумеется, по старой-доброй традиции, я предложу вам втащить ⭐ репозиторию. Для вас это клик, а для Paul Hiles это приятная неожиданность.
GitHub
GitHub - devtrends-org/configuration-extensions: Bind configuration to records and classes with parameterized (non parameterless)…
Bind configuration to records and classes with parameterized (non parameterless) constructors. - GitHub - devtrends-org/configuration-extensions: Bind configuration to records and classes with para...
Как писать интеграционные тесты без InMemoryDB или SQLite?
Этот крутой вопрос поднял мой добрый коллега Паша Кириллин. И я в очередной раз убедился, насколько же я дуболом 🤖.
💩 Обычно, если я хочу написать тесты, которым зачем-то нужна реальная база, то я втупую напишу docker-compose.yaml с конфигурацией этой базы. И каждый раз при запуске дергаю docker compose up. В общем, довольно грубый метод.
А вот Паша посидел разок и задумался, а как бы это сделать автоматизированно, чтобы не пришлось делать docker compose up? И сразу нашел решение в виде такого репозитория: https://github.com/HofmeisterAn/dotnet-testcontainers
✅ Вы только посмотрите, как это работает:
Если вы, как и я, пропускаете большие блоки кода при чтении (да-да, ты не один такой ленивый, нас как минимум двое 👬), то вот вам текстовое описание происходящего:
1. В переменной _testcontainers мы создаем конфигурацию контейнера, также как мы это обычно делаем в docker-compose.yaml
2. В методе SetUp мы запускаем эти контейнеры. Они запускаются в вашем локальном Docker
3. В методе TestMethod мы подключаемся к базе данных и делаем запрос.
4. В методе TearDown мы их гасим, после всех тестов
Звучит достойно! Но еще более достойно звучит тот факт, что таким же макаром вы можете поднимать RabbitMq, Kafka и еще всякие штуки!
🅰️Итого: Если вам хочется делать тесты на уровне классов, которые ходят в инфраструктурные сервисы, вы можете использовать эту штуку. Но кажется надо посмотреть, как такие тесты поднимать в Github Actions? Как запускать их в параллель? Я попробую ответить на эти вопросы завтра, а вам пореомендую не сцать и тоже попробовать эту штуку!
P.S. Естественно, я въебал звезду на гитхабе этому проекту. И ты тоже не сиди, пойди и въеби звезду! У проекта уже 994 ⭐, так что это серьезно!
Этот крутой вопрос поднял мой добрый коллега Паша Кириллин. И я в очередной раз убедился, насколько же я дуболом 🤖.
💩 Обычно, если я хочу написать тесты, которым зачем-то нужна реальная база, то я втупую напишу docker-compose.yaml с конфигурацией этой базы. И каждый раз при запуске дергаю docker compose up. В общем, довольно грубый метод.
А вот Паша посидел разок и задумался, а как бы это сделать автоматизированно, чтобы не пришлось делать docker compose up? И сразу нашел решение в виде такого репозитория: https://github.com/HofmeisterAn/dotnet-testcontainers
✅ Вы только посмотрите, как это работает:
using System.Threading.Tasks;
using DotNet.Testcontainers.Containers.Builders;
using DotNet.Testcontainers.Containers.Configurations.Databases;
using DotNet.Testcontainers.Containers.Modules.Abstractions;
using DotNet.Testcontainers.Containers.Modules.Databases;
using MySql.Data.MySqlClient;
using NUnit.Framework;
namespace TryTestContainers;
public sealed class UnitTest1
{
private readonly TestcontainerDatabase _testcontainers = new TestcontainersBuilder<MySqlTestcontainer>()
.WithDatabase(new MySqlTestcontainerConfiguration
{
Database = "db",
Username = "mysql",
Password = "mysql",
})
.Build();
[SetUp]
public async Task SetUp()
{
await _testcontainers.StartAsync();
}
[TearDown]
public async Task TearDown()
{
await _testcontainers.DisposeAsync().AsTask();
}
[Test]
public void TestMethod()
{
using MySqlConnection connection = new MySqlConnection(_testcontainers.ConnectionString);
using var command = new MySqlCommand();
connection.Open();
command.Connection = connection;
command.CommandText = "SELECT 1";
command.ExecuteReader();
}
}
Если вы, как и я, пропускаете большие блоки кода при чтении (да-да, ты не один такой ленивый, нас как минимум двое 👬), то вот вам текстовое описание происходящего:
1. В переменной _testcontainers мы создаем конфигурацию контейнера, также как мы это обычно делаем в docker-compose.yaml
2. В методе SetUp мы запускаем эти контейнеры. Они запускаются в вашем локальном Docker
3. В методе TestMethod мы подключаемся к базе данных и делаем запрос.
4. В методе TearDown мы их гасим, после всех тестов
Звучит достойно! Но еще более достойно звучит тот факт, что таким же макаром вы можете поднимать RabbitMq, Kafka и еще всякие штуки!
🅰️Итого: Если вам хочется делать тесты на уровне классов, которые ходят в инфраструктурные сервисы, вы можете использовать эту штуку. Но кажется надо посмотреть, как такие тесты поднимать в Github Actions? Как запускать их в параллель? Я попробую ответить на эти вопросы завтра, а вам пореомендую не сцать и тоже попробовать эту штуку!
P.S. Естественно, я въебал звезду на гитхабе этому проекту. И ты тоже не сиди, пойди и въеби звезду! У проекта уже 994 ⭐, так что это серьезно!
GitHub
GitHub - testcontainers/testcontainers-dotnet: A library to support tests with throwaway instances of Docker containers for all…
A library to support tests with throwaway instances of Docker containers for all compatible .NET Standard versions. - GitHub - testcontainers/testcontainers-dotnet: A library to support tests with ...
Проверяем TestContainers в Github Actions
Да уж после долгого перерыва, приятно вернуться в родную гавань. А я наконец попробовал запустить test-containers в Github Actions.
✅ Что же выяснилось. Выянилось, что все работает из коробки! Я ожидал, что нужны будут дополнительные телодвижения, но оказалось, что хватает стандартного запуска тестов.
Пример можно посмотреть тут, но в нем ничего не изменилось, кроме добавления файлов wofrkflow.
https://github.com/Undermove/TryTestContainers/runs/5623573070?check_suite_focus=true
🅰️Итого: dotnet-testcontainers однозначно заслуживает вашего внимания. Если хотите поднимать базы в докере, но не хотите писать docker-compose то это ваш вариант. Думаю, что если захотите параллелизации, то можно придумать какой-нибудь общий сетап для тестов, который будет поднимать контейнеры единожды.
Да уж после долгого перерыва, приятно вернуться в родную гавань. А я наконец попробовал запустить test-containers в Github Actions.
✅ Что же выяснилось. Выянилось, что все работает из коробки! Я ожидал, что нужны будут дополнительные телодвижения, но оказалось, что хватает стандартного запуска тестов.
Пример можно посмотреть тут, но в нем ничего не изменилось, кроме добавления файлов wofrkflow.
https://github.com/Undermove/TryTestContainers/runs/5623573070?check_suite_focus=true
🅰️Итого: dotnet-testcontainers однозначно заслуживает вашего внимания. Если хотите поднимать базы в докере, но не хотите писать docker-compose то это ваш вариант. Думаю, что если захотите параллелизации, то можно придумать какой-нибудь общий сетап для тестов, который будет поднимать контейнеры единожды.
GitHub
Fix tests · Undermove/TryTestContainers@caca0aa
Contribute to Undermove/TryTestContainers development by creating an account on GitHub.
Span: Как быстро уменьшить количество аллокаций? (кликбейт)
📹 Посмотрел недавно на все том же славном канале Ника Чапсаса видос про Span<T>. Рекламируется, как штука, которая позволяет избавиться от лишних упаковок при нарезке массивов. Примерно так:
1️⃣ Вот в этом примере есть упаковка при создании строки dayAsText:
2️⃣А вот в этом примере при создании dayAsSpan аллокации нет:
Потому что dayAsSpan просто ссылается на кусочек памяти, размещенный в dateAsSpan.
Я всегда пытаюсь приложить новые знания на практику web-разработки, и в этом случае, как вы понимаете тоже попытался сделать также, но… Потерпел фиаско, как известный в широких кругах пёс.
Долго пытался понять, что можно сделать. Может как-то в контроллерах там можно сэкономить, или в сервисах, которые обрабатывают батчами информацию. Но, нет.
В итоге пришел к выводу, что в web-разработке вам эта штука вряд ли пригодится, хотя бы потому, что у нее есть ограничение на использование только в синхронных методах.
🅰️ Так что, на вопрос в заголовке можно уверенно ответить: для web-разрабочтиков не через Span. Но вот в каких-нибудь библиотечных историях, вещь хорошая. А, ну и на собесах (ебучих) теперь вы можете ответить на какие-нибудь каверзные вопросы про этот Span.
📹 Посмотрел недавно на все том же славном канале Ника Чапсаса видос про Span<T>. Рекламируется, как штука, которая позволяет избавиться от лишних упаковок при нарезке массивов. Примерно так:
1️⃣ Вот в этом примере есть упаковка при создании строки dayAsText:
string _dateAsText = "08 07 2021";
string dayAsText = _dateAsText.Substring(0, 2);
2️⃣А вот в этом примере при создании dayAsSpan аллокации нет:
ReadOnlySpan<char> dateAsSpan = "08 07 2021";
ReadOnlySpan<char> dayAsSpan = dateAsSpan.Slice(0, 2);
Потому что dayAsSpan просто ссылается на кусочек памяти, размещенный в dateAsSpan.
Я всегда пытаюсь приложить новые знания на практику web-разработки, и в этом случае, как вы понимаете тоже попытался сделать также, но… Потерпел фиаско, как известный в широких кругах пёс.
Долго пытался понять, что можно сделать. Может как-то в контроллерах там можно сэкономить, или в сервисах, которые обрабатывают батчами информацию. Но, нет.
В итоге пришел к выводу, что в web-разработке вам эта штука вряд ли пригодится, хотя бы потому, что у нее есть ограничение на использование только в синхронных методах.
🅰️ Так что, на вопрос в заголовке можно уверенно ответить: для web-разрабочтиков не через Span. Но вот в каких-нибудь библиотечных историях, вещь хорошая. А, ну и на собесах (ебучих) теперь вы можете ответить на какие-нибудь каверзные вопросы про этот Span.
Вопросы, которые вам не задают на собесах: Что если заэвэйтить заэвэйченное?
Недавно я знатно объебался при написании кода. Прод не пострадал только благодаря тому, что нагрузка выявила рост потребления памяти и времени ответа. Время ответа выросло в два раза, а память на 20% подросла.
Оказалось все дело было в том, что я, уважаемые граждане, тупой и не знаю. Но теперь я умный и знаю и сейчас вам расскажу.
Предположим у вас есть такой метод:
✅Нормальный вариант вызова этого метода выглядит так:
❌Но вы можете вызвать его вот так:
😬И это будет ошибкой, но компилятор об этом никому не скажет и спокойно все прожует. Только вот вопрос, а что же тогда будет?
ℹ️ А будет вот что. Как вы (может быть) знаете async/await при использовании генерирует класс IAsyncStateMachine, в котором менеджерится продолжение работы вашего кода после оператора await. Так вот во втором случае таких классов сгенерируется не один, как в первом случае, а два! Отсюда и рост потребления памяти! Соответсвтенно увеличится и количество исполняемых инструкций после оператора await, что приводит и к замедлению работы метода. Такие дела!
🅰️Итого: не будьте тупыми, как я, и не передавайте асинхронные лямбды в методы с названием Async.
P.S.: А вот и ссылка на диффы между разными вариантами вызовов https://quickdiff.net/?unique_id=84CB0FCA-A15D-7D87-5747-80E13C087198
Недавно я знатно объебался при написании кода. Прод не пострадал только благодаря тому, что нагрузка выявила рост потребления памяти и времени ответа. Время ответа выросло в два раза, а память на 20% подросла.
Оказалось все дело было в том, что я, уважаемые граждане, тупой и не знаю. Но теперь я умный и знаю и сейчас вам расскажу.
Предположим у вас есть такой метод:
public async Task ExecuteAsync(Func<Task> action)
{
await action();
}
✅Нормальный вариант вызова этого метода выглядит так:
public async Task Bar()
{
await ExecuteAsync(() => Task.Delay(1000));
}
❌Но вы можете вызвать его вот так:
public async Task Foo()
{
await ExecuteAsync(async () =>
{
await Task.Delay(1000);
});
}
😬И это будет ошибкой, но компилятор об этом никому не скажет и спокойно все прожует. Только вот вопрос, а что же тогда будет?
ℹ️ А будет вот что. Как вы (может быть) знаете async/await при использовании генерирует класс IAsyncStateMachine, в котором менеджерится продолжение работы вашего кода после оператора await. Так вот во втором случае таких классов сгенерируется не один, как в первом случае, а два! Отсюда и рост потребления памяти! Соответсвтенно увеличится и количество исполняемых инструкций после оператора await, что приводит и к замедлению работы метода. Такие дела!
🅰️Итого: не будьте тупыми, как я, и не передавайте асинхронные лямбды в методы с названием Async.
P.S.: А вот и ссылка на диффы между разными вариантами вызовов https://quickdiff.net/?unique_id=84CB0FCA-A15D-7D87-5747-80E13C087198
Нужен ли async await в однострочных методах?
🗣 Третьего дня сели с Пашей Кириллиным перетереть за жизнь и как-то зацепились за предыдущий пост. И соответственно возник такой вопрос. Предположим есть у вас репозиторий, который достает там что-то из базы. вы его можете написать вот так:
❓Вопрос, нужОн ли здесь async await? Думаю вы уже догадались, что не нужОн. Но вот вопрос, а почему? На самом деле ответ был постом выше – такое решение приведет к генерации лишней стейт машины при вызове метода.
Опять же, я искренне думал, что компилятор как-то умно это обработает и не даст случиться беде. Но, как обычно, думать нужно головой, а не о компиляторах.
Ну и вот диффы для сравнения: https://quickdiff.net/?unique_id=BE81872D-7947-BF93-D398-3B6D0E321A05
🅰️Итого: избегаем async await в однострочных методах. Но, сеньоры, давайте уже признаемся, что мы все давно уже пользуемся этими async await-ами просто потому что они прикольные! Так что если очень хочется, то оставляйте – никто вас не поругает)))
🗣 Третьего дня сели с Пашей Кириллиным перетереть за жизнь и как-то зацепились за предыдущий пост. И соответственно возник такой вопрос. Предположим есть у вас репозиторий, который достает там что-то из базы. вы его можете написать вот так:
public class Repository
{
public Task<string> GetAsync()
{
return Task.FromResult("123");
}
}
❓Вопрос, нужОн ли здесь async await? Думаю вы уже догадались, что не нужОн. Но вот вопрос, а почему? На самом деле ответ был постом выше – такое решение приведет к генерации лишней стейт машины при вызове метода.
Опять же, я искренне думал, что компилятор как-то умно это обработает и не даст случиться беде. Но, как обычно, думать нужно головой, а не о компиляторах.
Ну и вот диффы для сравнения: https://quickdiff.net/?unique_id=BE81872D-7947-BF93-D398-3B6D0E321A05
🅰️Итого: избегаем async await в однострочных методах. Но, сеньоры, давайте уже признаемся, что мы все давно уже пользуемся этими async await-ами просто потому что они прикольные! Так что если очень хочется, то оставляйте – никто вас не поругает)))
Напишу-ка я про всякое, а не только про C#
Я тут понял, что увлечение C#-ом у меня носит сезонный характер – летом почему-то похуй на новые релизы .NET
А вот к осени и весне почему-то тянет насолененькое заумное.
Короче, я решил не забрасывать канал и писать тут еще и про процессы и про всякие организационные штуки, такие как управления изменениями, совмещения бизнес-потребностей с техническими долгами без боли и, что самое важное, Вазелина.
В общем, буду теперь и про это писать. Буду надеяться, что получится хотя бы в течение месяца это делать плюс-минус регулярно.
Я тут понял, что увлечение C#-ом у меня носит сезонный характер – летом почему-то похуй на новые релизы .NET
А вот к осени и весне почему-то тянет на
Короче, я решил не забрасывать канал и писать тут еще и про процессы и про всякие организационные штуки, такие как управления изменениями, совмещения бизнес-потребностей с техническими долгами без боли и, что самое важное, Вазелина.
В общем, буду теперь и про это писать. Буду надеяться, что получится хотя бы в течение месяца это делать плюс-минус регулярно.
Удаляйте задачи
И первое, что хочется рассказать – это про задачи в бэклоге. За свою карьеру я видел мнго бэклогов. Больших и маленьких, кривых и прямых, с двумя и десятью колонками. Но все их объединяло одно – команды боятся удалять старые задачи.
Причем удалять их боятся именно разработчики. Бизнесу в общем-то индиферентно (хуекладительно ) на то, что творится в бэклоге у этих задротов, но сами задроты свой бэклог стерегут.
Если в бэклоге есть задача, которой сто лет, то ее конечно никто делать не будет, но не дай боже какая падла эту задачку тронет – поминай как звали.
А вместе с тем: неактуальные задачи мешают видеть, что важно в данный момент.
💡 Пример: пришел в команду. В бэклоге есть задача: "Поправить клиентские логи" Делать ее 5 минут, польза приходит практически моментально. Но выше нее скопилось 56 задач. Из них 38 завели люди, которые уже уволились. Но у задач стоит какой-то высокий приоритет, поэтому они закрывают свежую задачу.
🅰️ Что делать? Удаляем все задачи, что лежат в бэклоге дольше месяца, если не хочется удалять, то берем и сразу делаем. Если сразу сделать не получилось, то удаляем.
Но что происходит на самом деле: при попытке удалить задачу все вокруг взрываются и шипят – ты что, а как же техдолг! Ты его не выплачиваешь! Потом его придется отдавать вдвойне! (летят слюни впереммешку с камнями)
Ответ: настоящие срочные задачи вылезут сами и жизнь поставит условия так, что их придется сделать. Если задача два года лежала и не мешала, значит вы – ошиблись формулируя эту задачу и ее важность. Поэтому так вышло, что она там лежит, а не потому что это реальный техдолг.
В общем, удаляйте задачи.
#бэклог
И первое, что хочется рассказать – это про задачи в бэклоге. За свою карьеру я видел мнго бэклогов. Больших и маленьких, кривых и прямых, с двумя и десятью колонками. Но все их объединяло одно – команды боятся удалять старые задачи.
Причем удалять их боятся именно разработчики. Бизнесу в общем-то индиферентно (
Если в бэклоге есть задача, которой сто лет, то ее конечно никто делать не будет, но не дай боже какая падла эту задачку тронет – поминай как звали.
А вместе с тем: неактуальные задачи мешают видеть, что важно в данный момент.
💡 Пример: пришел в команду. В бэклоге есть задача: "Поправить клиентские логи" Делать ее 5 минут, польза приходит практически моментально. Но выше нее скопилось 56 задач. Из них 38 завели люди, которые уже уволились. Но у задач стоит какой-то высокий приоритет, поэтому они закрывают свежую задачу.
🅰️ Что делать? Удаляем все задачи, что лежат в бэклоге дольше месяца, если не хочется удалять, то берем и сразу делаем. Если сразу сделать не получилось, то удаляем.
Но что происходит на самом деле: при попытке удалить задачу все вокруг взрываются и шипят – ты что, а как же техдолг! Ты его не выплачиваешь! Потом его придется отдавать вдвойне! (летят слюни впереммешку с камнями)
Ответ: настоящие срочные задачи вылезут сами и жизнь поставит условия так, что их придется сделать. Если задача два года лежала и не мешала, значит вы – ошиблись формулируя эту задачу и ее важность. Поэтому так вышло, что она там лежит, а не потому что это реальный техдолг.
В общем, удаляйте задачи.
#бэклог
🔥2
Телега и боты.
Если вы ищете непаханные поля, то боты в телеге это именно они. Во первых их мало, во вторых в них пока нет общепринятых правил для оформления UI. Очень много ботов с хорошими полезными функциями, но с дерьмовым юзабилити.
Так что можно брать существующего бота, улучшать его юзабилити и захватывать рынок!
Кстати из-за того что в этой области пока что нет индустрии - появляются очень прикольные штуки типа текстовых ММО для дружеских чатов! К примеру @toadbot позволяет вам с друзьями растить своих жаб, собирать из них кланы и нападать на других жаб!
Если у вас есть полудохлый дружеский чатик в телеге, то вы можете оживить его с помощью жабок 🐸
Или вот чел сделал текстовый вариант игры Wastelands с другими игроками, преферансом и радиоактивными куртизанками! 🌆
Короче боты для телеги - топчик! Думаю буду периодически рассказывать про поо них.
Если вы ищете непаханные поля, то боты в телеге это именно они. Во первых их мало, во вторых в них пока нет общепринятых правил для оформления UI. Очень много ботов с хорошими полезными функциями, но с дерьмовым юзабилити.
Так что можно брать существующего бота, улучшать его юзабилити и захватывать рынок!
Кстати из-за того что в этой области пока что нет индустрии - появляются очень прикольные штуки типа текстовых ММО для дружеских чатов! К примеру @toadbot позволяет вам с друзьями растить своих жаб, собирать из них кланы и нападать на других жаб!
Если у вас есть полудохлый дружеский чатик в телеге, то вы можете оживить его с помощью жабок 🐸
Или вот чел сделал текстовый вариант игры Wastelands с другими игроками, преферансом и радиоактивными куртизанками! 🌆
Короче боты для телеги - топчик! Думаю буду периодически рассказывать про поо них.
DTF
Wasteland Wars: о развитии игры-бота в условиях блокировки Telegram — Офтоп на DTF
Здравствуйте, дорогие друзья! Сказать, что блокировка Telegram ударила по многим магазинам и развлекательным сервисам — значит ничего не сказать.
🤔2
Принцип Питера.
Недавно узнал про такую штуку, как Принцип Питера.(А ещё узнал что существуют люди с фамилией Питер) Он гласит, что любой человек в иерархической системе будет продвигаться вверх по карьерной лестнице до тех пор, пока не окажется на такой должности, где он окажется полным профаном.
И в целом это логично - вы хотите поощрить хорошего сотрудника, логично дать ему звание повыше, соответственно зарплату побольше. Так и получается что из хороших программистов получаются среднего качества тимлиды, архитекторы, начальники департаментов и прочие директора.
❓Короче, я решил порассуждать, как это исправить? Первое что приходит на ум, отвязать зарплату от должности. Но тогда появляется проблема. Вот у вас программист стал тимлидом, а зарплату вы ему не подняли. Вроде как и несправедливо получается - ответственности больше, а деньги все те же. Никто так тимлидом становиться не захочет.
🅰️ Но можно так – дать возможность пройти испытательный срок. При этом сразу поднять зп, но несильно, к примеру на 10% от стандартного повышения. Если человеку комфортно в новой должности и он чувствует себя в ней ок, то выдать полный пакет денег и считать эксперимент удачным, а если нет, то ничего страшного, можно оставить эту слегка поднятую зарплату - так как человек оброс новым опытом за этот срок.
Мне показалось, что это норм решение в целом – вроже и для продвижения наверх есть какой-то стимул, и при этом это продвижение не обязует тебя оставаться на некомфортной должности, то есть дает возможность отсутпить.
Хотя мне, конечно легко распоряжаться деньгами, которых у меня нет 🌚 Но вот такое мыслительное упражнение.
Недавно узнал про такую штуку, как Принцип Питера.
И в целом это логично - вы хотите поощрить хорошего сотрудника, логично дать ему звание повыше, соответственно зарплату побольше. Так и получается что из хороших программистов получаются среднего качества тимлиды, архитекторы, начальники департаментов и прочие директора.
❓Короче, я решил порассуждать, как это исправить? Первое что приходит на ум, отвязать зарплату от должности. Но тогда появляется проблема. Вот у вас программист стал тимлидом, а зарплату вы ему не подняли. Вроде как и несправедливо получается - ответственности больше, а деньги все те же. Никто так тимлидом становиться не захочет.
🅰️ Но можно так – дать возможность пройти испытательный срок. При этом сразу поднять зп, но несильно, к примеру на 10% от стандартного повышения. Если человеку комфортно в новой должности и он чувствует себя в ней ок, то выдать полный пакет денег и считать эксперимент удачным, а если нет, то ничего страшного, можно оставить эту слегка поднятую зарплату - так как человек оброс новым опытом за этот срок.
Мне показалось, что это норм решение в целом – вроже и для продвижения наверх есть какой-то стимул, и при этом это продвижение не обязует тебя оставаться на некомфортной должности, то есть дает возможность отсутпить.
Хотя мне, конечно легко распоряжаться деньгами, которых у меня нет 🌚 Но вот такое мыслительное упражнение.
🤸Горизонтальная мобильность.
Короче, я тут прочитал книгу Гуриева "Мифы экономики" и как любой пиздюк, узнавший новое слово, вворачиваю её в разговор по делу и без дела. Вот и сейчас вверну.
Там в этой книге основная мысль, что для того чтобы поднять Россию с колен нужно
1️⃣ Обеспечить справедливое рыночное взаимодействие в каждой из отраслей. Это типа чтобы частное лицо могло подать в суд на корпорацию и имело справедливый шанс выиграть.
2️⃣ Обеспечить населению страны горизонтальную мобильность. Это чтобы чуваки из депрессивных регионов могли свободно гонять по стране в поисках счастья в менее депрессивных регионах (физическая мобильность, она же миграция). Ну и там еще попутно решается проблема моногородов – если в городе закрылся металлургический завод, то оплати людям курсы переквалификации (социальная мобильность)
Первый пункт меня зацепил, но с ним у нас все грустно.
А вот второй пункт я переложил на АйТи. Потому что в АйТи сейчас как мне кажется мало кто вообще озабочен вопросами горизонтальной мобильности. Народ строит всякие ассесменты по уровням Джуниор-Миддл-Синьор-Эльф 80-го уровня и так далее.
Все это выглядят искусственно и по своей сути недалеко ускакало от табели о рангах Петра I. (Кстати, как думаете за сколько конф-коллов с боярами Петр успел намутить такую пиздатую таблицу? А ведь у него даже гуглшитов не было!) В общем, наверное это хороший первый шаг, но подозреваю, что нужно уже начинать искать в других направлениях. Горизонтальная мобильность – как раз такое направление! Идея этого дела проста, вы в своей компании создаете механизм, который позволяет преващаться в дата-сайнетиста из продакт-оунера и наоборот.
❓Чем вообще полезен такой переход? Дохрена чем:
1. К примеру у вас человек застрял на каком-то уровне. Не может он вытянуть дата-сайнетизм на сеньора и все тут. В общем, начал человек кукситься и в конечном итоге скурвился и осатанел. Хочет сменить работу. В обычном случае он от вас уйдет куда-то и унесет пару кило экспертизы, которую успел накопить. А тут вы со своей горизонтальной мобильностью! И он остается с вами! (и пару кило его компетенций тоже)
2. Или вот предположим, что человек для общего развития захотел посмотреть, а чем живут те, кто делают его таски? То ему надо на какие-то курсы для IT идти, платить туда деньги и так далее. А тут вы раз и его на три месяца в ссылку к этим ебаным ойтишникам. И вот он уже через три месяца возвращается как огурчик и спятнцами в подмышках! И все с минимальными потерями.
🅰️У кого же подсмотреть примеры того что это работает? На самом деле горизонтальная мобильность очень хорошо развита у стртапов. Там на начальном этапе развития многие работники – многостаночники. То есть программисты работают продакт-оунерами, продакт-оунеры сис-админами. Из этого всего вырастают вполне себе классыне лидеры, которые разбираются в нескольких обласятх, от чего могут нанимать качественный персонал и в те и другие области. Ну кстати, чем не пример – Билл Гейтс.
🎰 Короче, моя ставка на то, что компании, которые смогут продумать у себя толковую горизонтальную мобильность займут место на Олимпе великих, остальные сдохнут.(не является частной инвистиционной рекомендацией)
Короче, я тут прочитал книгу Гуриева "Мифы экономики" и как любой пиздюк, узнавший новое слово, вворачиваю её в разговор по делу и без дела. Вот и сейчас вверну.
Там в этой книге основная мысль, что для того чтобы поднять Россию с колен нужно
1️⃣ Обеспечить справедливое рыночное взаимодействие в каждой из отраслей. Это типа чтобы частное лицо могло подать в суд на корпорацию и имело справедливый шанс выиграть.
2️⃣ Обеспечить населению страны горизонтальную мобильность. Это чтобы чуваки из депрессивных регионов могли свободно гонять по стране в поисках счастья в менее депрессивных регионах (физическая мобильность, она же миграция). Ну и там еще попутно решается проблема моногородов – если в городе закрылся металлургический завод, то оплати людям курсы переквалификации (социальная мобильность)
Первый пункт меня зацепил, но с ним у нас все грустно.
А вот второй пункт я переложил на АйТи. Потому что в АйТи сейчас как мне кажется мало кто вообще озабочен вопросами горизонтальной мобильности. Народ строит всякие ассесменты по уровням Джуниор-Миддл-Синьор-Эльф 80-го уровня и так далее.
Все это выглядят искусственно и по своей сути недалеко ускакало от табели о рангах Петра I. (Кстати, как думаете за сколько конф-коллов с боярами Петр успел намутить такую пиздатую таблицу? А ведь у него даже гуглшитов не было!) В общем, наверное это хороший первый шаг, но подозреваю, что нужно уже начинать искать в других направлениях. Горизонтальная мобильность – как раз такое направление! Идея этого дела проста, вы в своей компании создаете механизм, который позволяет преващаться в дата-сайнетиста из продакт-оунера и наоборот.
❓Чем вообще полезен такой переход? Дохрена чем:
1. К примеру у вас человек застрял на каком-то уровне. Не может он вытянуть дата-сайнетизм на сеньора и все тут. В общем, начал человек кукситься и в конечном итоге скурвился и осатанел. Хочет сменить работу. В обычном случае он от вас уйдет куда-то и унесет пару кило экспертизы, которую успел накопить. А тут вы со своей горизонтальной мобильностью! И он остается с вами! (и пару кило его компетенций тоже)
2. Или вот предположим, что человек для общего развития захотел посмотреть, а чем живут те, кто делают его таски? То ему надо на какие-то курсы для IT идти, платить туда деньги и так далее. А тут вы раз и его на три месяца в ссылку к этим ебаным ойтишникам. И вот он уже через три месяца возвращается как огурчик и спятнцами в подмышках! И все с минимальными потерями.
🅰️У кого же подсмотреть примеры того что это работает? На самом деле горизонтальная мобильность очень хорошо развита у стртапов. Там на начальном этапе развития многие работники – многостаночники. То есть программисты работают продакт-оунерами, продакт-оунеры сис-админами. Из этого всего вырастают вполне себе классыне лидеры, которые разбираются в нескольких обласятх, от чего могут нанимать качественный персонал и в те и другие области. Ну кстати, чем не пример – Билл Гейтс.
🎰 Короче, моя ставка на то, что компании, которые смогут продумать у себя толковую горизонтальную мобильность займут место на Олимпе великих, остальные сдохнут.
🤩1
Как сделать горизонтальную мобильность просто и справедливо?
Я тут еще поразмышлял про горизонтальную мобильность и подумал, что это тоже своего рода лекарство от выполнения принципа Питера. Вы не перемещаете человека на уровень выше, но тоже что-то меняете в его жизни, может ему этого будет достаточно.
💡Попробовал вспомнить, как в других компаниях организуют горизонтальную мобильность. И оказалось, что хуево. Если человек совершает горизонтальный переход, ему много где срезают ЗП. Мотивируется это так: «У меня был синьор продакт оунер, а стал Джуниор дата-сайнетист. Конечно я буду платить ему меньше»
Ну так-то оно так, да нихуя не так. У тебя появляется джуниор с хорошим пониманием бизнес-задач, это не просто хер с горы, а потенциально человек, который может тебе подарить нестандартное решение, которое может выстрелить. И вероятность выстрела высока, так как меняют профессиональную отрасль зачастую нацеленные на результат люди. Но вопрос зарплаты действительно требует разрешения.
❓Так как же сделать горизонтальную мобильность просто и справедливо?
К примеру у нас есть синьор продакт оунер с зарплатой 160к и он хочет стать джуниор фронтенд разработчиком, где зп, 80к. Какие очевидные варианты у нас есть?
1. Перевести с сохранением зарплаты. Но тогда у нас появляется Джуниор с непомерной зп, и все остальные начинают ему завидовать. Вдобавок к этому в этой должности повышать и индексировать зарплату уже никто не будет, так как надо ещё до этой дорасти.
2. Перевести с не очень сильным снижением зп. Типа чуть посправедливее к коллегам по цеху.
И тот и другой вариант стимулируют скорее ничего не делать, чем делать что-то. А нам все же нужны стимулы для горизонтальной мобильности.
🅰️Я придумал похожий вариант, как в посте про принцип Питера: Оставляем зп на уровне 160к + 3к за смелость и даем испытательный срок. В случае провала мы получим продакта с подросшей компетенцией в новой области, который лучше понимает проблематику разработки (и еще у него ЗП станет 163к). А в случае успеха мы получим фронтенд разработчика, который может помочь с бизнесовым видением задачи (и тоже с зп в 163к). И то и другое потенциально может не сработать, но если сработает, то может позволить вам создать что-то чего на рынке пока нет.
Тут остаётся много вопросов ещё на тему денег, к примеру, а как поступить, если чувак захотел вернуться в свою область? А что будет, если все в компании начнут бегать по смежным областям и набивать себе микроприбавки к ЗП. Но мне лень писать обо всем этом подробно, потому что кажется все это можно решить с помощью здравого смысла.
✅Главный принцип в том, что инициативу необходимо поощрять, независимо от результата, но при этом минимизировать потери на случай неудачи.
Я тут еще поразмышлял про горизонтальную мобильность и подумал, что это тоже своего рода лекарство от выполнения принципа Питера. Вы не перемещаете человека на уровень выше, но тоже что-то меняете в его жизни, может ему этого будет достаточно.
💡Попробовал вспомнить, как в других компаниях организуют горизонтальную мобильность. И оказалось, что хуево. Если человек совершает горизонтальный переход, ему много где срезают ЗП. Мотивируется это так: «У меня был синьор продакт оунер, а стал Джуниор дата-сайнетист. Конечно я буду платить ему меньше»
Ну так-то оно так, да нихуя не так. У тебя появляется джуниор с хорошим пониманием бизнес-задач, это не просто хер с горы, а потенциально человек, который может тебе подарить нестандартное решение, которое может выстрелить. И вероятность выстрела высока, так как меняют профессиональную отрасль зачастую нацеленные на результат люди. Но вопрос зарплаты действительно требует разрешения.
❓Так как же сделать горизонтальную мобильность просто и справедливо?
К примеру у нас есть синьор продакт оунер с зарплатой 160к и он хочет стать джуниор фронтенд разработчиком, где зп, 80к. Какие очевидные варианты у нас есть?
1. Перевести с сохранением зарплаты. Но тогда у нас появляется Джуниор с непомерной зп, и все остальные начинают ему завидовать. Вдобавок к этому в этой должности повышать и индексировать зарплату уже никто не будет, так как надо ещё до этой дорасти.
2. Перевести с не очень сильным снижением зп. Типа чуть посправедливее к коллегам по цеху.
И тот и другой вариант стимулируют скорее ничего не делать, чем делать что-то. А нам все же нужны стимулы для горизонтальной мобильности.
🅰️Я придумал похожий вариант, как в посте про принцип Питера: Оставляем зп на уровне 160к + 3к за смелость и даем испытательный срок. В случае провала мы получим продакта с подросшей компетенцией в новой области, который лучше понимает проблематику разработки (и еще у него ЗП станет 163к). А в случае успеха мы получим фронтенд разработчика, который может помочь с бизнесовым видением задачи (и тоже с зп в 163к). И то и другое потенциально может не сработать, но если сработает, то может позволить вам создать что-то чего на рынке пока нет.
Тут остаётся много вопросов ещё на тему денег, к примеру, а как поступить, если чувак захотел вернуться в свою область? А что будет, если все в компании начнут бегать по смежным областям и набивать себе микроприбавки к ЗП. Но мне лень писать обо всем этом подробно, потому что кажется все это можно решить с помощью здравого смысла.
✅Главный принцип в том, что инициативу необходимо поощрять, независимо от результата, но при этом минимизировать потери на случай неудачи.
❤1
Так это порт у вас или адаптер?
Не понимаю как можно жить без пет-проектов. Есть вот к примеру такая статья.
https://herbertograca.com/2017/11/16/explicit-architecture-01-ddd-hexagonal-onion-clean-cqrs-how-i-put-it-all-together/
Там есть красивая картинка, что мол вот у тебя есть ядро и вот оно такое красивое, только с бизнес-логикой и все такое прочее, а все остальное это порты и адаптеры.
❓Но как это должно выглядеть в итоге в коде? Что значит вот это ядро? Это папка с таким названием? Или отдельный репозиторий? Или проект? Или класс такой?
✅ Благо есть репозиторий от Джейсона Тейлора, который проливает свет на это дело. Там это все уже как надо расписано: https://github.com/jasontaylordev/NorthwindTraders
❓Круто! Но вот я сел за код и у меня задача – написать телеграм-бота. А Джейсона Тейлора он для веб-приложений. Возникает вопрос. Часть, которая отвечает за взаимодействие с телегой – это часть ядра? Или это уже какой-то порт? А может вообще адаптер? А может еще что-то третье?
✅По итогу вышло, что это на самом деле это зависит от твоего желания.
Если ты пишешь чисто телеграм-бота и ты решил, что никаких больше других соц сетей ты поддерживать не хочешь, то это будет частью ядра.
Если ты выяснил, что будут еще какие-то соц-сети, то это будет адаптер, а из ядра тебе надо будет прокидывать порты для него, ну медиатры там всякие.
Короче, я ХЗ как после чтения этой статьи без пет-проекта можно все это прохавать. Может есть кто-то кто может, но мне вот прям никак.
Не понимаю как можно жить без пет-проектов. Есть вот к примеру такая статья.
https://herbertograca.com/2017/11/16/explicit-architecture-01-ddd-hexagonal-onion-clean-cqrs-how-i-put-it-all-together/
Там есть красивая картинка, что мол вот у тебя есть ядро и вот оно такое красивое, только с бизнес-логикой и все такое прочее, а все остальное это порты и адаптеры.
❓Но как это должно выглядеть в итоге в коде? Что значит вот это ядро? Это папка с таким названием? Или отдельный репозиторий? Или проект? Или класс такой?
✅ Благо есть репозиторий от Джейсона Тейлора, который проливает свет на это дело. Там это все уже как надо расписано: https://github.com/jasontaylordev/NorthwindTraders
❓Круто! Но вот я сел за код и у меня задача – написать телеграм-бота. А Джейсона Тейлора он для веб-приложений. Возникает вопрос. Часть, которая отвечает за взаимодействие с телегой – это часть ядра? Или это уже какой-то порт? А может вообще адаптер? А может еще что-то третье?
✅По итогу вышло, что это на самом деле это зависит от твоего желания.
Если ты пишешь чисто телеграм-бота и ты решил, что никаких больше других соц сетей ты поддерживать не хочешь, то это будет частью ядра.
Если ты выяснил, что будут еще какие-то соц-сети, то это будет адаптер, а из ядра тебе надо будет прокидывать порты для него, ну медиатры там всякие.
Короче, я ХЗ как после чтения этой статьи без пет-проекта можно все это прохавать. Может есть кто-то кто может, но мне вот прям никак.
@hgraca
DDD, Hexagonal, Onion, Clean, CQRS, … How I put it all together
In my last posts I’ve been writing about many of the concepts and principles that I’ve learned and a bit about how I reason about them. But I see these as just pieces of big a puzzle. …
👏1
🐈 Маленький победоносный пет-проект.
Вот пет-проекты это круто, но жутко порой задалбывают. Ты их начинаешь писать, чтобы отвлечься от работы, но потом тебе уже хочтся отвлечься от самих пет-проектов, и ты заводишь новый пет-проект, чтобы отвлечься от предыдущего пет-проекта. Ну а когда тебя задолбает этот пет-проект, то понятно, что ты заведешь новый и так далее.
🅰️ Короче, я придумал выход из этой смачной ситуации! Нужно, чтобы отвлекающие пет-пргоекты были на пару дней всего.
💡 Типа делаете вы там супер-пупер сервис и работы там на год. Хотите отвлечься. Ну и денек пишете генератор для названий водки. Быстренько сделали, всем похвастались, ну и дальше пошли пилить свой мега-проект.
Вот так вот просто!
P.S. Начал тут такой пет-проект, а он растянулся на неделю. Вот же сука!
Вот пет-проекты это круто, но жутко порой задалбывают. Ты их начинаешь писать, чтобы отвлечься от работы, но потом тебе уже хочтся отвлечься от самих пет-проектов, и ты заводишь новый пет-проект, чтобы отвлечься от предыдущего пет-проекта. Ну а когда тебя задолбает этот пет-проект, то понятно, что ты заведешь новый и так далее.
🅰️ Короче, я придумал выход из этой смачной ситуации! Нужно, чтобы отвлекающие пет-пргоекты были на пару дней всего.
💡 Типа делаете вы там супер-пупер сервис и работы там на год. Хотите отвлечься. Ну и денек пишете генератор для названий водки. Быстренько сделали, всем похвастались, ну и дальше пошли пилить свой мега-проект.
Вот так вот просто!
P.S. Начал тут такой пет-проект, а он растянулся на неделю. Вот же сука!
🔥1
Быстрое знание: console.table()
💨 Смотрел тут сторис в инстаграмме и между фотками из чужих путешествий и чужих котов проскочила инфа, что помимо console.log() в браузере можно использовать console.table()
🅰️ Так удобнее смотреть большие объекты. Сначала не поверил. Но! Проверил – работает! Юзайте.
P.S.: Хотя может я один такой не знал 😕
💨 Смотрел тут сторис в инстаграмме и между фотками из чужих путешествий и чужих котов проскочила инфа, что помимо console.log() в браузере можно использовать console.table()
🅰️ Так удобнее смотреть большие объекты. Сначала не поверил. Но! Проверил – работает! Юзайте.
P.S.: Хотя может я один такой не знал 😕
🤯1
😐Ресайленс и самообучение
Расскажу сейчас про охуенную штуку для изучения ресайленса!
Год назад я думал, как нам заятнуть на работу Chaos Testing. Ничего особо не получилось. Но! Удалось посмотреть такую штуку как Simmy https://github.com/Polly-Contrib/Simmy.
Simmy это версия Polly из темной всеенной 🌚. Если в Polly вы настраиваете все так чтобы у вас ничего не упало по итогу, то в Simmy вы настраиваете рандомные падения так, чтобы все деградировало каждый раз по-разному, но чтобы эти деградации выглядели реалистично. (Наконец в этом канале хоть что-то про деградацию! Услада для тех, кто пришел деградировать )
💆 Я если честно не допер, как в итоге это применить в работе. Подумал, что пока туповат. Потом посидели с чуваками на работе, потупили в код этой штуки. Он выглядит кстати вот так:
В этом коде делается так чтобы 10% ваших запросов проходили с задержкой в 5 секунд.
Так вот мы тогда потупили с ребятами и подумали, ну мол, в продуктовый код это впихивать стремно пока, а делать отдельные учения – это надо работать. Так что, взвесив все эти экономические показатели, мы отказались делать что-то еще.
Но! Но! Память об этой штуке всплыла недавно вот в этом О-ХУ-И-ТЕЛЬ-НОМ репозитории https://github.com/bjartnes/bounded-disturbances
Что это за репозиторий такой? Это полноценный готовый к запуску курс по обучению ресайленсу! Если вы каждый раз, как и я тупите, когда думаете о том сколько ретраев вам надо впихнуть в какой-либо запрос. Или просто вы не знаете ничего про Polly, то этот репозиторий это ваш абсолютный БРО!
📶 В нем есть 10 быстрых задач, в которых вам дают ненадежный канал (настроенный как раз с помощью Simmy), дают прометей и задачу – с помощью правильных настроек ресайленса (кол-ва ретраев и правил таймаута) добиться заданного SLO!
И это прям максимально прикладная задача! Это как лабы в универе, если бы все преподы в нем вылечились от маразма!
🅰️ Итого: Быстро берите эту репу, скачивайте проходите все 10 занятий и становитесь богом ресайленса! 👼 Вы никогда больше не будете смотреть на вашего httpClient'a прежними глазами, только ресайленс, только усиление!
P.S.: Ну и въебите звезду этой штуке! Давайте. Это всего лишь клик, а авторам это будет приятно!
#ресайленс
Расскажу сейчас про охуенную штуку для изучения ресайленса!
Год назад я думал, как нам заятнуть на работу Chaos Testing. Ничего особо не получилось. Но! Удалось посмотреть такую штуку как Simmy https://github.com/Polly-Contrib/Simmy.
Simmy это версия Polly из темной всеенной 🌚. Если в Polly вы настраиваете все так чтобы у вас ничего не упало по итогу, то в Simmy вы настраиваете рандомные падения так, чтобы все деградировало каждый раз по-разному, но чтобы эти деградации выглядели реалистично. (
💆 Я если честно не допер, как в итоге это применить в работе. Подумал, что пока туповат. Потом посидели с чуваками на работе, потупили в код этой штуки. Он выглядит кстати вот так:
var isEnabled = true;
var chaosPolicy = MonkeyPolicy.InjectLatency(with =>
with.Latency(TimeSpan.FromSeconds(5))
.InjectionRate(0.1)
.Enabled(isEnabled)
);
В этом коде делается так чтобы 10% ваших запросов проходили с задержкой в 5 секунд.
Так вот мы тогда потупили с ребятами и подумали, ну мол, в продуктовый код это впихивать стремно пока, а делать отдельные учения – это надо работать. Так что, взвесив все эти экономические показатели, мы отказались делать что-то еще.
Но! Но! Память об этой штуке всплыла недавно вот в этом О-ХУ-И-ТЕЛЬ-НОМ репозитории https://github.com/bjartnes/bounded-disturbances
Что это за репозиторий такой? Это полноценный готовый к запуску курс по обучению ресайленсу! Если вы каждый раз, как и я тупите, когда думаете о том сколько ретраев вам надо впихнуть в какой-либо запрос. Или просто вы не знаете ничего про Polly, то этот репозиторий это ваш абсолютный БРО!
📶 В нем есть 10 быстрых задач, в которых вам дают ненадежный канал (настроенный как раз с помощью Simmy), дают прометей и задачу – с помощью правильных настроек ресайленса (кол-ва ретраев и правил таймаута) добиться заданного SLO!
И это прям максимально прикладная задача! Это как лабы в универе, если бы все преподы в нем вылечились от маразма!
🅰️ Итого: Быстро берите эту репу, скачивайте проходите все 10 занятий и становитесь богом ресайленса! 👼 Вы никогда больше не будете смотреть на вашего httpClient'a прежними глазами, только ресайленс, только усиление!
P.S.: Ну и въебите звезду этой штуке! Давайте. Это всего лишь клик, а авторам это будет приятно!
#ресайленс
👍2
🕐Задачка: Увеличиваем надежность канала с помощью ретраев.
Окай, я на сотку готов поспорить, что хрена с два вы пойдете смотреть репозиторий из прошлого поста. Да я бы и сам подзабил, будем солидарны в этом.🦥
Но раз уж Магомед не идет к ресайленсу, то я принесу ему ресайленс сам. В виде серии микрозадачек.
Итак первая микро-ЗАДача. РазминОЧКА, так сказать:
💡 Условие: У вас есть нестабильный кАНАЛ (ладно, обещаю, что таких КАЛамбуров больше не будет), который падает в q = 15% случаев.
Ну то есть вы обращаетесь в своем коде к какому-то сервису, и в 15% случаев он возвращает ошибку (Internal Server Error).
❓Вопрос: Сколько ретраев минимально нужно сделать при обращении к этому сервису, чтобы обеспечить успех работоспособности вашего кода в > 99%?
✅ Ответ тут (сразу скажу, что итоговая формула простая, но путь к ней надо будет вспомнить):
Вспоминаем формулу Бернулли:
Pn(k)=Ckn⋅pk⋅(1−p)n−k=Ckn⋅pk⋅qn−k.
Ckn=n!/(n−k)!⋅k!. -считается вот так
В ней надо много считать факториалы и это скучно, но не стоит бояться, потому что в чистом виде эта формула не нужна.
После всех упрощений и с учетом, что нам необходимо всего одно попадание она превращается в простую: 1 - q^n , где q - это процент ошибок, а n - количество ретраев.
Итого:
Для одного ретрая вероятность успеха: 1 - 0.15^2 = 0.9775 - маловато будет!
Делаем два: P = 1 - 0.15^3 = 0.9966 - уже подходит!
Попробуем три: P = 1 - 0.15^4 = 0.9995 - ого, аж три девятки! Если ваш SLA нацелен на такое количество девяток, то выбирайте большее!
Но минимально необходимое количество ретраев будет: 2
#ресайленс
Окай, я на сотку готов поспорить, что хрена с два вы пойдете смотреть репозиторий из прошлого поста. Да я бы и сам подзабил, будем солидарны в этом.🦥
Но раз уж Магомед не идет к ресайленсу, то я принесу ему ресайленс сам. В виде серии микрозадачек.
Итак первая микро-ЗАДача. РазминОЧКА, так сказать:
💡 Условие: У вас есть нестабильный кАНАЛ (ладно, обещаю, что таких КАЛамбуров больше не будет), который падает в q = 15% случаев.
Ну то есть вы обращаетесь в своем коде к какому-то сервису, и в 15% случаев он возвращает ошибку (Internal Server Error).
❓Вопрос: Сколько ретраев минимально нужно сделать при обращении к этому сервису, чтобы обеспечить успех работоспособности вашего кода в > 99%?
✅ Ответ тут (сразу скажу, что итоговая формула простая, но путь к ней надо будет вспомнить):
Pn(k)=Ckn⋅pk⋅(1−p)n−k=Ckn⋅pk⋅qn−k.
Ckn=n!/(n−k)!⋅k!. -считается вот так
В ней надо много считать факториалы и это скучно, но не стоит бояться, потому что в чистом виде эта формула не нужна.
После всех упрощений и с учетом, что нам необходимо всего одно попадание она превращается в простую:
Итого:
Для одного ретрая вероятность успеха: 1 - 0.15^2 = 0.9775
Делаем два: P = 1 - 0.15^3 = 0.9966
Попробуем три: P = 1 - 0.15^4 = 0.9995 - ого, аж три девятки! Если ваш SLA нацелен на такое количество девяток, то выбирайте большее!
Но минимально необходимое количество ретраев будет: 2
#ресайленс
❤3
⏲ Задача 2: улучшаем latency своего сервиса с помощью таймаутов
Во второй задаче у нас есть запрос, который в 10% случаев выдает высокую задержку в 1 секунду.
❓Вопрос: Какой максимальный таймаут нам нужно выставить для этого запроса, чтобы обеспечить latncy нашего метода в пределах 200 мс на 95-ом перцентиле? При этом процентом успешности выполнения можно пренебречь.
✅ Ответ тут (на этот раз без тервера):
По первой прикидке тут все просто – таймаут в 200мс нам точно даст требуемое значение. И это правильное предположение! Но лучше взять с запасом, к примеру в 180 мс. Практика показывает что теоретические значения при столкновении с реальностью являются лишь опорой, а не точными параметрами.
Ну все же, напоследок ложечку тервера. Если вы знаете функцию плотности распределения вероятности для latency сервиса, то сможете посчитать среднеквадратическое отклонение (она же сигма) и уже по нему определить теоретический таймаут, который будет давать вам оптимальное соотношение времени задержек к успешности запроса.
#ресайленс
Во второй задаче у нас есть запрос, который в 10% случаев выдает высокую задержку в 1 секунду.
❓Вопрос: Какой максимальный таймаут нам нужно выставить для этого запроса, чтобы обеспечить latncy нашего метода в пределах 200 мс на 95-ом перцентиле? При этом процентом успешности выполнения можно пренебречь.
✅ Ответ тут (на этот раз без тервера):
Ну все же, напоследок ложечку тервера. Если вы знаете функцию плотности распределения вероятности для latency сервиса, то сможете посчитать среднеквадратическое отклонение (она же сигма) и уже по нему определить теоретический таймаут, который будет давать вам оптимальное соотношение времени задержек к успешности запроса.
#ресайленс
🤯1