Вовсе нет. Вы для них не настолько важная персона, что первая линия поддержки известила их отдел соцсетей службы пиара, чтобы они вообще смогли увязать публикацию этой статьи с какой-то там перепиской.
По очень простой причине. Первая линия настолько загружена обращениями пользователей, что они намеренно это всё автоматизируют и в лучшем случае записывают самые интересные случаи куда-нибудь в беклог. Авось раз в квартал набежит менеджер и сделает обзор. В противном случае менеджеры поддержки не могли бы заснуть от распухшей головы в заботах о юзерах.
Думаете, от хорошей жизни там роботы с футболом?
А вот научить первую линию отличать рутинное от критического - это важная задача. И сделать это можно, к сожалению, исключительно через голову службы поддержки.
Поэтому хватит жеманничать. ИМЯ КОМПАНИИ - В СТУДИЮ. Иначе Яндекс будет думать, что вы ломились в Сбер, Сбер - что во Вкусно-И-Точку, а Вкусно-и-Точка - в шавермачечную на вокзале.
Конечно, если желание узнать состояние асинхронной задачи (запускаем - запустили - отменили - закончили с отменой - закончили без отмены) входит в ТЗ, то реализация несколько усложнится.
Но тут мы встанем на очень скользкую дорожку конкурентного выполнения. Когда информация о статусе будет зависеть от моментов, когда мы этот статус спрашиваем и параллельно изменяем.
Поэтому - а насколько часто нам это в коде нужно? Может быть, "выстрелил и забыл" тоже подойдёт?
Меня не покидает чувство, что вы только что переизобрели std::promise/future/async. Да ещё и с довольно странным дизайном, в котором у вас есть явные владельцы и всё такое.
Имхо, надо было отталкиваться от описания задачи, а не от допиливания фич к существующему первичному коду. Причём замечу, что если с самого начала взять фьючерсы, то оперировать тредами вообще не придётся. (Они там будут под капотом).
Итак, хочется
асинхронную функцию, которая как-то сама может проверять флажок остановки
частный случай - функцию, которая делает это в цикле, собранном из условия и тела
Ну окей. Договоримся, что в первом случае это void(atomic_bool& /*stop*/)
Второй делается из первого нехитрым образом:
auto make_async_while_loop(auto precondition, auto body) {
return [=](atomic_bool& stop) {
while(!stop && precondition()) { body(); }
};
}
auto make_async_do_while_loop(auto body, auto postcondition) {
return [=](atomic_bool& stop) {
while(!stop && postcondition(body())) {}
}
}
Если body само по себе длинная операция - ну окей, переделать на body(stop)
Всё. Теперь нам нужна сущность, у которой есть две ручки: cancel и wait. Первая посылает команду остановки (мгновенно), вторая - ждёт завершения, какое бы оно ни было.
Я бы посоветовал сперва скомпилировать код, прежде чем вставлять его в статью... Потому что он с ошибками.
bool StopFunc() // метод для её остановки
{
if (!FuncThread && !FuncStatus)
return false;
FuncStatus = false;
if (FuncThread.joinable()) FuncThread.join(); // не . а ->
if (FuncThread) delete FuncThread; // delete не нуждается в проверке на nullptr
FuncThread = nullptr;
return true;
}
bool FuncStatus() { return FuncStatus; } // два члена с одним именем
private:
thread* FuncThread; // (лишняя косвенность)
Я думаю, что надо открытым текстом назвать компанию, чья служба поддержки так беспомощно и НАОТШИБИСЬ прореагировала на сообщение о критической проблеме. Потому что это входит в систему. И пока менеджерам самого верхнего уровня не настучат по шапке за антипиар, которого они добились и заслужили, - на первой и второй линиях поддержки (а то и на нулевой, с этими чёртовыми роботами) ничего не изменится.
Описуемые числа - это числа, которые можно (не обязательно уникально) задать некоторой конечной нотацией, - например, математической формулой или программой на любом языке программирования.
Например, конечные десятичные числа включают в себя множество целых и подмножество рациональных (среди рациональных есть бесконечные десятичные).
Десятичные числа со специальной нотацией ЦЕЛАЯ_ЧАСТЬ , КОНЕЧНАЯ_ДРОБЬ ( ПЕРИОД ) неуникально охватывают все рациональные числа. Неуникально - потому что периоды из девяток равны единице в предыдущий разряд и вырожденному периоду из нулей. То есть, 1,23(9) = 1,23(99) = 1,24.
Алгебраические числа - корни многочленов. Это не только рациональные, но и иррациональные числа. И как мы знаем, для многочленов 5 и более высоких степеней мы даже не всегда можем записать это в виде арифметических формул, дополненных знаком корня целой степени... Но тем не менее, эти числа (неуникально) определяются в виде "вот коэффициенты многочлена, а вот порядковый номер его корня". Если коэффициенты рациональные, номер натуральный, то кортежи таких чисел образуют счётное множество. Поэтому, хоть множество алгебраических чисел и шире, чем рациональных (включает их), но оно по-прежнему счётно.
Трансцедентные числа - то есть, не алгебраические. Вот тут дело обстоит интереснее. Да, очевидно, что вещественные числа - это континуум, а трансцедентные = вещественные \ алгебраические, континуум минус счётность = континуум. Пусть и всюду дырявый.
Однако, если мы попробуем описать любое трансцедентное число... ну, какие у нас есть средства? Именованные константы наподобие пи, е, гаммы там всякой. Именованные функции наподобие синуса, куда подставляем константы и числовые литералы. Безымянные ряды с формулой для члена. Интегралы-неберучки с формулой для подынтегрального выражения. И тому подобное.
А все ли трансцедентные числа можно так описать? А давайте посчитаем!
Пусть у нас есть некоторый язык формул. (И неважно, насколько он формальный - то есть, насколько мы где-то отдельно записали его синтаксис и семантику). Формулы конечной длины из символов конечного алфавита. Образуют множество строк... мощностью... ПРАВИЛЬНО! Счётное!!!
И вот что получилось. Описуемые числа - это счётное множество, которое включает в себя
целые (конечные цепочки цифр и знака)
рациональные (конечные цепочки цифр, знака, разделителей целой части и периода)
алгебраические (инструкции "реши-ка мне вот такое уровнение с многочленом")
некоторые трансцедентные (формулы произвольной громоздкости)
Но мы-то знаем, что всего вещественных чисел - континуум...
СЛЕДОВАТЕЛЬНО: существует континуум (везде дырявый) неописуемых чисел, - подмножество трансцедентных.
И - нет, не пытайтесь найти неописуемое число. Каждая такая попытка, если будет успешной, просто добавит ещё одно число в жалкую счётность описуемых, а континуум без этой штуки останется континуумом.
Плохие аналогии подобны котёнку с дверцей. Куда пошлёт вас нанятый вами, ЖЭКом, сантехник, когда вы предложите ему купить себе весь инструмент самостоятельно, хоть ключи хоть плоскогубцы.
И вы ещё не распробовали ценность удалённой виртуальной машины. Сколько ядер и мозгов доступно вам на вашем ноутбуке, и сколько - на ферме. Сколько нервов потратили интеграторы, чтобы у всех разработчиков были одинаковые версии компиляторов и библиотек. Как часто делаете бэкап вы на своём ноутбуке, по сравнению с виртуалкой.
Ну мы же вроде договорились, что задача без заподлянок в виде 11 адресов, отличающихся в единственной компоненте.
Смысл выбора пробы по наиболее равномерному распределению размеров классов - в том, чтобы как можно сильнее сузить пространство в самом худшем случае. И неважно, этот худший случай "не совпало ничего" или "совпало 3 из 5". А не выбирать такую пробу, у которой именно класс "не совпало ничего" самый большой.
В принципе, можно запустить моделирование. Взяли какую-то стратегию и применили её ко всем 100 адресам. Если вписались в ограничение в 10 попыток, - это дерево решений считаем удачным. Если для каких-то веток дерево слишком высокое, то находим узел, из которого растут высокие ветки, и делаем в нём другую пробу (следующую по предпочтению в нашей стратегии). И убеждаемся, разумеется, что классы эквивалентности там получаются другие, иначе смысла нет менять шило на мыло. Да, в худшем случае это NP-полная задача.
(немножко накосячил: результат пробы - это величина, противоположная расстоянию Хэмминга, то есть, "5" соответствует расстоянию 0, все компоненты равны)
Пусть у нас есть метрика d(a,b) - расстояние Хэмминга между двумя адресами-кортежами.
Изначально множество адресов S состоит из всех 100 штук.
Для каждого адреса a из S строим табличку: H[a][m] = {b : d(a,b) = m}
Выбираем такой адрес a1, для которого разбиение на классы эквивалентности по расстоянию до него наиболее равномерно. (Ну понятно, что для любого a, H[a][5] = {a}, поэтому этот класс мы учитывать не будем).
Для каждого адреса из S (не из S1) снова строим табличку H1[a][m] = {b in S1 : d(a,b) = m}. Проще говоря, оставляем в классах в H только те, что лежат в S1. Ключами по-прежнему являются все адреса.
Опять же, выбираем такой a2, для которого разбиение на классы в H1 наиболее равномерно.
Пусть у нас первые четыре компоненты - по 10 уникальных значений, а пятая - все 100 (сквозная нумерация всех адресов). Четыре компоненты задают 4-значные десятичные числа, то есть, там возможна 1000 вариантов. Но чисел всего 100 штук.
Любой запрос даст нам либо ответ "5" (полное совпадение), либо - от 0 до 3. Ответ "4" не может быть, так как это означало бы, что либо пятая компонента совпала, а какая-то другая нет, либо четыре первых совпали, а пятая нет, то есть, сломана сквозная нумерация.
Поэтому пятую компоненту можно просто исключить из рассмотрения, и свести задачу к "угадай 4-значный адрес".
Предположим, что "угадай 5-значный адрес (строго десятичный) за 10 попыток" - заведомо решаемая задача. В таком случае берём наши 4-значные адреса и добавляем к ним хаотично пятые цифры. Мы свели задачу к известной. Следовательно, "угадай 4-значный адрес" также заведомо решаемая.
Следовательно, существуют наборы адресов со 100 уникальными квартирами, для которых решение всё ещё есть.
Если адреса с точностью до дома уникальны - решение (видимо) есть
Если адрес с точностью до дома одинаков для всех - решения точно нет
Эти две границы можно, наверное, ещё как-то сузить.
тогда очень похоже - 1230, 1800, 1810 этих саженей = 2274, 3341, 3346 метров "приблизительно"
Вовсе нет. Вы для них не настолько важная персона, что первая линия поддержки известила их отдел соцсетей службы пиара, чтобы они вообще смогли увязать публикацию этой статьи с какой-то там перепиской.
По очень простой причине. Первая линия настолько загружена обращениями пользователей, что они намеренно это всё автоматизируют и в лучшем случае записывают самые интересные случаи куда-нибудь в беклог. Авось раз в квартал набежит менеджер и сделает обзор. В противном случае менеджеры поддержки не могли бы заснуть от распухшей головы в заботах о юзерах.
Думаете, от хорошей жизни там роботы с футболом?
А вот научить первую линию отличать рутинное от критического - это важная задача. И сделать это можно, к сожалению, исключительно через голову службы поддержки.
Поэтому хватит жеманничать. ИМЯ КОМПАНИИ - В СТУДИЮ. Иначе Яндекс будет думать, что вы ломились в Сбер, Сбер - что во Вкусно-И-Точку, а Вкусно-и-Точка - в шавермачечную на вокзале.
что происходит при краже браслета?
Конечно, если желание узнать состояние асинхронной задачи (запускаем - запустили - отменили - закончили с отменой - закончили без отмены) входит в ТЗ, то реализация несколько усложнится.
Но тут мы встанем на очень скользкую дорожку конкурентного выполнения. Когда информация о статусе будет зависеть от моментов, когда мы этот статус спрашиваем и параллельно изменяем.
Поэтому - а насколько часто нам это в коде нужно? Может быть, "выстрелил и забыл" тоже подойдёт?
Меня не покидает чувство, что вы только что переизобрели std::promise/future/async. Да ещё и с довольно странным дизайном, в котором у вас есть явные владельцы и всё такое.
Имхо, надо было отталкиваться от описания задачи, а не от допиливания фич к существующему первичному коду. Причём замечу, что если с самого начала взять фьючерсы, то оперировать тредами вообще не придётся. (Они там будут под капотом).
Итак, хочется
асинхронную функцию, которая как-то сама может проверять флажок остановки
частный случай - функцию, которая делает это в цикле, собранном из условия и тела
Ну окей. Договоримся, что в первом случае это
void(atomic_bool& /*stop*/)
Второй делается из первого нехитрым образом:
Если body само по себе длинная операция - ну окей, переделать на
body(stop)
Всё. Теперь нам нужна сущность, у которой есть две ручки: cancel и wait. Первая посылает команду остановки (мгновенно), вторая - ждёт завершения, какое бы оно ни было.
Конечно же, нам хотелось бы семантики перемещения хотя бы. Но для этого есть пимпл.
Я бы посоветовал сперва скомпилировать код, прежде чем вставлять его в статью... Потому что он с ошибками.
предлагаете бизнесу размещать свои офисы у вас в датацентрах?
Я думаю, что надо открытым текстом назвать компанию, чья служба поддержки так беспомощно и НАОТШИБИСЬ прореагировала на сообщение о критической проблеме. Потому что это входит в систему. И пока менеджерам самого верхнего уровня не настучат по шапке за антипиар, которого они добились и заслужили, - на первой и второй линиях поддержки (а то и на нулевой, с этими чёртовыми роботами) ничего не изменится.
Это не говнокод, а ху_ня какая-то.
Подкину смежный пример.
Описуемые числа - это числа, которые можно (не обязательно уникально) задать некоторой конечной нотацией, - например, математической формулой или программой на любом языке программирования.
Например, конечные десятичные числа включают в себя множество целых и подмножество рациональных (среди рациональных есть бесконечные десятичные).
Десятичные числа со специальной нотацией ЦЕЛАЯ_ЧАСТЬ , КОНЕЧНАЯ_ДРОБЬ ( ПЕРИОД ) неуникально охватывают все рациональные числа. Неуникально - потому что периоды из девяток равны единице в предыдущий разряд и вырожденному периоду из нулей. То есть, 1,23(9) = 1,23(99) = 1,24.
Алгебраические числа - корни многочленов. Это не только рациональные, но и иррациональные числа. И как мы знаем, для многочленов 5 и более высоких степеней мы даже не всегда можем записать это в виде арифметических формул, дополненных знаком корня целой степени... Но тем не менее, эти числа (неуникально) определяются в виде "вот коэффициенты многочлена, а вот порядковый номер его корня". Если коэффициенты рациональные, номер натуральный, то кортежи таких чисел образуют счётное множество. Поэтому, хоть множество алгебраических чисел и шире, чем рациональных (включает их), но оно по-прежнему счётно.
Трансцедентные числа - то есть, не алгебраические. Вот тут дело обстоит интереснее. Да, очевидно, что вещественные числа - это континуум, а трансцедентные = вещественные \ алгебраические, континуум минус счётность = континуум. Пусть и всюду дырявый.
Однако, если мы попробуем описать любое трансцедентное число... ну, какие у нас есть средства? Именованные константы наподобие пи, е, гаммы там всякой. Именованные функции наподобие синуса, куда подставляем константы и числовые литералы. Безымянные ряды с формулой для члена. Интегралы-неберучки с формулой для подынтегрального выражения. И тому подобное.
А все ли трансцедентные числа можно так описать? А давайте посчитаем!
Пусть у нас есть некоторый язык формул. (И неважно, насколько он формальный - то есть, насколько мы где-то отдельно записали его синтаксис и семантику). Формулы конечной длины из символов конечного алфавита. Образуют множество строк... мощностью... ПРАВИЛЬНО! Счётное!!!
И вот что получилось. Описуемые числа - это счётное множество, которое включает в себя
целые (конечные цепочки цифр и знака)
рациональные (конечные цепочки цифр, знака, разделителей целой части и периода)
алгебраические (инструкции "реши-ка мне вот такое уровнение с многочленом")
некоторые трансцедентные (формулы произвольной громоздкости)
Но мы-то знаем, что всего вещественных чисел - континуум...
СЛЕДОВАТЕЛЬНО: существует континуум (везде дырявый) неописуемых чисел, - подмножество трансцедентных.
И - нет, не пытайтесь найти неописуемое число. Каждая такая попытка, если будет успешной, просто добавит ещё одно число в жалкую счётность описуемых, а континуум без этой штуки останется континуумом.
Тональ и Нагваль. Живите с этим, как хотите.
Единственное, на что похоже, чтобы было "примерно" - это ровно 1.8 морской мили. В футах или ярдах получается такая же 4-5-значная фигня.
Я хз, кто меряет глубину в морских милях, но от журналистов всего можно ожидать.
Откровенные идиоты - это какая возрастная категория?
Плохие аналогии подобны котёнку с дверцей. Куда пошлёт вас нанятый вами, ЖЭКом, сантехник, когда вы предложите ему купить себе весь инструмент самостоятельно, хоть ключи хоть плоскогубцы.
И вы ещё не распробовали ценность удалённой виртуальной машины. Сколько ядер и мозгов доступно вам на вашем ноутбуке, и сколько - на ферме. Сколько нервов потратили интеграторы, чтобы у всех разработчиков были одинаковые версии компиляторов и библиотек. Как часто делаете бэкап вы на своём ноутбуке, по сравнению с виртуалкой.
Ну мы же вроде договорились, что задача без заподлянок в виде 11 адресов, отличающихся в единственной компоненте.
Смысл выбора пробы по наиболее равномерному распределению размеров классов - в том, чтобы как можно сильнее сузить пространство в самом худшем случае. И неважно, этот худший случай "не совпало ничего" или "совпало 3 из 5". А не выбирать такую пробу, у которой именно класс "не совпало ничего" самый большой.
В принципе, можно запустить моделирование. Взяли какую-то стратегию и применили её ко всем 100 адресам. Если вписались в ограничение в 10 попыток, - это дерево решений считаем удачным. Если для каких-то веток дерево слишком высокое, то находим узел, из которого растут высокие ветки, и делаем в нём другую пробу (следующую по предпочтению в нашей стратегии). И убеждаемся, разумеется, что классы эквивалентности там получаются другие, иначе смысла нет менять шило на мыло. Да, в худшем случае это NP-полная задача.
(немножко накосячил: результат пробы - это величина, противоположная расстоянию Хэмминга, то есть, "5" соответствует расстоянию 0, все компоненты равны)
Эммм... А почему бы не пойти таким путём.
Пусть у нас есть метрика d(a,b) - расстояние Хэмминга между двумя адресами-кортежами.
Изначально множество адресов S состоит из всех 100 штук.
Для каждого адреса a из S строим табличку: H[a][m] = {b : d(a,b) = m}
Выбираем такой адрес a1, для которого разбиение на классы эквивалентности по расстоянию до него наиболее равномерно. (Ну понятно, что для любого a, H[a][5] = {a}, поэтому этот класс мы учитывать не будем).
Делаем пробу a1, получаем расстояние m1, получаем подмножество S1 = H[a1][m].
Для каждого адреса из S (не из S1) снова строим табличку H1[a][m] = {b in S1 : d(a,b) = m}.
Проще говоря, оставляем в классах в H только те, что лежат в S1. Ключами по-прежнему являются все адреса.
Опять же, выбираем такой a2, для которого разбиение на классы в H1 наиболее равномерно.
Делаем пробу a2, и так далее.
Неправда. Давайте построим такой же контрпример!
Пусть у нас первые четыре компоненты - по 10 уникальных значений, а пятая - все 100 (сквозная нумерация всех адресов).
Четыре компоненты задают 4-значные десятичные числа, то есть, там возможна 1000 вариантов. Но чисел всего 100 штук.
Любой запрос даст нам либо ответ "5" (полное совпадение), либо - от 0 до 3. Ответ "4" не может быть, так как это означало бы, что либо пятая компонента совпала, а какая-то другая нет, либо четыре первых совпали, а пятая нет, то есть, сломана сквозная нумерация.
Поэтому пятую компоненту можно просто исключить из рассмотрения, и свести задачу к "угадай 4-значный адрес".
Предположим, что "угадай 5-значный адрес (строго десятичный) за 10 попыток" - заведомо решаемая задача.
В таком случае берём наши 4-значные адреса и добавляем к ним хаотично пятые цифры. Мы свели задачу к известной. Следовательно, "угадай 4-значный адрес" также заведомо решаемая.
Следовательно, существуют наборы адресов со 100 уникальными квартирами, для которых решение всё ещё есть.
Если адреса с точностью до дома уникальны - решение (видимо) есть
Если адрес с точностью до дома одинаков для всех - решения точно нет
Эти две границы можно, наверное, ещё как-то сузить.
В статье вся вёрстка кода люто яростно поехала! Что это за
pythonКопироватьРедактироватьold_events
и т.п.?Если вы кодите так же, как статьи пишете, то... ну ээээ... ожидаемо.
я в детстве крону попробовал - думал, будет как две планеты, а оказалось, как собака за язык укусила!
лакричные конфетки же.