Pull to refresh
3
0.1
Сергей @gres_84

C++ Developer

Send message

Полезные фичи С++ на примере организации пайплайна

Reading time20 min
Views8.1K

В рамках микросервисной архитектуры достаточно легко делать «реактивные» сервисы: к вам приходит событие или вызов HTTP-метода, и в ответ на это происходит какое-то действие. Однако бывают более сложные сценарии, когда надо собрать некоторое количество информации или событий прежде, чем что-то делать. В таком случае нужен пайплайн — механизм организации сложных правил обработки событий. 

Недавно нам пришлось организовать пайплайн с использованием интересных С++-трюков. О них я и расскажу в статье. 

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

— Как средствами метапрограммирования удобно сериализовать и десериализовать разнотипные объекты 

— Как сделать универсальный запускатель функций, который будет запускать любую функцию и сам искать, откуда «добыть» эти аргументы 

— И главное, как сделать интерфейс для написания пайплайна обработки события — удобный и полностью изолированный от инфраструктуры

Читать далее
Total votes 40: ↑40 and ↓0+51
Comments15

Правда и мифы о чёрных дырах. Горизонт событий и сингулярность. Основы холонавтики

Level of difficultyMedium
Reading time30 min
Views7.6K

Чёрная дыра… Ничто так не притягивает и не будоражит воображение, пока не погрузишься в глубины теоретической физики и не поймешь, что в реальности всё довольно скучно и прозаично. Знаю, тема буквально затёрта… до дыр, да и хайп вокруг неё поутих с тех пор, как появились первые фотографии, сделанные Телескопом горизонта событий. Но без краткого ликбеза по чёрным дырам будет трудно понять мои будущие статьи по квантовой гравитации и цифровой физике, ведь на горизонте событий пересекаются сферы применимости двух фундаментальных, но плохо совместимых физических теорий – квантовой теории поля (КТП) и общей теории относительности (ОТО). К тому же изучение чёрных дыр – это идеальное упражнение на понимание релятивистской физики Эйнштейна, в частности, принципа относительности одновременности и принципа эквивалентности инертной и гравитационной масс. Поэтому я решил систематизировать информацию о чёрных дырах и расставить все точки над «i». В данной статье мы рассмотрим чёрные дыры как астрофизические объекты. Квантовые аспекты чёрных дыр оставим на потом.

Читать далее
Total votes 34: ↑33 and ↓1+43
Comments92

Во что вам обойдется конкурентная обработка. Иерархия проблем

Reading time47 min
Views6.1K

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

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

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

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

Читать далее
Total votes 22: ↑20 and ↓2+26
Comments5

486-го хватит всем

Level of difficultyEasy
Reading time15 min
Views57K

В конце технического интервью, если кандидат ответил на вопросы и справился с задачами, у нас есть время для свободных вопросов, которые можно задать команде или кому-то из интервьюеров. Эту практику я переносил из компании в компанию, и она всегда помогала разрядить обстановку или вывести человека на разговор, если он был напряжен во время общения. Вопросы могут быть любые, кроме личных или тех, что под NDA. Обычно кандидаты задают технические вопросы по стеку, пайплайнам, иногда пытаются задать каверзные вопросы, особенно по плюсам, чтобы проверить нас. Иногда мы не можем ответить на них. Вопросы в стиле Google — например, «почему таблетки круглые?» — тоже встречаются, но недавно на одном из интервью прозвучал вопрос, на который вроде все и знали ответ, но никто сразу не смог его дать. Вопрос звучал так: «Какие общие технологии и решения появились в процессорах с времён 486, которыми мы часто пользуемся?»

Вопрос действительно интересный — что нового появилось, чем мы пользуемся каждый день? Что умеют современные процессоры, чего не могли процессоры год или два назад, пять или десять лет назад, сорок лет назад? Мы просто используем миллиарды транзисторов, даже не зная, как они работают. Покопавшись в Википедии, на сайте Агнера Фога и в документации Intel, я составил список того, что появилось и используется в современных процессорах. Всё, что указано ниже, относится в основном к x86 и консолям, если не указано иное. Поскольку консоли после третьего поколения PlayStation — фактически ПК с минимальными отличиями, речь дальше пойдёт в основном о ПК. История имеет склонность повторяться, и многое из того, что мы сейчас имеем, вводилось не один раз, просто под разными названиями.

