Как стать автором
Обновить
30
0.5
Валерий @mvv-rus

Ненастоящий программист

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

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

PS А кому прямо так нужен аналог Promise в C#, то для этого есть TaskCompletionSource. Но это уже другая история.

Просто неудачно выразил мысль - слишком сократил. Если говорить точнее (и длиннее), то в ContinueWith передается делегат, не возвращающий результатата (либо делегат, возвращающий результат задачи, а не задачу, но, в любом случае - выполняющийся синхронно), а в then - функция, возвращающая promise.

Против этого возражения будут?

С чего бы цепочка then должна быть эквивалентной вложенным ContinueWith? Это во-первых.

Возражение справедливое, хотя IMHO тут начать надо (причем - не комментарий, а саму статью) с того, что метод then в JS семантически не эквивалентен методу ContinueWith в.NET даже когда ои используются внешне одинаково - ровно с одним параметром и даже если проигнорировать для простоты условия продолжения и считать, что все завершается нормально. Потому что через этот параметр передаются сущности разного типа: в then - promise, т.е. задача, а в ContinueWith - делегат, т.е. код который будет выполняться в задаче (а уж ContinueWith обернет его в задачу).

Вообще в данной статье случай рассмотрен простейший: параметр для ContinueWith поменять несложно, т.к. код соответствующих делегатов доступен. А потому я сильно сомневаюсь, что ее вообще стоило переводить. А к чему это приводит и как с этим бороться в разных более сложных случаях, например, когда доступен только Task, а не делегат, который им выполняется - это уже совсем другая история, и в комментарии ее я рассказать не берусь.

PS Поубирал минусы, которые вы тут друг другу понаставили: не по делу они IMHO.

Интереснее результат можно получить если удалить ключ из словаря.

Причем, возможно - если удалить совсем другой ключ;-). Вы не посмотрели когда туда лазили, не открытая ли адресация там используется?

Этот функционал предназначен для взаимодействия с кодом, выполняющимся не под управлением .NET. И находится там же, где всё подобное - в System.InteropServices.

В обычном (управляемом) коде .NET его лучше не использовать - как например и указатели, ровно по тем же причинам: unsafe.

Для корпоративного рынка примерно так. Есть, правда, нюанс - какой софт считаь плохим (по науке это - асимметрия информации), но пока что бог с ним.

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

Спорить дальше совсем не хочу, только пару вещей отмечу.

  1. Капитализм - это не только рынок, но и частная собственность на средства производства. А это уже не столь универсальная штука. С понятиями африканских племен, к примеру, не сочетается - там делиться надо. И со Средневековьем европейским - тоже очень посредственно: к примеру, право распоряжаться землей там было обставлено кучей условий. А отсюда - и другая психология. К примеру, психология тех же участников Крестовых походов (да и рыцарского сословия вообще - для которого честь была дороже любых денег) нашему современнику далеко не органична. Но это, особенно весь массив связанных с этим знаний - оно опять-таки далеко за пределами тематики Хабра.

  2. Плевать на других получается не всегда. К примеру, при "первобытном коммунизме" (родово-племенном строе) - не получается: на индивида, коли он против понятий пойдет, там наплюют так, что мало не покажется. А в одиночку там не проживешь - съедят или сам с голоду помрешь.

никто не будет правила вырабатывать, капитализм это не выдуманный конструкт, это буквально суть человечества которую немного огородили правилами и законами чтобы люди друг друга не перегрызли

Капитализм - это способ управления общественным производством. На текущий момент - оптимальный, но так было не всегда и не факт что так будет всегда начиная с настоящего момента.

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

Но это все - уже философия (конкретно - материалистическое понимание истории). Не думаю, что на Хабре это можно и нужно всерьез обсуждать.

IMHO - нет. А пару глав можно написать в следующей статье.

