Search
Write a publication
Pull to refresh
-29
@svr_91read⁠-⁠only

Пользователь

Send message

C++20. Coroutines

Reading time33 min
Views69K

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


image

Читать дальше →

Как экономисты потеряли веру в разумность людей и научились их понимать

Reading time21 min
Views34K


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

Бывают ложные белые грибы, у амебы есть ложноножки, а такое отношение к экономистам я называю феноменом ложноглупых классиков. Кстати, частично он тоже объясняется когнитивных искажением, одним из тех, которые изучает современная поведенческая экономика: «мудростью задним числом» (hindsight bias). Однако в первую очередь он связан с той особенностью развития экономической науки, которая отличает ее от естественных наук вроде физики. Об этой особенности экономической теории и о том, как так получилось, что до ХХ века одной из ее самых прочных основ была предпосылка о рациональном и эгоистичном экономическом человеке, и почему в ХХ веке её вдруг решили пересмотреть, я и расскажу сегодня.
Читать дальше →

Случайный трамвай посреди незнакомого города

Reading time13 min
Views24K


Есть одна довольно любопытная задачка, она уже давно вошла в математический фольклор, а так же стала излюбленным испытанием на собеседованиях. Ее условия просты, а решение, кажется напрашивается само собой, однако не будем торопиться с выводами. Берите карандаш, чистый лист бумаги, усаживайтесь поудобней и давайте во всем разбираться.

В чем же, собственно, задача


Итак представьте, что Вы приехали в абсолютно незнакомый город и первый трамвай, который вам там повстречался, следовал под номером 17. Как оценить, сколько всего в этом городе трамвайных маршрутов?

Для простоты считайте, что трамвайные маршруты в городе пронумерованы без пропусков числами от 1 до N и изначально каждое из этих чисел с равными шансами могло оказаться номером трамвая, который вы бы увидели первым.
Читать дальше →

std::atomic. Модель памяти C++ в примерах

Reading time11 min
Views132K

Для написания эффективных и корректных многопоточных приложений очень важно знать какие существуют механизмы синхронизации памяти между потоками исполнения, какие гарантии предоставляют элементы многопоточного программирования, такие как мьютекс, join потока и другие. Особенно это касается модели памяти C++, которая была создана сложной таковой, чтобы обеспечивать оптимальный многопоточный код под множество архитектур процессоров. Кстати, язык программирования Rust, будучи построенным на LLVM, использует модель памяти такую же, как в C++. Поэтому материал в этой статье будет полезен программистам на обоих языках. Но все примеры будут на языке C++. Я буду рассказывать про std::atomic, std::memory_order и на каких трех слонах стоят атомики.

Читать далее

Как заставить код выполняться за одинаковое время? Способы от Яндекс.Контеста

Reading time5 min
Views13K
Недавно мы объявили на Хабре, что начинаем принимать заявки на Яндекс.Алгоритм и другие треки чемпионата по программированию Yandex Cup. Уже много лет онлайн-соревнования Яндекса и других компаний проходят на платформе Контест. Меня зовут Павел Тыквин, я один из разработчиков Контеста. Основная задача нашей платформы — получить от участника чемпионата исходный код решения, скомпилировать и запустить этот код, прогнать тесты и вернуть результат. Звучит не очень сложно. Давайте попробуем.

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;
}
Читать дальше →

Уязвимости в коде. Как отличить опасную брешь от незначительной ошибки?

Reading time18 min
Views15K
Как обычно выглядит проверка кода приложений на уязвимости? Специалист по безопасности инициирует процедуру, код сканируется, в приложении обнаруживаются тысячи уязвимостей. Все — и безопасник, и разработчики — в шоке. Естественная реакция разработчика: «Да наверняка половина — это ложные срабатывания, а другая — некритичные уязвимости!»

Что касается ложных срабатываний, здесь все просто: можно взять и посмотреть непосредственно те места кода, где обнаружены уязвимости с подозрением на false positive. Действительно, какая-то их часть может оказаться ложными срабатываниями, (хотя явно не половина от общего числа).

А вот о том, что критично, а что нет, хотелось бы поговорить более предметно. Если вы понимаете, почему сейчас уже нельзя использовать SHA-1 и зачем экранировать «;», возможно, эта статья не откроет вам чего-то нового. Но если по итогам сканирования от найденных уязвимостей рябит в глазах, добро пожаловать под кат – расскажем, какие «дыры» чаще всего встречаются в мобильных и веб-приложениях, как они работают, как их исправить, а главное — как понять, что перед вами — опасная брешь или незначительная ошибка в коде.


Читать дальше →

Совершенный цикл for

Reading time6 min
Views56K

Сегодня необычный для меня формат статьи: я скорее задаю вопрос залу, нежели делюсь готовым рецептом. Впрочем, для инициирования дискуссии рецепт тоже предлагаю. Итак, сегодня мы поговорим о чувстве прекрасного.


Я довольно давно пишу код, и так вышло, что практически всегда на 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).


image


Так каков он, совершенный цикл?

Читать дальше →

Руководство Google по стилю в C++. Часть 2

