Почему вы так полагаете? Человек утверждает что версия с шаблоном никогда не вызывается, я наоборот привел примеры когда это происходит. Что снова не так? :)
Когда примеры кода в текст вставляют в виде картинок -- это, с моей точки зрения, прямое неуважение к читателю.
Ну это же были не те примеры, которые есть смысл собирать и что-то менять в них. Это скорее иллюстрация описываемой проблемы. Реализация и примеры использования приводятся в конце статьи как ссылки - там можно "пощупать" реальный код.
Что и было сделано в мягкой форме.
Страшно представить как вы это делаете в жесткой форме :) бедный монитор.
За обилие смайлов в ответных комментариях еще одна порция оных.
Смайлами точно не хотел оскорбить, наоборот даже. И вы это... не изойдите совсем на эту субстанцию, оставьте немного для других авторов :)
Еще одно доказательство для тех, кто сомневается в адекватности подобной системы отбора.
Так вы еще и HR специалист оказывается, а как же нужно делать, по вашему мнению?
Ну понятно: есть два мнения -- одно из них мое, второе неправильное.
Есть много мнений: с какими-то соглашаешься с какими-то нет, а у вас только два? Или это вы за меня решили порассуждать? :)
Можно принять это несовпадение к сведению
Как я уже говрил, тут вопрос к коррктности подачи замечания. Одно дело когда человек вежливо обращает внимание на недостатки в статье - с ним может завязаться конструктивный диалог и совсем другое когда сразу начинают писать про "поносные лучи" :) диалог получается из этой же серии.
Так и мы не на ученом совете. Если уж в комментариях в Интернете не использовать мемы из этого самого Интернета, то зачем тогда комментарии нужны вообще? Вопрос риторический. Суть же в том, что вы не на страницах научного реферируемого издания публикуетесь.
Не на совете, но и не в подростковом чате :) мем мему рознь.
Интересно, интересно. Вот этот поворот!Может мне еще нужно и денежку куда-то занести, за то, что вы здесь статью опубликовали и снизошли до того, чтобы донести до темных и лапотников результаты своих изысканий?
Ну я имел в виду, что претензия это когда вы купили что-то или заплатили за услугу, а товар или услуга в реузльтате не отвечает вашим ожиданием. Я же вам ничего не продвал :)
А то ведь пока не компенсирую вам ваши затраты, у меня нет никаких прав на критику.
Да ладно вам :) адекватную конструктивную критику интересно послушать.
Вам бы задуматься: а зачем это мне? Ну вот зачем мне нужно, чтобы вы к моему мнению прислушались?
Ну я же написал: если хотите чтобы к нему прислушались. Зачем вам это знать не могу - чужая голова потемки, как говориться :) Но зачем то же вы продолжаете писать эти портянки? Видимо зачем-то нужно :)
Я-то, по наивности, полагал, что обратная связь в первую очередь нужна автору статьи. Но, видимо, сильно ошибался.
Нужна, но уже не раз писал, что важна не только сама обратная связь, но и форма ее подачи. Вам бы тоже задуматься над этим, а не повторять из сообщения в собщение какой вы исключительно вежливый :)
PS. Если позволите, нескромный вопрос: а в Kaspersky Lab вы попали обычным образом -- через серию собеседований, включая знание языка, алгоритмическую секцию и т.д.?
Да, пожалуйста. Все верно так и проходил. У меня тогда тоже нескромный встречный вопрос: а вы случайно не состоите на учете в ПНД? :)
Косяк? А вы вообще читали что там написано? :) В чем по вашему заключается косяк? Человек в строке 27 явно вызывает версию метода view без шаблона: `v.view([] (int i) -> int {`
Если попробовать присвоить возвращаемое значение переменной код перестанет компилироваться: `auto d = v.view([](int i) -> int {` Потому что вызывается версия view без шаблона, которая возвращает void.
Если нужно возвращать, например, int нужно пользоваться версией view с шаблоном: `auto d = v.view([](int i) -> int {`
Тут даже коментировать особо нечего, думал человек сам осознает :)
Так это зависит от субъективной оценки - в моем понимании кликабельный, в вашем кликбейт.
В том и суть: заголовок претендует на что-то серьезное, а по факту получается такое себе.
Опять же ваша субъективная оценка.
Вы, похоже, никогда не слышали выражения "посылать лучи поноса"
Дело не в том слышал или нет, просто не считаю это уместным и корректным для высказывания замечания.
Если суть претензии
Претензии вправе высказывать заказчик или покупатель, вы же можете лишь озвучивать свое частное мнение и желательно в вежливой и корректной форме, если, конечно, хотите чтобы к нему прислушались.
Можно и дальше считать меня идиотом
Ну если говорить серьезно, идиотом я вас не считаю - технические комментарии вполне адекватные.
Уверяю вас, что все замечания, которые вы не смогли адекватно воспринять, были сделаны в максимально корректной форме.
"лучи поноса" не адекватно воспринял? Ну уж извините :)
Как я уже написал выше, класс SharedState полностью работоспособный и покрыт UT. Напильником ее дорабатывать не нужно, но можно при желании, потому что совершенству не предела :)
Так вроде как раз подходит: объединяем все зависимые переменные в одну структуру, запрашиваем у SharedState доступ к этой структуре на запись и согласованно вносим необходимые изменения.
Rust хорош тем, что гарантирует отсутствие состояния гонок для успешно скомпилированного кода, но от дедлоков не спасет. Да и разработчик не всегда волен использовать тот ЯП, который ему нравится.
Во-первых, напрямую обращаться к полям чужого класса это нарушение инкапсуляции и лучше так не делать :) Во-вторых, нужно понять что имеется в виду под "объект живет в нити". Нить это независисмый поток выполнения, и объекты "жить" в нем не могут. Но, например, в Qt при создании объекта запоминается идентификатор нити, в котором он был создан и при динамическом связывании через слоты-сигналы не допускаются прямые вызовы из разных нитей. Благодаря этому можно писать код как в однопоточном режиме, не прибегая к синхронизации. Обычно в документации к публичному интерфейсу класса пишут являются ли его методы потокобезопасными или нет. Если да, значит можно спокойно дергать его методы из разных нитей, если же нет, а вам нужно использовать этот класс в многопоточной среде, придется самостоятельно продумать возможные проблемы синхронизации и добиться атомарности вызовов методов, которые не являются потокобезопасными.
Код вполне рабочий, покрытый UT и демонстрирует концепцию. Но исследований на производительность между std::function и предложенным вами вариантом я не проводил, поэтому окончательное решение будет за потенциальным пользователем, который уже решит что ему лучше подходит для "боевого" кода.
b) "серебрянной пули" нигде не обещал, вы это сами себе придумали, видимо, из-за упомянутого здесь нестандартного воcприятия реальности :)
> А я уже и не сомневаюсь что вы откровенно не умны и не умеете воспринимать информацию. Ну значит у нас взаимно такое мнение сложилось :) только помимо всего прочего вы еще откровенно невежливы, впредь, пожалуйста, воздержитесь от оценочных суждений такого рода.
> Потому что, во-первых, вам прямо было сказано, что на ваш дурацкий вопрос следует такой же дурацкий ответ. Да согласен, ответ действительно дурацкий и излишне самоуверенный, отчего выглядит довольно глупо :)
> Вы же этот дурацкий ответ воспринимаете всерьез. Да нет же, с чего вы взяли? :) Ну как можно всерьез отвечать собеседнику, который пишет ХЗ что про лучи и какие-то субстанции? :)
> Я не говорил о полезности статьи вообще. "Благодарность" была высказана исключительно за примеры кода в виде картинок. Да я понял, конечно же :) Тут был вопрос к корректности высказывания своих замечаний к статье.
> Про Kaspersky OS можно и не беспокоится. Она явно в надежных руках. А вы почитайте на досуге про KasperskyOS - скептицизма сразу поубавится :)
Код демонстрирует распространенную проблему, а не создает ее. Причем здесь RAII? Проблема владения ресурсом здесь не затрагивалась, поэтому и нарушить этот принцип никак не могли :) Да вы не беспокойтесь насчет будущего KasperskyOS - не вы же один такой уникальный специалист по микроядерным архитектурам :)
В Rust-е наоборот общие данные "живут" внутри мьютекса. Но то что вы описываете скорее можно назвать мутатором. На мой взгляд, такой поход более опасный чем лямбда т.к. если сохранить где-нибудь мутатор исходный объект останется залоченным. С лямбдами такие риски меньше. Но если нравится такой подход можно посмотреть в сторону Boost Synchronized Value или Folly Synchronized - там это реализовано, в конце статьи писал об этом.
Предлагаю Оккама оставить в покое и посчитать на пальцах сущности до и после: были mutex, lock guard и condition variable + защищаемые данные, стало SharedState + защищаемые данные, которые могут быть отдельной структурой/классом или просто строкой, например. Т.е. мы уменьшили общее количество сущностей, которыми вынуждены были манипулировать и получили одну новую абстракцию, которая объединяет общие данные со средствами их защиты. А правила всегда будут чем бы вы не пользовались :)
Любой класс с двумя шаблонами N и K может сгенерировать N * K вариантов, если видите в этом проблему, тогда конечно, видимо, лучше не пользоваться шаблонными классами :)
Гонками обычно называют ситуации когда два потока "на перегонки" одновременно меняют общие данные и в итоге приводят их в несогласованное состояние. При правильном использовании мьютексов или как здесь предлагается SharedState вместо них, гонки как раз исключаются.
Писать код "не думая" не думал даже рекомендовать - вы, видимо, как-то превратно трактуете прочитанное :)
А где вы увидели мьютексы в публичном API - они наоборот спрятаны внутри SharedState, который тоже совсем необязательно светить в публичном API, это скорее предполагается как часть внутренней реализации.
Подход решает проблему доступа к общим данным из разных потоков, что может пригодиться для распараллеливания. Хотя, безусловно, если есть возможность распараллелить без использования общих данных, то и данный подход не пригодится.
Почему вы так полагаете? Человек утверждает что версия с шаблоном никогда не вызывается, я наоборот привел примеры когда это происходит. Что снова не так? :)
Ну это же были не те примеры, которые есть смысл собирать и что-то менять в них. Это скорее иллюстрация описываемой проблемы. Реализация и примеры использования приводятся в конце статьи как ссылки - там можно "пощупать" реальный код.
Страшно представить как вы это делаете в жесткой форме :) бедный монитор.
Смайлами точно не хотел оскорбить, наоборот даже. И вы это... не изойдите совсем на эту субстанцию, оставьте немного для других авторов :)
Так вы еще и HR специалист оказывается, а как же нужно делать, по вашему мнению?
Если нужно возвращать, например, int нужно пользоваться версией view с шаблоном:`auto d = v.view<int>([](int i) -> int {`
Есть много мнений: с какими-то соглашаешься с какими-то нет, а у вас только два? Или это вы за меня решили порассуждать? :)
Как я уже говрил, тут вопрос к коррктности подачи замечания. Одно дело когда человек вежливо обращает внимание на недостатки в статье - с ним может завязаться конструктивный диалог и совсем другое когда сразу начинают писать про "поносные лучи" :) диалог получается из этой же серии.
Не на совете, но и не в подростковом чате :) мем мему рознь.
Ну я имел в виду, что претензия это когда вы купили что-то или заплатили за услугу, а товар или услуга в реузльтате не отвечает вашим ожиданием. Я же вам ничего не продвал :)
Да ладно вам :) адекватную конструктивную критику интересно послушать.
Ну я же написал: если хотите чтобы к нему прислушались. Зачем вам это знать не могу - чужая голова потемки, как говориться :) Но зачем то же вы продолжаете писать эти портянки? Видимо зачем-то нужно :)
Нужна, но уже не раз писал, что важна не только сама обратная связь, но и форма ее подачи. Вам бы тоже задуматься над этим, а не повторять из сообщения в собщение какой вы исключительно вежливый :)
Да, пожалуйста. Все верно так и проходил. У меня тогда тоже нескромный встречный вопрос: а вы случайно не состоите на учете в ПНД? :)
Косяк? А вы вообще читали что там написано? :) В чем по вашему заключается косяк?
Человек в строке 27 явно вызывает версию метода view без шаблона:
`v.view([] (int i) -> int {`
Если попробовать присвоить возвращаемое значение переменной код перестанет компилироваться:
`auto d = v.view([](int i) -> int {`
Потому что вызывается версия view без шаблона, которая возвращает void.
Если нужно возвращать, например, int нужно пользоваться версией view с шаблоном:
`auto d = v.view([](int i) -> int {`
Тут даже коментировать особо нечего, думал человек сам осознает :)
Так это зависит от субъективной оценки - в моем понимании кликабельный, в вашем кликбейт.
Опять же ваша субъективная оценка.
Дело не в том слышал или нет, просто не считаю это уместным и корректным для высказывания замечания.
Претензии вправе высказывать заказчик или покупатель, вы же можете лишь озвучивать свое частное мнение и желательно в вежливой и корректной форме, если, конечно, хотите чтобы к нему прислушались.
Ну если говорить серьезно, идиотом я вас не считаю - технические комментарии вполне адекватные.
"лучи поноса" не адекватно воспринял? Ну уж извините :)
Как я уже написал выше, класс SharedState полностью работоспособный и покрыт UT. Напильником ее дорабатывать не нужно, но можно при желании, потому что совершенству не предела :)
Так вроде как раз подходит: объединяем все зависимые переменные в одну структуру, запрашиваем у SharedState доступ к этой структуре на запись и согласованно вносим необходимые изменения.
Rust хорош тем, что гарантирует отсутствие состояния гонок для успешно скомпилированного кода, но от дедлоков не спасет. Да и разработчик не всегда волен использовать тот ЯП, который ему нравится.
Во-первых, напрямую обращаться к полям чужого класса это нарушение инкапсуляции и лучше так не делать :)
Во-вторых, нужно понять что имеется в виду под "объект живет в нити". Нить это независисмый поток выполнения, и объекты "жить" в нем не могут. Но, например, в Qt при создании объекта запоминается идентификатор нити, в котором он был создан и при динамическом связывании через слоты-сигналы не допускаются прямые вызовы из разных нитей. Благодаря этому можно писать код как в однопоточном режиме, не прибегая к синхронизации.
Обычно в документации к публичному интерфейсу класса пишут являются ли его методы потокобезопасными или нет. Если да, значит можно спокойно дергать его методы из разных нитей, если же нет, а вам нужно использовать этот класс в многопоточной среде, придется самостоятельно продумать возможные проблемы синхронизации и добиться атомарности вызовов методов, которые не являются потокобезопасными.
Код вполне рабочий, покрытый UT и демонстрирует концепцию. Но исследований на производительность между
std::function
и предложенным вами вариантом я не проводил, поэтому окончательное решение будет за потенциальным пользователем, который уже решит что ему лучше подходит для "боевого" кода.a) название статьи должно быть кликабельным
b) "серебрянной пули" нигде не обещал, вы это сами себе придумали, видимо, из-за упомянутого здесь нестандартного воcприятия реальности :)
> А я уже и не сомневаюсь что вы откровенно не умны и не умеете воспринимать информацию.
Ну значит у нас взаимно такое мнение сложилось :) только помимо всего прочего вы еще откровенно невежливы, впредь, пожалуйста, воздержитесь от оценочных суждений такого рода.
> Потому что, во-первых, вам прямо было сказано, что на ваш дурацкий вопрос следует такой же дурацкий ответ.
Да согласен, ответ действительно дурацкий и излишне самоуверенный, отчего выглядит довольно глупо :)
> Вы же этот дурацкий ответ воспринимаете всерьез.
Да нет же, с чего вы взяли? :) Ну как можно всерьез отвечать собеседнику, который пишет ХЗ что про лучи и какие-то субстанции? :)
> Я не говорил о полезности статьи вообще. "Благодарность" была высказана исключительно за примеры кода в виде картинок.
Да я понял, конечно же :) Тут был вопрос к корректности высказывания своих замечаний к статье.
> Про Kaspersky OS можно и не беспокоится. Она явно в надежных руках.
А вы почитайте на досуге про KasperskyOS - скептицизма сразу поубавится :)
Код демонстрирует распространенную проблему, а не создает ее. Причем здесь RAII? Проблема владения ресурсом здесь не затрагивалась, поэтому и нарушить этот принцип никак не могли :)
Да вы не беспокойтесь насчет будущего KasperskyOS - не вы же один такой уникальный специалист по микроядерным архитектурам :)
Ценю ваш сарказм :) ответил выше.
В Rust-е наоборот общие данные "живут" внутри мьютекса. Но то что вы описываете скорее можно назвать мутатором. На мой взгляд, такой поход более опасный чем лямбда т.к. если сохранить где-нибудь мутатор исходный объект останется залоченным. С лямбдами такие риски меньше. Но если нравится такой подход можно посмотреть в сторону Boost Synchronized Value или Folly Synchronized - там это реализовано, в конце статьи писал об этом.
Предлагаю Оккама оставить в покое и посчитать на пальцах сущности до и после: были mutex, lock guard и condition variable + защищаемые данные, стало SharedState + защищаемые данные, которые могут быть отдельной структурой/классом или просто строкой, например. Т.е. мы уменьшили общее количество сущностей, которыми вынуждены были манипулировать и получили одну новую абстракцию, которая объединяет общие данные со средствами их защиты. А правила всегда будут чем бы вы не пользовались :)
В статье писал почему так - просто для наглядности, чтобы сразу было видно сигнатуры. В боевом коде, безусловно, лучше сделать как у вас.
Любой класс с двумя шаблонами N и K может сгенерировать N * K вариантов, если видите в этом проблему, тогда конечно, видимо, лучше не пользоваться шаблонными классами :)
Гонками обычно называют ситуации когда два потока "на перегонки" одновременно меняют общие данные и в итоге приводят их в несогласованное состояние. При правильном использовании мьютексов или как здесь предлагается SharedState вместо них, гонки как раз исключаются.
Писать код "не думая" не думал даже рекомендовать - вы, видимо, как-то превратно трактуете прочитанное :)
А где вы увидели мьютексы в публичном API - они наоборот спрятаны внутри SharedState, который тоже совсем необязательно светить в публичном API, это скорее предполагается как часть внутренней реализации.
Насчет "чертовщины", пожалуйста, в церковь :)
Подход решает проблему доступа к общим данным из разных потоков, что может пригодиться для распараллеливания. Хотя, безусловно, если есть возможность распараллелить без использования общих данных, то и данный подход не пригодится.
Ну это скорее вопросы к реализации Streams, которые могут повлиять на ваше решение использовать его или нет.