Одно из первых моих воспоминаний о проблемах вычислительной техники - это когда я, будучи студентом на ЕС-1045, захотел поиграть в Star Trek, и для этого вечерком переключил proclib - подсмотрев, как это делают инженеры и системщики, тоже большие любители погонять клингонов. А обратно - не переключил, в результате вся ночная пачка заданий не выполнилась. Мне повезло - обошлось без телег в деканат, всего лишь лишили на пару месяцев машинного времени. Но в полную изоляцию чего-либо на компьютерах я с тех пор верить опасаюсь.

Микросервисы решают (как кажется) ещё одну серьезную, хоть и не техническую, проблему: разбиение единой организации, ведущей разработку, на практически независимые друг от друга группы. Такое разбиение сильно уменьшает потребность в качестве управления и квалификации управленцев. А хороший управленец для большой организации - товар не менее эксклюзивный, чем хороший разработчик. Именно поэтому, полагаю, микросервисы столь популярны у менеджмента.

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

Понимая как реализовано в С++, почти без заглядывания под капот С#, понимаешь как оно там всё устроено.

Не всегда. В C++, насколько я помню, традиционно было плохо с информацией о типах во время выполнения (может, в последних стандартах и улучшили, не знаю, я лично не прошел дальше C++ 2003), а в C# эта информация практически полная. И это позволяет работать с классами, которые не были известны на момент компиляции.
Типичный (хотя сейчас и несколько устаревший) пример - Startup-класс в ASP.NET Core web-приложении, сделанном по шаблону Generic Host: этот класс может отыскиваеться кодом библиотеки (заранее скомпилированным) в рантайме по его имени и может даже быть разным для разных окружений (development/staging/production) и не обязан при этом содержать все потенциально вызываемые кодом библиотеки методы (к примеру, ConfigureContainer там бывал нечасто AFAIK, ибо нужен он только при использовании сторонних DI-контейнеров).

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

Три раза был свидетелем, как программисту МК предлагали напарника, помощника, а тот говорил:

А программисту напарник вовсе не нужен. Взаимодействие с другим программистом - это дополнительные сложности, всегда. А то, что результат получается медленнее - это не забота программиста. Программист в результате не заинтересован чисто объективно: ему деньги за процесс труда плятят, а не за результат. Реально, заинтересованные лица тут - владельцы бизнеса и их представители - менеджеры.

А по факту проблема в том, что без TDD (Test Driven Development) совместная разработка реально не работает

Как это: везде - работает, а при программировании микроконтроллеров - нет? Что это такая специфика именно для микроконтроллеров? В своей области я что-то такого не замечал, что без TDD никак. Вполне программировал совместно ещё в те времена, когда о TDD и слыхом не слыхали. Правда, не для микроконтроллеров, а для десктопов, на Delphi.

Неужели для микроконтроллеров нельзя найти способ организации разработки подешевле? Не знаю, как там у вас в микроконтроллерах, а я тут вот развликаюсь написанием чисто самодельной библиотеки (Middleware для ASP.NET Core) в соответствии с наилучшими практиками: могу себе позволить, потому что надо мной погонщик с кнутом не стоит. Так вот для этой библиотеки полное покрытие тестами (xUnit+Moq+VS 2022) - это примерно раза в два больше кода, чем в самой библиотеке. Причем, это - с максимальным выносом общего для тестов кода в общие классы и методы тестового проекта. Я понимаю, конечно, что код библиотеки - он не простой, там куча асинхронщины и параллельщины, которую как раз и проверять надо, а тестов - наоборот простой: там копипасты с мелкими правками много. Но даже если кода требуется не в три, а в два раза больше - это IMHO дорого, слишком.

А в реальной разработке для микроконтроллеров и без TDD явно есть чего улучшать. Вон, вчера сын принес с работы историю про смежников-эмбедщиков. Он сам не эбедщик вообще-то, но с их изделиями ему приходится работать, и плотно. Суть истории: смежники сделали для них железку, и она в целом работает стабильно, но тут доработки потребовались. А с этим оказалось сложно, потому что смежники начали чинить то, что не сломалось - добавили (чисто в прошивку в новую) какую-то не особо нужнуую фичу (вроде как, со слов - запись логов в флеш-память). После чего железка через полсуток работы стала виснуть. Казалось бы, нет ничего проще - вернтуься к стабильной версии и танцевать от нее - ан нет: исходники стабильной версии продолбаны. Потому что CVS/SVN/Git/Mercurial смежники ниасилили. А вы говорите - TDD!

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

