Как стать автором
Обновить
4
0.1
Валерий Реуцкий @benjik

Пользователь

Отправить сообщение

НАКОНЕЦ-ТО!

Я так и не понял, чем это отличается от many producers/single consumer вокруг ConcurrentQueue для синхронного кода или System.Threading.Channels для асинхронного (

Вкатывал свитчера с ноября 2019 г. (37 лет на тот момент, не Россия)

Бекграунд: отучился в технаре (не IT), потом мой сокурсник в тех.вузе, НО: с 1 по 4 курс был старостой, по факту особо не учился (кроме 3-4 предметов за 5 лет) - где-то договаривался, где-то покупал, где-то списывал, где-то автоматы просто потому что староста. На 5 курсе почти всё автоматом, т.к. зачётка красивая, и заказной диплом. Язык подвешен, не тупой, усидчивый.

С 1 курса и до 2019 г. работал официантом, барменом, мясником, баристой. Решил таки вкатиться в IT и даже взял книжку по c++ - в этот момент я его убедил глянуть на javascript. Он согласился, прочёл пару статей, сходил на курс по фронтэнду со скидкой 50%, ничего не понял и расстроился. Я накидал ему ссылок на книжки, плейлисты и почти-бесплатные курсы на одном зелёном сайте, помог настроить nodejs+sublime и разобраться и гитхабом, и раз в неделю созванивались. Он сам разобрался с основами языка с небольшой помощью, решал задачки, сделал несколько базовых штук вроде светофора/todo-list и тд, потом взялся за курсы по реакту - всё это или учил вечерами, или на работе в кофейне.

К лету 2020 опубликовал резюме и начал искать любые стажировки. Нашел "что-то" за $200, где просто сидел за компом, а вокруг бегали люди и решали, какой крутой проект им делать, но ничего не делали. Ментора у него в компании не было. Так пол-года продолжал учить js/react и апплаиться на все стажировки, на которые можно. Устроился на одну, был изгнан на испытательном. Летом 2021 с ним слепили портфолио на github pages из всех эти светофоров и сделанных тестовых, нашлась ещё одна работа уже за $400 - ментора снова не было, но были задачи, их ставили относительно грамотно и по ним давали обратную связь - с этим уже можно было как-то работать.

В начале 2021 г. ЗП уже была $600, нашел другую работу джуном за $1000, но там его хотели нагрузить и react native, и angular, и какими-то модными на тот момент мобильными js-фреймворками, и он слился через 4 месяца. Причесал резюме, портфолио, и через пару месяцев устроился мидлом на $1500 - с тех пор моё менторство прекратилось, и вкат я считаю успешным.

В чём заключалось менторство? В основном - чтоб держал фокус на текущих задачах (а вот щас ангуляр попробую, а вот щас vue, а там ещё ... и тд я пресекал), и чтоб не переживал особо - ПМы с горящей жопой это хоть и не норма, но и не диковинка, HRы в разработке могут вообще не понимать, кол-во решенных задач на собесе не гарантирует оффер, бизнес сам может не значь чего хочет и т.д. Ну и несколько хитростей - например в 2020 опубликовали от его имени фейковое резюме мидла чтоб он просто посмотрел, что спрашивают на настоящих собесах - он где-то в пяти поучавствовал и понял, что нужно подтянуть и к чему быть готовым. Плюс я рассказывал ему как торговаться за ЗП/обязанности, как выяснять что происходит в команде до трудоустройства, договариваться про скоуп/сроки, отбиваться от дичи и прочее.

За счёт чего он вытянул? Я думаю в основном из-за усидчивости, настойчивости и самодисциплины - т.е. до первой нормальной стажировки он полтора года по 10-20 часов в неделю учился кодить, разбирался с технологиями, апплаился на вакансии, читал/смотрел что-то и тд. Ещё у него не было малолетних детей и он бросил пить и шабить, но это детали.

Повлиял ли ВУЗ на его успех? Думаю что нет. Разве что со мной там познакомился, и всё. Потому что я пытался вкатить ещё двух своих сокурсников, которые реально учились (один даже с дипломом с отличием), и это фейл. Один видимо забыл, как читать книги и самостоятельно усваивать информацию хотябы из видосов. У второго мотивации/фокуса хватало в неделю на пару часов, и на 8-12 таких недель, потом на пол-года отваливался.

Ну до появления этих постов с телегой в конце я пропускал 50-100 статей в день, чтоб прочесть 1-2. Теперь пропускаю 51-101, делов-то.

Если статья хорошая - читаю и иногда в телегу заглядываю (вдруг там еще есть), если не оче - пропускаю. Не вижу особых отличий от рекламных статей в корпоративных бложиках, чьих-то потоков запутанных мыслей, адаптированных курсовых/дипломных работ и просто неинтересных статей.

В этих микрообзорах линукс-ноутов нехватает информации о работе от батареи. Мой xps 9570 после покупки работал от батареи 6-8 часов на свежеустановленной винде, и 2-4 на убунте без твиков. Собственно, линукс ставится почти на любой современный ноут, а вот как он батарейкой пользуется - обычно большой сюрприз.

Крутая штука!

Жаль, что репозиторий уже больше года не обновляется 😢

Это у вас прошлогодняя статья из черновиков, с вкраплениями свежего макбука?

Почти все модели с intel-процами уже есть с 13 поколением.

  1. Не "я не понимаю проблему", а вы её не можете правильно сформулировать. Я прошу MyServiceProvider создать мне класс Client1, как-то самостоятельно выбрать для него реализацию IFoo и подставить её в конструктор клиенту, с чем он прекрасно справляется. Так же точно, в конструктор контроллера подставится ровно то, что я укажу в GetService. А настройки для GetService я могу прочитать хоть из .txt, хоть из БД, хоть из ChatGPT.

  2. Вы хотите странного, и хотите этого от Microsoft. Они уже сделали достаточно абстракций и точек расширения: не устраивает родной DI - используйте ninject/autofac/lightinject/etc или пишите свой.

Нет такого условия в задаче (во всяком случае, на момент написания комментария).

Если не хочется менять классы-клиенты, то можно реализовать собственный IServiceProvider.GetService(Type serviceType), который всё это делает, и подменить им нативный:

вот так
void Main()
{
    var builder = Host.CreateDefaultBuilder();
    builder.UseServiceProviderFactory(new MyServiceProviderFactory());
    builder.ConfigureServices(services =>
    {
        services.AddTransient<IFoo, DefaultFoo>();
        services.AddTransient<Foo1>();
        services.AddTransient<Foo2>();
        services.AddTransient<Client1>();
        services.AddTransient<Client2>();
    });

    var provider = builder.Build().Services;

    var client1 = provider.GetRequiredService<Client1>();
    var client2 = provider.GetRequiredService<Client2>();
    IFoo defaultFoo = provider.GetRequiredService<IFoo>();
    defaultFoo.Bar();
}

public class MyServiceProvider : IServiceProvider
{
    private readonly ServiceProvider _nativeServiceProvider;
    public MyServiceProvider(ServiceProvider sp)
    {
        _nativeServiceProvider = sp;
    }

    public object GetService(Type serviceType)
    {
        return serviceType switch
        {
            Type _ when serviceType == typeof(Client1) =>
                ActivatorUtilities.CreateInstance(_nativeServiceProvider, serviceType, _nativeServiceProvider.GetRequiredService<Foo1>()),
            Type _ when serviceType == typeof(Client2) =>
                ActivatorUtilities.CreateInstance(_nativeServiceProvider, serviceType, _nativeServiceProvider.GetRequiredService<Foo2>()),
            _ => _nativeServiceProvider.GetRequiredService(serviceType)
        };
    }
}

public class MyContainerBuilder
{
    public IServiceCollection Services { get; set; }
    public IServiceProvider ServiceProvider => new MyServiceProvider(Services.BuildServiceProvider());
}

public class MyServiceProviderFactory : IServiceProviderFactory<MyContainerBuilder>
{
    public MyContainerBuilder CreateBuilder(IServiceCollection services)
    {
        return new MyContainerBuilder { Services = services };
    }

    public IServiceProvider CreateServiceProvider(MyContainerBuilder containerBuilder)
    {
        return containerBuilder.ServiceProvider;
    }
}

public interface IFoo
{
    void Bar();
}

public class DefaultFoo : IFoo
{
    public void Bar() => Console.WriteLine(nameof(DefaultFoo));
}

public class Foo1 : IFoo
{
    public void Bar() => Console.WriteLine(nameof(Foo1));
}

public class Foo2 : IFoo
{
    public void Bar() => Console.WriteLine(nameof(Foo2));
}

public class Client1
{
    public Client1(IFoo foo)
    {
        Console.WriteLine(nameof(Client1));
        foo.Bar();
    }
}

public class Client2
{
    public Client2(IFoo foo)
    {
        Console.WriteLine(nameof(Client2));
        foo.Bar();
    }
}

Client1
Foo1
Client2
Foo2
DefaultFoo

Вариаций множество, под любые требования любых заказчиков, поэтому нет смысла тащить такое в стандартную библиотеку. Я уверен, что в большинстве крупных проектов подобные велосипеды есть в достатке.

Например так:

void Main()
{
    var services = new ServiceCollection();
    services.AddTransient<DefaultFoo>();
    services.AddTransient<Foo1>();
    services.AddTransient<Foo2>();
    services.AddSingleton<FooFactory>();
    services.AddTransient<Client1>();
    services.AddTransient<Client2>();
    var provider = services.BuildServiceProvider();
    
    var client1 = provider.GetRequiredService<Client1>();
    var client2 = provider.GetRequiredService<Client2>();
    IFoo defaultFoo = provider.GetRequiredService<FooFactory>().GetFoo(null);
    defaultFoo.Bar();
}

public interface IFoo
{
    void Bar();
}

public class DefaultFoo : IFoo
{
    public void Bar() => Console.WriteLine(nameof(DefaultFoo));
}

public class Foo1 : IFoo
{
    public void Bar() => Console.WriteLine(nameof(Foo1));
}

public class Foo2 : IFoo
{
    public void Bar() => Console.WriteLine(nameof(Foo2));
}

public class FooFactory
{
    private readonly IServiceProvider _sp;
    public FooFactory(IServiceProvider sp) => _sp = sp;
    public IFoo GetFoo(object client)
    {
        return client switch
        {
            Client1 => _sp.GetRequiredService<Foo1>(),
            Client2 => _sp.GetRequiredService<Foo2>(),
            _ => _sp.GetRequiredService<DefaultFoo>()
        };
    }
}

public class Client1
{
    public Client1(FooFactory fooFactory)
    {
        Console.WriteLine(nameof(Client1));
        IFoo foo = fooFactory.GetFoo(this);
        foo.Bar();
    }
}

public class Client2
{
    public Client2(FooFactory fooFactory)
    {
        Console.WriteLine(nameof(Client2));
        IFoo foo = fooFactory.GetFoo(this);
        foo.Bar();
    }
}
Client1
Foo1
Client2
Foo2
DefaultFoo

Для Microsoft DI это давно решается маленькими самописными фабриками, которые настраиваются как душе угодно - хоть передачей типа запрашивающего, хоть передачей enum-ключа для выбора нужной реализации.

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

$ winget install -e --id Docker.DockerDesktop
$ docker run --name mysql \
   -p 3306:3306 \
   -e MYSQL_ROOT_PASSWORD=<secret-password> \
   --restart unless-stopped \
   -d mysql:8
  1. ...

  2. PROFIT!

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

Вот инструмент, который решает твою задачу достаточно хорошо. Зачем тратить время на А и Б, когда задача уже решена, и скорее всего был опыт с В и Г в прошлом, отмели Д и Е по каким-то причинам, а Ж была на проекте раньше, и с неё долго и мучительно съезжали?
У архитекторов (не 23-летних) обычно и без этого хватает работы.
Про стеснение вообще не понял - зачем стесняться того, что ты чего-то не знаешь или не смотрел?

Альтернативное название статьи: "За что бить по рукам на Code Review"

Пять лет учишь матан, линал, тервер, матстат, алгоритмы, машоб, распределёнщину, функциональщину.
Два года настраиваешь шрифты в 1С,меняешь картриджи в принтере и предлагаешь выключить и включить.

Адекватные (и объективные) процессы оценки:

  • Мониторить стоимость найма сотрудника (или сотрудников) с аналогичным скиллсетом в данную конкретную контору в данный конкретный проект (а не в среднем по рынку) и стоимость его онбординга. Да, надо собесить людей. Да, первые 1-3-6 месяцев (иногда и больше) он может не приносить особой пользы. Очень дорого, но относительно надёжно и предсказуемо.

  • Смотреть, с каким оффером от условных конкурентов приходит увольняться/просить повышения ваш сотрудник. Дёшево, но внезапно и ненадёжно.

Адекватный процесс мотивации (только денежной):

  • Платить что-то между цифрами из первого и второго процессов оценки.

Т.е. если термины "незаменимость" (или "заменимость") поменять на термин "стоимость замены" - всё становится гораздо проще и для компании, и для сотрудника.

Естественно, всё это работает, если обстановка в компании относительно адекватная. Токсичность, бардак, микро/чайка-менеджмент, задержки ЗП и прочее веселье - и сотрудники будут уходить "в никуда".

На прошлой работе в моей и в соседней командах делали UI для админок продакшн-систем на Blazor+Telerik. В .net 5.0 им уже вполне можно было пользоваться, сейчас (.net 7.0) стало еще лучше.
Выбирали не потому что wasm, а чтобы относительно простой UI мог сделать дотнетчик без привлечения реакто-фронтов.

Информация

В рейтинге
3 112-й
Откуда
Москва, Москва и Московская обл., Россия
Дата рождения
Зарегистрирован
Активность