Search
Write a publication
Pull to refresh
44
0
Березников Алексей @gdt

Разработчик C#

Send message

Смысл в том, что в случае с REST мы не вызываем методы явно, а работаем с ресурсами. Естественно, на каком-то уровне какой-то код своим запросом мы выполним, но в случае REST нам неважно, что делает этот код, до тех пор, пока он выполняет нужные нам операции с ресурсами. Например, это может быть какой-то API сервис заметок - где мы будем создавать заметки, обновлять заметки, получать их и удалять, типа такого:

  1. GET /notes

  2. GET /notes/{id}

  3. PUT /notes/{id} (или POST /notes)

  4. PATCH /notes/{id}

  5. DELETE /notes/{id}

Т е наш API не даёт нам возможность вызвать какую-то процедуру, давая нам вместо этого возможность работать с ресурсами. В случае с RPC можно было бы сделать какой-то такой API:

  1. POST /getAllNotes

  2. POST /getNoteById

  3. POST /createNote

  4. POST /updateNote

  5. POST /deleteNote

Т е мы своими вызовами явно выполняем какие-то конкретные действия. Теперь мы можем сделать то, что обычно в REST не делается, например:

  • POST /backupNotes - такой метод мог бы сделать бэкап заметок, и отправить его куда-нибудь

  • POST /emailNote - типа отправить заметку на почту

  • POST /printNote - распечатать заметку

И так далее. Конечно, для работы с ресурсами (как заметки) - REST подходит намного лучше, даже выглядит как-то красивее и лаконичнее.

Я бы не стал приравнивать REST к RPC. REST вроде как больше ориентирован на работу с данными (CRUD операции по сути - создать / получить / обновить / удалить что-то), в то время как RPC - это именно удалённый вызов какой-то логики, любой. REST работает с ресурсами, в то время как RPC - с действиями, которые можно выполнять. Вроде как они даже в каком-то роде противоставляются друг другу - см. например вики - https://ru.wikipedia.org/wiki/REST):

REST является альтернативой RPC

Например, gRPC можно использовать для поднятия RPC канала локально, между приложением и сервисом, на одной машине. Чтобы REST для таких целей использовали - ни разу не видел.

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

Тут есть нюансы. Во-первых, детерминированность чего? Во-вторых, ну замокаю я сервисы вью модели, проверю, что по нажатию кнопки что-то где-то вызвалось. Что на самом деле мне даёт такой тест? У нас в команде не идиоты работают, + qa, так что, вероятность того, что кто-то уберёт этот вызов по нажатию кнопки, крайне мала. Опять же, интеграционные тесты не пройдут после такого, так что qa даже билд не получит с такой проблемой. Зато, после рефакторинга, придётся ещё и этот бесполезный тест менять.

Интересный подход, но как по мне выглядит некрасиво. Мы у себя начали писать больше интеграционных тестов - они на самом деле покрывают бизнес логику так, как её видит бизнес, и дают хороший coverage. Unit тесты оставили только для каких-то часто используемых примитивов, типа своих observable collections или чего-то многопоточного, где на самом деле есть неочевидные граничные условия, которые необходимо покрывать. Вот после этого стало проще и интереснее.

Кампания героев была хорошей игрой для своего времени, но вот чтобы прямо топ-20 - крайне сомнительно

Существует три проблемы программирования:

  • Именование переменных

  • Инвалидация кэшей

  • Групповые операции в плейлистах

Я вот тоже думал, что это шутка такая, а вы по сути что-то такое и утверждаете

Зачем нам надо обращать внимание на то, кто вызывает функцию Thread.Start

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

ну не равно, а что дальше то

Божественная аргументация :) Не думал, что это потребует дополнительных объяснений. Вот, например, есть у вас автомобиль, и вы его используете. У него есть двигатель. Верно ли будет сказать, что вы != двигатель, или вы несогласны? Вот, например, есть ДВС, а есть электродвигатель. ДВС загрязняет окружающую среду. Правда ли то, что если у вас есть автомобиль, вы загрязняете окружающую среду? А если там электродвигатель? А если он просто в гараже стоит?

Я честно говоря думал, что мысль крайне простая и доступная.

Пока не вижу, опять же, что, на практике, зависит от того, считаем мы, что асинхронный код может создавать потоки, или выносим эту функцию на какой-то другой уровень, чем отличается аренда потока от создания

Серьёзно? Вы не видите разницы между арендой потока и созданием? :)

получается, что вы просто хотите проигнорировать эту функциональность, типа: вот тут у меня асинхронный код, а все остальное меня не интересует