Некоторые сомнительные рекомендации:

Очевидно, вклад в чужой репозиторий требует прочтения чужого кода, что само по себе учит новому.

Есть такое новое, которому лучше не учиться. Пример - да прямо там рядом на картинке. После того, как в C# появились автоматические свойства (auto property) - уже больше 10 лет как ЕМНИП - совершенно незачем для реализации доступа к полю/свойству только для чтения приделывать ещё и теневую переменную. Да и до того незачем было городить две реализации: оптимизация путем замены свойства полем выгляит явно сомнительной и, скорее всего, преждевременной: метод получения свойства чтение поля почти наверняка будет встроен в код по месту. И, кстати, давать примеры кода лучше не картинкой а вставкой кода.

Рас ты хочешь внести изменения в чужой код, значит это… Рефакторинг! Отличный способ попрактиковаться в этом направлении. Приятное с полезным.

  • Видишь повторяющиеся строки кода? Вынеси в отдельный метод.

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

Вежливость, конструктивность помогут тебе.

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

Вы точно не запутались в том, что вы хотите мне доказать? А то я вас прошу "указать где написано про вызов, содержащий только один запрос" в некоей фразе , а вы мне стремитесь доказать, что вообще " К вызову, содержащему только один запрос, эта фраза относиться не может". Ну, если так, то я даже обсуждать это ваше доказательство не буду - самого по себе признания моей правоты мне хватит.

Или вы что-то другое хотели написать?

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

Я уже не знаю, по буквам что-ли разбирать?

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

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

Если в вызове больше одного запроса, даже если они только на чтение, то не установка Transactional может привести к неконсистентности данных при любом уровне изоляции. С этим согласны?

С этим я и не спорил, я с самого начала говорил про одну тразакцию на несколько запросов, и даже пример про это привел. И что с того?

А как его еще понимать?

Я же написал. Читайте.

Если не поставить Transactional на вызов, содержащий несколько запросов...

А если поставить (да ещё и бездумно, как говорил автор обсуждаемого комментария)? Прямо "над методом где выполняется несколько SQL запросов на чтение " (цитата из оригинального, до правки, варианта статьи)? Такой вариант прочтения вам в голову не приходил?

Так что предлагаю не заниматься тут герменевтикой, а подождать, что скажет автор обсуждаемого комментария.

Вы, похоже, не так поняли утверждение (не свосем однозначное, да) , однако сразу кинулись его опровергать. А я вот так понял, что утверждавший имел в виду вызов метода с несколькими запросами на чтение к БД внутри него - а в этом сценарии уровень изоляции имеет значение.

Ну, для вас такая безапелляционность - это норма. А вот я пока что, прежде чем спорить дальше, попробую подождать уточнения от @martin_wanderer

последующие запросы могут считать запись зафиксированную до завершения предыдущих запросов.

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

И ЕМНИП оно реально неверно (было, в те давние времена) для конкретного Interbase 4. Тамошняя приблуда для интерактивной работы с БД - wisql.exe - при посылке первого же запроса открывала транзакцию (с изоляцией формально, если по тогдашним стандартам - REPEATBLE READ, но по жизни это был снимок, в Interbase была многоверсионная схема хранения), и сидела в ней, пока транзакцию явно не завершишь. В результате при отладке прогаммы на Delphi можно было внезапно не увидеть в wisql сделанное программой и зафиксированное изменение, потому что час назад в wisql был сделан и забыт запрос к совершенно другой таблице, а транзакция так и осталась висеть.

Информация

В рейтинге
1 614-й
Зарегистрирован
Активность