Читать далее
Total votes 103: ↑102 and ↓1+139
Comments185

50 оттенков линейной регрессии, или почему всё, что вы знаете об A/B тестах, помещается в одно уравнение

Reading time18 min
Views19K

Всем привет! A/B тестирование уже давно стало стандартом в проверке гипотез и улучшении продуктов в X5. Но, как ни странно, многие из «модных» техник, которые применяются в A/B тестировании, на самом деле, не что иное, как вариации старой доброй линейной регрессии. 

Основная идея здесь проста: правильное добавление новых переменных в модель помогает лучше контролировать внешние факторы и уменьшать шум в данных. Это позволяет точнее оценить эффект от воздействия и объединить разные статистические подходы, которые обычно рассматриваются отдельно. Но почему это работает? Почему всё сводится к тому, что добавление переменных помогает объединить, казалось бы, разрозненные техники? 

Чтобы разобраться в этом, для начала вспомним основы линейной регрессии, после чего перейдём к различным статистическим методам снижения дисперсии и покажем, как они сводятся к линейной регрессии. Затем объединим все техники вместе и на примере покажем, как они работают на практике.

Читать далее
Total votes 20: ↑20 and ↓0+27
Comments10

Во что компилятор C++ превращает код, или ускоряем код безопасно

Level of difficultyMedium
Reading time13 min
Views9.2K

Привет, Хабр! Меня зовут Алексей Салтыков, я инженер-программист в команде КОМПАС-3D. Решил поделиться соображениями насчет оптимизаций в С++ глазами обычного разработчика. Хочется сразу предупредить, что статья никого ни к чему не призывает. Цель – наглядно показать, как незначительные трансформации кода могут помочь компилятору лучше оптимизировать код и насколько это вообще эффективно.

Читать далее
Total votes 21: ↑19 and ↓2+26
Comments14

Производные дробного порядка и экспоненциальная производная

Level of difficultyEasy
Reading time4 min
Views11K

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

Обычную производную и её обобщения используют повсеместно, например в машинном обучении, при обучении нейронных сетей.

Если продифференцировать функцию - то получится её производная. Если сделать это дважды - получится вторая производная. Но если ли что “между”? Конечно же есть, и именно про такие объекты написана эта статья.

Читать далее
Total votes 41: ↑40 and ↓1+55
Comments15

Шаблоны C++: как итерировать по std::tuple — основы

Reading time9 min
Views21K

Для большинства стандартных контейнеров перебор элементов можно осуществлять просто с помощью цикла for с диапазоном прямо во время выполнения. Но что насчет кортежей (std::tuple)? В этом случае мы не можем использовать обычный цикл, так как он не «понимает» список аргументов кортежа во время компиляции. В этой статье я покажу вам несколько приемов, которые вы можете использовать для итерации по элементам кортежа.

Читать далее
Total votes 13: ↑12 and ↓1+14
Comments1

И целых 20 ядер мало

Level of difficultyEasy
Reading time27 min
Views19K

Если вы посмотрите на общую раздутость современного софта, загружаемые 100 гигабайтные игры, ежегодную Nvidia X090 дающую +20% год от года, и 20-ядерные процессоры, то со стороны может показаться, что оптимизация производительности неважно чего, будь то игры или другой софт, казалось бы, утратила свою актуальность. В эпоху безнаказанной производительности аппаратной части можно расплескивать хоть половину этой мощи, и пользователь этого даже не заметит. Это все может и верно, если вы не делаете игру. Почему же тогда на этих двадцати ядрах, фризит и тормозит (хорошо что не вылетает часто) игра выпущенная два года назад?

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

При том, что все эти 30 — 60 — 120 — 200 фпс в играх, это чисто маркетинговый показатель, это время с которой движок может создавать фреймы для видеокарты, но движок это не только картинка, есть физика — а она как работала на 30 фпсах 10 лет назад, так и работает. Или звуковая подсистема, так она вообще своей отдельной жизнью живет в своих приоритетных тредах, мы просто кидаем туда меседжи с настройками и номером фрейма, чтобы засинхронизировать это с картинкой. Это сложно, но решаемо, но звук не привязан к картинке.