Это не совсем так работает. Это называется абстракция и декомпозиция - вот у нас есть контекст синхронизации (это абстракция), он будет отвечать за детали логики выполнения continuation'ов. И да, с точки зрения асинхронного кода то, как это будет происходить - я могу проигнорировать, так же, как это осознанно сделали разработчики .NET. Это значительно упрощает разработку.

Мне кажется, у нас с вами разное представление о том, что такое "асинхронный код" и что значит "создает потоки".

Код, который создает потоки - это код, который явно делает Thread.Start. Создание потоков, кстати, это относительно ресурсоёмкая операция, да и память отжирает понемногу.

Асинхронный код - это какой-то код внутри асинхронного метода с асинхронными вызовами (await), раскладываемый компилятором на стейт-машину.

Так вот, если вы явно не вызываете Thread.Start в своем асинхронном коде - он потоков не создает. Контекст может создавать новые потоки или переиспользовать в ходе выполнения асинхронного метода. Но контекст != асинхронный код. И то, что в каких-то случаях асинхронный код может использовать такой контекст, совершенно не обозначает, что асинхронный код создает потоки.

Не создает асинхронный код потоки :)

Грубо говоря, асинхронный метод делится на части и превращается в некоторую стейт машину. Можно сказать, что разделение проходит по await'ам. Т е до первого await'а выполнение происходит синхронно, затем стейт-машина эти кусочки (continuation'ы) по очереди шедулит в synchronization context.

В вашем случае, используется дефолтный контекст, который шедулит continuation'ы на потоки из тред-пула. Более того, вы не await'ите первый вызов, т е делаете fire and forget - глупо ожидать, что две параллельные задачи в таком контексте начнут выполняться на одном потоке.

То есть, эти потоки они уже есть в наличии, и их использование дефолтным контекстом вполне оправданно.

Что касается контекстов UI - ну, во-первых, название метода вообще ни о чем не говорит. Во-вторых, добавьте .ConfigureAwait(false) и получите немалый шанс того, что после этого await'а поток поменяется. Не потому, что кто-то создал новый поток. Просто для continuation'а может быть использован другой контекст - тот же дефолтный, на тред пуле.

fasm вроде как и в x86-64 умеет тоже

У меня стойкое ощущение, что этот комментарий был ответом на что-то другое :)

Тем не менее. Совсем неясно, о каких табличках идет речь. enum в C# в целом используется точно так же, как и в других языках, где он есть. Значение по умолчанию для enum работает точно так же, как и для примитивных типов. Только если вы не путаете enum и Enum, который в чистом виде никто не использует.

По-моему Visual Studio имеет community edition и в ней можно писать в том числе и на C.

А можно подробнее про Norton Commander?

https://github.com/dnSpyEx/dnSpy вот такое не пробовали использовать?

Интересный подход, облегчаете задачу критикам. Однако, оригинал и перевод ничем визуально не отличаются, это усложняет чтение. Было бы круто оригинал выделить визуально как-то (например, курсивом) или убрать под спойлер. То же самое касается выделения слов, сильно пестрит - я уверен есть способ, который меньше бросается в глаза.

И все же интересно, как правильно - мультипроцессор или многопроцессор? У вас встречаются оба термина. А перейдя по ссылке в начале статьи увидел "Драйвер уровень" вместо "Уровень драйвера". Думаю в целом с переводами есть еще над чем поработать.

Для заметок действительно подходит Google Keep, для простого планирования и списков задач TickTick бесплатной версии за глаза

Да нет у меня никакого презрительного отношения, с чего вы это взяли. Каждому разработчику нужен редактор, чтобы редактировать какие-то отдельно взятые файлы (xml, json, или вот GH Actions) - в моем случае, это Notepad++, кто-то в моей команде использует VS Code, кто-то Sublime и т. д. - и это нормально и вопросов здесь никаких нет. Каждому инструменту своя область применения.

Но я пока что-то не вижу чтобы кто-то всерьёз делал крупные C# проекты на VS Code - с нормальным GUI, чтобы 100+ проектов было в солюшне и так далее. Почему-то все используют для этого VS или Rider, загадка правда?

Насколько я понимаю, ваш опыт в этом вопросе исходит из сравнения WebStorm и VS Code в плане разработки на js/ts. Вот честно, на js/ts +- можно хоть в блокноте писать, особенно на js. Так что вполне допускаю, что IDE для js не дает какого-то вау эффекта :)

Information

Rating
6,509-th
Location
Кемерово, Кемеровская обл., Россия
Date of birth
Registered
Activity

Specialization

Software Developer
Senior
C#
.NET
Software development
Object-oriented design
Multiple thread
Git
WPF