Reading time7 min
Views39K
Часть 1. Вступление
Часть 2. Заголовочные файлы
Часть 3. Область видимости



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

Кто такие шизоиды, где они обитают, и почему вам может быть полезно о них узнать

Reading time35 min
Views169K

Основные стереотипы о шизоидах в одной картинке

Synopsis: шизоид — не диагноз, это тип характера. Существуют шизоиды, имеющие психические заболевания (как существуют истероиды, эпилептоиды, сварщики, мужчины и женщины, дети и бухгалтеры, имеющие диагнозы из области психиатрии), но далеко не каждый шизоид (мужчина, бухгалтер, сварщик и т.д.) — болен.

Сам этот характер довольно тяжело описать одновременно коротко и корректно. Некоторые называют их «гиками», «интровертами», «чудаками», «ботаниками», «хикканами», «эксцентричными», «нердами», «компьютерными гениями»[1, стр. 231], и все эти характеристики в той или иной мере имеют отношение к, собственно, шизоидам, но ни одна из них не является определяющей.

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

Большая часть литературы, посвящённой шизоидам, имеет клиническую направленность и описывает достаточно тяжёлые случаи шизоидизации, а в рамках этого текста я хотел бы рассказать о здоровых шизоидах, коих среди нас присутствует достаточно для того, чтобы их особенности имели значение в контексте трудовых отношений, управления и маркетинга.
Читать дальше →

Немного об ускорении программы: распараллеливание (ручное или автоматическое) на базе сверхоптимистичных вычислений

Reading time8 min
Views6.9K
Здравствуйте, уважаемые читатели. В этой публикации речь пойдет о такой (уже ставшей привычной) вещи как ускорение работы программы путем применения параллельных вычислений. Технологии организации таких вычислений известны – это и обычное многопоточное программирование, и применение специальных интерфейсов: OpenMP, OpenAcc, MPI, DVM и многих других (при этом распараллеливаются циклы, используется векторизация или конвейеризация, организуются ленивые вычисления, выделяются независимые блоки программы, которые можно запустить в параллель и т.п.).

При этом обычно исходят из той идеи, что распараллеливание не должно каким-то образом влиять на результаты исполнения программы. Это жесткое, но справедливое для многих случаев требование. Однако если мы пытаемся распараллелить программу, ведущую какие-либо расчеты численными методами (обучаем нейронную сеть, моделируем динамику жидкости или молекулярной системы, решаем обыкновенные дифференциальные уравнения или оптимизационные задачи), то результат и так (в любом случае) будет иметь некоторую погрешность. Поэтому, почему бы не применить «рискованные» технологии распараллеливания, которые могут внести в математическое решение небольшую дополнительную погрешность, но позволят получить еще некоторое дополнительное ускорение? Об одной из таких технологий – о расщеплении тел циклов с предсказанием промежуточных результатов и откатом при неудачном предсказании (собственно, это и есть «сверхоптимистичные» вычисления в частично транзакционной памяти) и пойдет речь.
Читать дальше →

Структуры данных и алгоритмы, которыми я пользовался, работая в технологических компаниях

Reading time15 min
Views114K
Пользуетесь ли вы структурами данных и алгоритмами в повседневной работе? Я обратил внимание на то, что всё больше и больше людей считает алгоритмы чем-то таким, чем, без особой связи с реальностью, технические компании, лишь по собственной прихоти, интересуются на собеседованиях. Многие жалуются на то, что задачи на алгоритмы — это нечто из области теории, имеющей слабое отношение к настоящей работе. Такой взгляд на вещи, определённо, распространился после того, как Макс Хауэлл, автор Homebrew, опубликовал твит о том, что произошло с ним на собеседовании в Google:

Google: 90% наших инженеров пользуются программой, которую вы написали (Homebrew), но вы не можете инвертировать бинарное дерево на доске, поэтому — прощайте.

Хотя и у меня никогда не возникало нужды в инверсии бинарного дерева, я сталкивался с примерами реального использования структур данных и алгоритмов в повседневной работе, когда трудился в Skype/Microsoft, Skyscanner и Uber. Сюда входило написание кода и принятие решений, основанное на особенностях структур данных и алгоритмов. Но соответствующие знания я, по большей части, использовал для того чтобы понять то, как созданы некие системы, и то, почему они созданы именно так. Знание соответствующих концепций упрощает понимание архитектуры и реализации систем, в которых эти концепции используются.



В эту статью я включил рассказы о ситуациях, в которых структуры данных, вроде деревьев и графов, а так же различные алгоритмы, были использованы в реальных проектах. Здесь я надеюсь показать читателю то, что базовые знания структур данных и алгоритмов — это не бесполезная теория, нужная только для собеседований, а что-то такое, что, весьма вероятно, по-настоящему понадобится тому, кто работает в быстрорастущих инновационных технологических компаниях.
Читать дальше →

Boost.Compute или параллельные вычисления на GPU/CPU. Часть 2

Reading time4 min
Views5.5K

Вступление


Привет, Хабр!