Налево пойдешь проца не хватит...
Total votes 58: ↑58 and ↓0+76
Comments53

Создаем свою библиотеку на C++ с тестированием, CMake и блекджеком: часть 2

Level of difficultyMedium
Reading time30 min
Views5.7K

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

Если вы ловили себя на мысли: «А почему мне бы не создать свою полноценную библиотеку?», то я рекомендую прочитать вам мою статью.

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

Некоторые из вас могут подумать, что мы изобретаем велосипед. А я в ответ спрошу — сможете ли вы прямо сейчас, без подсказок, только по памяти, нарисовать велосипед без ошибок?

Добро пожаловать во вторую, скорее всего финальную часть статьи! Здесь мы окончательно допишем код, исправим некоторые ошибки.

Читать далее
Total votes 23: ↑23 and ↓0+31
Comments19

О шаблонах в С++, чуть сложнее

Reading time40 min
Views35K

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

Потрогать здесь
Total votes 50: ↑50 and ↓0+50
Comments31

Создаем свою простую (C++) библиотеку с документацией, CMake и блекджеком

Level of difficultyMedium
Reading time33 min
Views16K

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

Если вы ловили себя на мысли: ‭«А почему мне бы не создать свою полноценную библиотеку?‭», то я рекомендую прочитать вам мою статью.

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

Некоторые из вас могут подумать что мы изобретаем велосипед. А я в ответ скажу — сможете ли вы прямо сейчас, без подсказок, только по памяти, нарисовать велосипед без ошибок?

Читать далее
Total votes 49: ↑48 and ↓1+59
Comments68

Шеф, всё пропало

Level of difficultyEasy
Reading time12 min
Views19K

Ошибки программистов C++ — это отдельный вид искусства, вроде бы простой язык, но стоит отвлечься на чашечку кофе, как компилятор начинает вываливать простыню ворнингов пополам с ошибками, и иногда это больше похоже на древнеегипетские письмена, чем на нормальный выхлоп. Вы наверное и сами не раз сталкивались с разыменованием nullptr или перепутали (= и ==) по недосмотру. Часто причиной ошибкой является лень или невнимательность, или усталость - не зря появились суеверия "не комитить в пятницу вечером", "не кодить в состоянии изменного сознания" или "избегать кода под кофейным угаром", ну это когда три-четыре кружечки кофе навернул и пошел нести добрый код направо и налево.

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

C++ не прощает ошибок, но именно в этом его "шарм". В большинстве приведенных примеров сохранен стиль и названия параметров, только немного подчищены коментарии, дабы не палить контору.

Поотгадывать баги, выпить чашечку кофе...
Total votes 29: ↑29 and ↓0+41
Comments37

Идеальная передача и универсальные ссылки в C++

Reading time9 min
Views159K
Недавно на isocpp.org была опубликована ссылка на статью Eli Bendersky «Perfect forwarding and universal references in C++». В этой небольшой статье есть простой ответ на простой вопрос — для решения каких задач и как нужно использовать rvalue-ссылки.
Узнать этот ответ
Total votes 56: ↑56 and ↓0+56
Comments28

Реализация подписчиков в c++ — пляшем от печки, но уже совсем далеко

Level of difficultyHard
Reading time12 min
Views2.7K

В прошлой статье мы написали вполне себе разумный оповещатель (notifier) для рассылки уведомлений подписчикам (subscribers). Он достаточно удобен, там нет ничего лишнего - всего 130 строчек кода. Моменты, важные для клиентов этого кода, продуманы. Как например, многопоточный вызов доставки оповещений с минимальными взаимными блокировками и возможность отписывать прямо из обработчика подписчика.

На этом бы и остановиться, но мы шагнём дальше, добавив немного шаблонной магии и сделав код "академичнее".

Читать далее
Total votes 6: ↑6 and ↓0+13
Comments4

Реализация подписчиков в c++ — пляшем от печки чуть дальше

Level of difficultyMedium
Reading time8 min
Views2.8K

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

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

Читать далее
Total votes 8: ↑8 and ↓0+14
Comments2

