В этой статье мы подробно разберем понятие сопрограмм (coroutines), их классификацию, детально рассмотрим реализацию, допущения и компромиссы, предлагаемые новым стандартом C++20.
Пользователь
Как экономисты потеряли веру в разумность людей и научились их понимать

Многие научные открытия, когда они уже сделаны, кажутся очевидными. Настолько очевидными, что сложно себе представить, как это ученые могли быть настолько глупыми, чтобы когда-то считать иначе. Пожалуй, в экономической теории чаще других такое недоумение вызывает область, исследующая то, как люди принимают решения – поведенческая экономика. Я изучаю поведенческую экономику и отклонения от рационального поведения последние семь лет – началось всё с дипломного проекта, а в прошлом году исследования в этой области принесли мне кандидатскую степень по экономике. Когда я рассказываю интересующимся друзьям, что только в ХХ веке экономисты стали говорить, что человек, оказывается, не всегда рационален, да еще и не использует для совершения выбора всю возможную информацию, они начинают со скепсисом коситься на экономистов-классиков. Мол, серьезно, мистер Адам Смит? Ты думал, что, когда я молоко покупаю в Пятерочке, я матрицу решений строю, включая туда цены по всем розничным магазинам города?
Бывают ложные белые грибы, у амебы есть ложноножки, а такое отношение к экономистам я называю феноменом ложноглупых классиков. Кстати, частично он тоже объясняется когнитивных искажением, одним из тех, которые изучает современная поведенческая экономика: «мудростью задним числом» (hindsight bias). Однако в первую очередь он связан с той особенностью развития экономической науки, которая отличает ее от естественных наук вроде физики. Об этой особенности экономической теории и о том, как так получилось, что до ХХ века одной из ее самых прочных основ была предпосылка о рациональном и эгоистичном экономическом человеке, и почему в ХХ веке её вдруг решили пересмотреть, я и расскажу сегодня.
Случайный трамвай посреди незнакомого города

Есть одна довольно любопытная задачка, она уже давно вошла в математический фольклор, а так же стала излюбленным испытанием на собеседованиях. Ее условия просты, а решение, кажется напрашивается само собой, однако не будем торопиться с выводами. Берите карандаш, чистый лист бумаги, усаживайтесь поудобней и давайте во всем разбираться.
В чем же, собственно, задача
Итак представьте, что Вы приехали в абсолютно незнакомый город и первый трамвай, который вам там повстречался, следовал под номером 17. Как оценить, сколько всего в этом городе трамвайных маршрутов?
Для простоты считайте, что трамвайные маршруты в городе пронумерованы без пропусков числами от 1 до N и изначально каждое из этих чисел с равными шансами могло оказаться номером трамвая, который вы бы увидели первым.
std::atomic. Модель памяти C++ в примерах
Для написания эффективных и корректных многопоточных приложений очень важно знать какие существуют механизмы синхронизации памяти между потоками исполнения, какие гарантии предоставляют элементы многопоточного программирования, такие как мьютекс, join потока и другие. Особенно это касается модели памяти C++, которая была создана сложной таковой, чтобы обеспечивать оптимальный многопоточный код под множество архитектур процессоров. Кстати, язык программирования Rust, будучи построенным на LLVM, использует модель памяти такую же, как в C++. Поэтому материал в этой статье будет полезен программистам на обоих языках. Но все примеры будут на языке C++. Я буду рассказывать про std::atomic, std::memory_order и на каких трех слонах стоят атомики.
Как заставить код выполняться за одинаковое время? Способы от Яндекс.Контеста
int main()
{
int n = 500000000;
int *a = new int[n + 1];
for (int i = 0; i <= n; i++)
a[i] = i;
for (int i = 2; i * i <= n; i++)
{
if (a[i]) {
for (int j = i*i; j <= n; j += i) {
a[j] = 0;
}
}
}
delete[] a;
return 0;
}
Уязвимости в коде. Как отличить опасную брешь от незначительной ошибки?
Что касается ложных срабатываний, здесь все просто: можно взять и посмотреть непосредственно те места кода, где обнаружены уязвимости с подозрением на false positive. Действительно, какая-то их часть может оказаться ложными срабатываниями, (хотя явно не половина от общего числа).
А вот о том, что критично, а что нет, хотелось бы поговорить более предметно. Если вы понимаете, почему сейчас уже нельзя использовать SHA-1 и зачем экранировать «;», возможно, эта статья не откроет вам чего-то нового. Но если по итогам сканирования от найденных уязвимостей рябит в глазах, добро пожаловать под кат – расскажем, какие «дыры» чаще всего встречаются в мобильных и веб-приложениях, как они работают, как их исправить, а главное — как понять, что перед вами — опасная брешь или незначительная ошибка в коде.