Предыдущая часть понравилась многим, поэтому я снова перелопатил половину документации boost и нашёл о чем написать. Очень странно что вокруг boost.compute нету такого же ажиотажа как и вокруг boost.asio. Ведь достаточно, того эта библиотека кроссплатформенная, так ещё и предоставляет удобный (в рамках c++) интерфейс взаимодействия с параллельными вычислениями на GPU и CPU.

Читать дальше →

Немного о SMART и утилитах для мониторинга

Reading time3 min
Views22K
В сети достаточно много информации о SMART и значениях атрибутов. Но мне не встречались упоминания о нескольких важных моментах, про которые знаю от людей, занимающихся исследованием носителей информации.

Когда я в очередной раз рассказывал знакомому о том, почему показаниям SMART не следует безоговорочно верить и почему лучше не использовать классические «мониторилки СМАРТа» постоянно, пришла в голову идея записать сказанные слова в виде набора тезисов с пояснениями. Чтобы давать ссылки, вместо того, чтобы каждый раз пересказывать. И для ознакомления широкой аудитории.
Читать дальше →

Распространённые заблуждения о временах жизни в Rust

Reading time27 min
Views23K

(прим. переводчика: времена жизни (lifetimes) — это одна из самых запутанных вещей в Rust, которая часто вызывает затруднение у новичков, даже несмотря на официальную документацию. Разъяснения по отдельным аспектам времён жизни есть, но они все разбросаны по разным источникам и ответам на Stack Overflow. Автор статьи собрал в одном месте и разъяснил множество связанных с временами жизни вопросов, что и делает эту статью столь ценной (я и сам почерпнул новое для себя отсюда). Я решил перевести её, чтобы дать возможность прочитать её тем, кто не владеет английским в достаточной степени, чтобы свободно читать оригинал, а также для того, чтобы повысить известность этой статьи среди русскоязычного Rust-сообщества)


19 мая 2020 г. · 37 минут · #rust · # lifetimes

Читать дальше →

Почему люди не используют формальные методы?

Reading time20 min
Views15K
На Software Engineering Stack Exchange я увидел такой вопрос: «Что мешает широкому внедрению формальных методов?» Вопрос был закрыт как предвзятый, а большинство ответов представляли собой комментарии типа «Слишком дорого!!!» или «Сайт — это не самолёт!!!» В каком-то смысле это верно, но мало что объясняет. Я написал эту статью, чтобы дать более широкую историческую картину формальных методов (FM), почему они на самом деле не используются и что мы делаем для исправления ситуации.

Прежде чем начать, нужно сформулировать некоторые условия. На самом деле существует не так много формальных методов: всего несколько крошечных групп. Это означает, что разные группы по-разному применяют термины. В широком смысле есть две группы формальных методов: формальная спецификация изучает запись точных, однозначных спецификаций, а формальная проверка — методы доказательства. Сюда входят и код, и абстрактные системы. Мало того, что мы используем разные термины для кода и систем, мы часто используем разные инструменты для их верификации. Чтобы ещё больше всё запутать, если кто-то говорит, что создаёт формальную спецификацию, обычно это означает и верификацию дизайна. А если кто-то говорит, что делает формальную верификацию, обычно это относится к верификации кода.
Читать дальше →

C++ template аллокатора с потокобезопасным циклическим буфером

Reading time9 min
Views8.8K
Вашему вниманию простой C++ template аллокатора с потокобезопасным циклическим буфером.

Вся реализация в одном заголовочном .h файле: [fast_mem_pool.h]

Фишки, чем этот аллокатор лучше сотни подобных — под катом.
Читать дальше →

Пять способов пагинации в Postgres, от базовых до диковинных

Reading time13 min
Views93K
Вас может удивить тот факт, что пагинация, распространенная, как таковая, в веб приложениях, с легкостью может быть реализована нерационально. В этой статье мы испробуем различные способы пагинации на стороне сервера и обсудим их удобство при использовании в PostgreSQL. Статья поможет Вам понять, какая техника более уместна в Вашей ситуации, в том числе некоторые Вы, возможно, не видели прежде, а именно те, которые полагаются на физическую кластеризацию и сборщика статистики базы данных.
Читать дальше →

Не стоит пользоваться OFFSET и LIMIT в запросах с разбиением на страницы

Reading time5 min
Views56K
Прошли те дни, когда не надо было беспокоиться об оптимизации производительности баз данных. Время не стоит на месте. Каждый новый бизнесмен из сферы высоких технологий хочет создать очередной Facebook, стремясь при этом собирать все данные, до которых может дотянуться. Эти данные нужны бизнесу для более качественного обучения моделей, которые помогают зарабатывать. В таких условиях программистам необходимо создавать такие API, которые позволяют быстро и надёжно работать с огромными объёмами информации.


Читать дальше →

CLion 2020.2: поддержка проектной модели Makefile, больше C++20 и не только

Reading time8 min
Views6.2K
Привет, Хабр!

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

CLion release

Коротко о том, что вошло в новую версию:

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

Как можно и как нельзя использовать нулевой указатель в С++

Reading time5 min
Views15K


Некоторым этот банальный вопрос уже набил оскомину, но мы взяли 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