Анатомия асинхронных фреймворков в С++ и других языках

Reading time20 min
Views44K
Привет! В этой статье я расскажу об устройстве асинхронных движков с корутинами и без них. Для начала сосредоточимся не на конкретном движке, а на том, почему во всех популярных языках программирования появились корутины и чем они так хороши. Это может быть интересно не только C++-разработчикам, но и всем, кто занимается разработкой сетевых приложений или интересуется архитектурой современных фреймворков.

Пройдёмся по разным архитектурам построения серверов — от самой простой синхронной к более интересным, посмотрим на типичную архитектуру корутинового движка, а после окунёмся в дебри C++ и взглянем на самое страшное на примере нашего фреймворка userver.

Пишем синхронный сервер


Представьте, что у вашего сервиса очень маленькая нагрузка — 100 rps, и вам дали задачу написать простой сервер, понятный каждому второму школьнику. У вас получится что-то наподобие следующего:

void naive_accept() {
  for (;;) {
    auto new_socket = accept(listener);

    std::thread thrd([socket = std::move(new_socket)] {
      auto data = socket.receive();
      process(data);
      socket.send(data);
    });

    thrd.detach();
  }
}
Читать дальше →
Total votes 56: ↑53 and ↓3+63
Comments32

Рекуррентное соотношение Мюллера: проблемы с округлением чисел с плавающей точкой

Reading time4 min
Views37K
Некоторое время назад я натолкнулся на упражнение, которое выглядит не так уж и сложно:

Пусть последовательность xn определена так:

посчитайте x30.

Это не так уж и трудно закодировать, возможно реализовав xi как рекурсивную функцию. С обычными числами с плавающей запятой двойной точности, по мере увеличения i, результат красиво сходится к 100. Супер!

К сожалению, 100 даже близко не является правильным ответом. На самом деле последовательность сходится к 5.
Читать дальше →
Total votes 60: ↑59 and ↓1+58
Comments116

Реализация подписчиков в c++ — пляшем от печки

Level of difficultyEasy
Reading time6 min
Views4K

За время долгой работы в IT непосредственно с кодом, подмечаю одну особенность, что писать приходится всё меньше (в последнее время практически не писать), а ревьювить всё больше. И всё чаще видны нагромождения тонн кода, которые по факту не нужны, не вносят никакой дополнительной пользы. Но создают раз за разом головную боль для следующего читающего этот код программиста, который вынужден что-то поправить или дописать в этом коде. По итогу, программист махает рукой на эту чудную "архитектуру"... и пишет ещё один wrapper / adapter над ним. И, таким образом, передаёт пламенный привет последующим коллегам в будущее ;).

Попробуем взять и переписать с минимумом кода одну из очень часто встречающихся задач - рассылку уведомлений объектам в коде при возникновении какого-то события. На первый взгляд кажется, что в c++ уже есть все инструменты, чтобы написать этот код в несколько строк: функтор std::function<...> - чтобы сохранить отложенный вызов, контейнер std::vector<std::function...> - чтобы сохранить цепочку отложенных вызовов. По которым нужно просто пробежаться при возникновении события и вызвать сохранённые функторы...

Читать далее
Total votes 15: ↑14 and ↓1+20
Comments27

Курс «PostgreSQL для начинающих»: #4 — Анализ запросов (ч.2 — узлы получения данных)

Level of difficultyMedium
Reading time12 min
Views12K

Продолжаю публикацию расширенных транскриптов лекционного курса "PostgreSQL для начинающих", подготовленного мной в рамках "Школы backend-разработчика" в "Тензоре".

В первой части лекции мы узнали, что такое план выполнения запроса, как и зачем его читать (и почему это совсем непросто), и о каких проблемах с производительностью базы он может сигнализировать. В этой - разберем, что такое Seq ScanBitmap Heap ScanIndex Scan и почему Index Only Scan бывает нехорош.

Как обычно, для предпочитающих смотреть и слушать, а не читать - доступна видеозапись (часть 1часть 2) и слайды.

Читать далее
Total votes 18: ↑18 and ↓0+23
Comments6
1
23 ...

Information

Rating
4,222-nd
Location
Москва, Москва и Московская обл., Россия
Date of birth
Registered
Activity