Совершенный цикл for
Сегодня необычный для меня формат статьи: я скорее задаю вопрос залу, нежели делюсь готовым рецептом. Впрочем, для инициирования дискуссии рецепт тоже предлагаю. Итак, сегодня мы поговорим о чувстве прекрасного.
Я довольно давно пишу код, и так вышло, что практически всегда на C++. Даже и не могу прикинуть, сколько раз я написал подобную конструкцию:
for (int i=0; i<size; i++) {
[...]
}
Хотя почему не могу, очень даже могу:
find . \( -name \*.h -o -name \*.cpp \) -exec grep -H "for (" {} \; | wc -l
43641
Наш текущий проект содержит 43 тысячи циклов. Проект пилю не я один, но команда маленькая и проект у меня не первый (и, надеюсь, не последний), так что в качестве грубой оценки пойдёт. А насколько такая запись цикла for
хороша? Ведь на самом деле, важно даже не то количество раз, когда я цикл написал, а то количество раз, когда я цикл прочитал (см. отладка и code review). А тут речь очевидно идёт уже о миллионах.
На КПДВ узел под названием «совершенная петля» (perfection loop).
Так каков он, совершенный цикл?
Руководство Google по стилю в C++. Часть 2
Часть 2. Заголовочные файлы
Часть 3. Область видимости
…

Все мы при написании кода пользуемся правилами оформления кода. Иногда изобретаются свои правила, в других случаях используются готовые стайлгайды. Хотя все C++ программисты читают на английском легче, чем на родном, приятнее иметь руководство на последнем.
Эта статья является переводом части руководства Google по стилю в C++ на русский язык.
Исходная статья (fork на github), обновляемый перевод.
Кто такие шизоиды, где они обитают, и почему вам может быть полезно о них узнать

Основные стереотипы о шизоидах в одной картинке
Synopsis: шизоид — не диагноз, это тип характера. Существуют шизоиды, имеющие психические заболевания (как существуют истероиды, эпилептоиды, сварщики, мужчины и женщины, дети и бухгалтеры, имеющие диагнозы из области психиатрии), но далеко не каждый шизоид (мужчина, бухгалтер, сварщик и т.д.) — болен.
Сам этот характер довольно тяжело описать одновременно коротко и корректно. Некоторые называют их «гиками», «интровертами», «чудаками», «ботаниками», «хикканами», «эксцентричными», «нердами», «компьютерными гениями»[1, стр. 231], и все эти характеристики в той или иной мере имеют отношение к, собственно, шизоидам, но ни одна из них не является определяющей.
Проще всего шизоида описать через динамику его внутренних процессов, но такое описание займёт слишком много места, поэтому ограничимся простым (и неточным определением): для целей этой статьи шизоид — это человек, имеющий внутренний конфликт по поводу желания близости и потребности сохранить свою независимость, и решающий этот конфликт через отказ от контактов с внешним миром в пользу погружения в мир собственных фантазий и абстрактных построений.
Большая часть литературы, посвящённой шизоидам, имеет клиническую направленность и описывает достаточно тяжёлые случаи шизоидизации, а в рамках этого текста я хотел бы рассказать о здоровых шизоидах, коих среди нас присутствует достаточно для того, чтобы их особенности имели значение в контексте трудовых отношений, управления и маркетинга.
Немного об ускорении программы: распараллеливание (ручное или автоматическое) на базе сверхоптимистичных вычислений
При этом обычно исходят из той идеи, что распараллеливание не должно каким-то образом влиять на результаты исполнения программы. Это жесткое, но справедливое для многих случаев требование. Однако если мы пытаемся распараллелить программу, ведущую какие-либо расчеты численными методами (обучаем нейронную сеть, моделируем динамику жидкости или молекулярной системы, решаем обыкновенные дифференциальные уравнения или оптимизационные задачи), то результат и так (в любом случае) будет иметь некоторую погрешность. Поэтому, почему бы не применить «рискованные» технологии распараллеливания, которые могут внести в математическое решение небольшую дополнительную погрешность, но позволят получить еще некоторое дополнительное ускорение? Об одной из таких технологий – о расщеплении тел циклов с предсказанием промежуточных результатов и откатом при неудачном предсказании (собственно, это и есть «сверхоптимистичные» вычисления в частично транзакционной памяти) и пойдет речь.
Структуры данных и алгоритмы, которыми я пользовался, работая в технологических компаниях
Google: 90% наших инженеров пользуются программой, которую вы написали (Homebrew), но вы не можете инвертировать бинарное дерево на доске, поэтому — прощайте.
Хотя и у меня никогда не возникало нужды в инверсии бинарного дерева, я сталкивался с примерами реального использования структур данных и алгоритмов в повседневной работе, когда трудился в Skype/Microsoft, Skyscanner и Uber. Сюда входило написание кода и принятие решений, основанное на особенностях структур данных и алгоритмов. Но соответствующие знания я, по большей части, использовал для того чтобы понять то, как созданы некие системы, и то, почему они созданы именно так. Знание соответствующих концепций упрощает понимание архитектуры и реализации систем, в которых эти концепции используются.

В эту статью я включил рассказы о ситуациях, в которых структуры данных, вроде деревьев и графов, а так же различные алгоритмы, были использованы в реальных проектах. Здесь я надеюсь показать читателю то, что базовые знания структур данных и алгоритмов — это не бесполезная теория, нужная только для собеседований, а что-то такое, что, весьма вероятно, по-настоящему понадобится тому, кто работает в быстрорастущих инновационных технологических компаниях.
Boost.Compute или параллельные вычисления на GPU/CPU. Часть 2
Вступление
Привет, Хабр!
Предыдущая часть понравилась многим, поэтому я снова перелопатил половину документации boost и нашёл о чем написать. Очень странно что вокруг boost.compute нету такого же ажиотажа как и вокруг boost.asio. Ведь достаточно, того эта библиотека кроссплатформенная, так ещё и предоставляет удобный (в рамках c++) интерфейс взаимодействия с параллельными вычислениями на GPU и CPU.
Немного о SMART и утилитах для мониторинга
Когда я в очередной раз рассказывал знакомому о том, почему показаниям SMART не следует безоговорочно верить и почему лучше не использовать классические «мониторилки СМАРТа» постоянно, пришла в голову идея записать сказанные слова в виде набора тезисов с пояснениями. Чтобы давать ссылки, вместо того, чтобы каждый раз пересказывать. И для ознакомления широкой аудитории.
Распространённые заблуждения о временах жизни в Rust
(прим. переводчика: времена жизни (lifetimes) — это одна из самых запутанных вещей в Rust, которая часто вызывает затруднение у новичков, даже несмотря на официальную документацию. Разъяснения по отдельным аспектам времён жизни есть, но они все разбросаны по разным источникам и ответам на Stack Overflow. Автор статьи собрал в одном месте и разъяснил множество связанных с временами жизни вопросов, что и делает эту статью столь ценной (я и сам почерпнул новое для себя отсюда). Я решил перевести её, чтобы дать возможность прочитать её тем, кто не владеет английским в достаточной степени, чтобы свободно читать оригинал, а также для того, чтобы повысить известность этой статьи среди русскоязычного Rust-сообщества)
19 мая 2020 г. · 37 минут · #rust · # lifetimes
Почему люди не используют формальные методы?
Прежде чем начать, нужно сформулировать некоторые условия. На самом деле существует не так много формальных методов: всего несколько крошечных групп. Это означает, что разные группы по-разному применяют термины. В широком смысле есть две группы формальных методов: формальная спецификация изучает запись точных, однозначных спецификаций, а формальная проверка — методы доказательства. Сюда входят и код, и абстрактные системы. Мало того, что мы используем разные термины для кода и систем, мы часто используем разные инструменты для их верификации. Чтобы ещё больше всё запутать, если кто-то говорит, что создаёт формальную спецификацию, обычно это означает и верификацию дизайна. А если кто-то говорит, что делает формальную верификацию, обычно это относится к верификации кода.
C++ template аллокатора с потокобезопасным циклическим буфером
Вся реализация в одном заголовочном .h файле: [fast_mem_pool.h]
Фишки, чем этот аллокатор лучше сотни подобных — под катом.
Пять способов пагинации в Postgres, от базовых до диковинных
Не стоит пользоваться OFFSET и LIMIT в запросах с разбиением на страницы

CLion 2020.2: поддержка проектной модели Makefile, больше C++20 и не только
У нашей команды выдалось очень насыщенное лето, результатами которого мы и спешим сегодня поделиться. Итак, встречайте новый релиз CLion 2020.2!

Коротко о том, что вошло в новую версию:
- Поддержка проектной модели Makefile.
- Последние обновления в CMake.
- Новые возможности C++20:
explicit(bool)
, назначенные инициализаторы (designated initializers), циклыfor
на основе диапазонов с инициализаторами. - Обновленный статический анализатор кода: анализ на висячие указатели (dangling pointers), поиск возможностей упрощения кода, поиск неиспользуемого кода, анализ возвращаемого значения функции, ограниченной концептом.
- Юнит-тестирование: поддержка нового фреймворка doctest, новые возможности Catch2 и Google Test. А также упрощение сбора метрик покрытия кода.
- Обновления в плагине PlatformIO для разработки встроенных систем.
- Улучшения в поддержке систем контроля версий.
- Улучшения производительности редактора.
- Исправления в отладчиках.
Как можно и как нельзя использовать нулевой указатель в С++

Некоторым этот банальный вопрос уже набил оскомину, но мы взяли 7 примеров и попытались объяснить их поведение при помощи стандарта:
struct A {
int data_mem;
void non_static_mem_fn() {}
static void static_mem_fn() {}
};
void foo(int) {}
A* p{nullptr};
/*1*/ *p;
/*2*/ foo((*p, 5));
/*3*/ A a{*p};
/*4*/ p->data_mem;
/*5*/ int b{p->data_mem};
/*6*/ p->non_static_mem_fn();
/*7*/ p->static_mem_fn();
Information
- Rating
- Does not participate
- Registered
- Activity