#cpp #highload
-2. Asking questions the right way.
Я кстати как-то писал что-то около этого, но тут конечно статья совсем конфета.
-1. C/C++ performance pitfall: int8_t, aliasing and the ways out.
0. Scaling the Instagram Explore recommendations system.
Интересные мльные штуки узнал. Например про подход Two Tower модели.
1. Any Day Can Be Prime Day: How Amazon.com Search Uses Chaos Engineering to Handle Over 84K Requests Per Second.
Опять тут aws lambda какая-то, но прикона. Про chaos engineering писал чуть-чуть ранее.
-2. Asking questions the right way.
Я кстати как-то писал что-то около этого, но тут конечно статья совсем конфета.
-1. C/C++ performance pitfall: int8_t, aliasing and the ways out.
0. Scaling the Instagram Explore recommendations system.
Интересные мльные штуки узнал. Например про подход Two Tower модели.
1. Any Day Can Be Prime Day: How Amazon.com Search Uses Chaos Engineering to Handle Over 84K Requests Per Second.
Опять тут aws lambda какая-то, но прикона. Про chaos engineering писал чуть-чуть ранее.
👍4❤1
this->notes.
#common О подходах к реализации шаблонов/дженериков. В C++ всё просто и понятно. Каждый раз, когда вы используете шаблонный тип или шаблон функции с новым типом, компилятор просто генерирует конкретную специализацию для него. Отсюда возникают такие проблемы…
Сначала я хотел обновить и расширить инфой пост про дженерики.
Потом я нашёл статью, которая очень хорошо описывает базовые подходы реализации дженериков в различных языках программирования: link. Подумал, что можно было бы перевести её на хабр. Такое вот полезное упражнение.
Потом я поискал уже готовый перевод на хабре. И такой есть: link. Так что в итоге я ничего не сделал. Но почитать можно : )
Потом я нашёл статью, которая очень хорошо описывает базовые подходы реализации дженериков в различных языках программирования: link. Подумал, что можно было бы перевести её на хабр. Такое вот полезное упражнение.
Потом я поискал уже готовый перевод на хабре. И такой есть: link. Так что в итоге я ничего не сделал. Но почитать можно : )
🫡24👍5🐳2❤1
#common
Исправление очепяток 1/2.
Я думаю, понятно, зачем нужно уметь исправлять запросы, но вот хороший пример от Google про то, как люди ищут Britney Spears: link. Тут и brittiny spears, и drittney spears, и buttney spears, и много всего другого.
Исправления обычно делят на два вида: isolated-term correction (когда пытаемся исправить каждый отдельный терм запроса отдельно) и context-sensitive (когда каждый отдельный терм корректен, но при этом они не согласуются друг с другом). Сначала про первое.
Есть два основных, применяющихся вместе, алгоритмических метода исправлять опечатки: по расстоянию между строками (edit distance) и по пересечению n-грамм.
Когда говорят про расстояние между строками, обычно имеют в виду, что есть некоторое множество операций (например, добавление, удаление и замена символа), и тогда расстоянием между s1 и s2 будет кол-во операций, нужное, чтобы превратить одну строку в другую (в данном случае это расстояние Левенштейна). В общем случае различным операциям может назначаться разный вес (например изменить гласную на другую гласную это семантически “дешевле”, чем гласную на согласную; или пользователи часто промахиваются по клавиатуре, что означает, что некоторые ошибки в буквах возникают чаще).
Нахождение расстояния Левенштейна между двумя строками это известная таска на динамическое программирование. Однако в рамках больших поисковых индексов подобная операция для всех пар (терм запроса, терм в индексе) будет занимать огромное время. Потому это не прям хорошее решение, однако на него в более простых случаях можно наворачивать разные эвристики. Например одной из простых может быть предположение, что пользователь не ошибся в первом символе слова (в общем случае в первых k символах), что означает сужение поиска по индексу лишь среди термов, которые начинаются на тот же префикс.
Или можно например использовать улучшение метрики Левенштейна под названием Дамерау-Левенштейн, где разрешено переставлять символы.
Иногда (даже всегда) работают не с расстояниями, а с вероятностями. Например можно посчитать
где
Исправление очепяток 1/2.
Я думаю, понятно, зачем нужно уметь исправлять запросы, но вот хороший пример от Google про то, как люди ищут Britney Spears: link. Тут и brittiny spears, и drittney spears, и buttney spears, и много всего другого.
Исправления обычно делят на два вида: isolated-term correction (когда пытаемся исправить каждый отдельный терм запроса отдельно) и context-sensitive (когда каждый отдельный терм корректен, но при этом они не согласуются друг с другом). Сначала про первое.
Есть два основных, применяющихся вместе, алгоритмических метода исправлять опечатки: по расстоянию между строками (edit distance) и по пересечению n-грамм.
Когда говорят про расстояние между строками, обычно имеют в виду, что есть некоторое множество операций (например, добавление, удаление и замена символа), и тогда расстоянием между s1 и s2 будет кол-во операций, нужное, чтобы превратить одну строку в другую (в данном случае это расстояние Левенштейна). В общем случае различным операциям может назначаться разный вес (например изменить гласную на другую гласную это семантически “дешевле”, чем гласную на согласную; или пользователи часто промахиваются по клавиатуре, что означает, что некоторые ошибки в буквах возникают чаще).
Нахождение расстояния Левенштейна между двумя строками это известная таска на динамическое программирование. Однако в рамках больших поисковых индексов подобная операция для всех пар (терм запроса, терм в индексе) будет занимать огромное время. Потому это не прям хорошее решение, однако на него в более простых случаях можно наворачивать разные эвристики. Например одной из простых может быть предположение, что пользователь не ошибся в первом символе слова (в общем случае в первых k символах), что означает сужение поиска по индексу лишь среди термов, которые начинаются на тот же префикс.
Или можно например использовать улучшение метрики Левенштейна под названием Дамерау-Левенштейн, где разрешено переставлять символы.
Иногда (даже всегда) работают не с расстояниями, а с вероятностями. Например можно посчитать
p(w|s) – вероятность того, что имели в виду терм w, при условии, что получили терм s (эту величину мы пытаемся максимизировать). Тут применяем формулу Байеса:p(w|s) = C * p(s|w) * p(w),где
p(s|w) – вероятность того, что при наборе w можно получить s, а p(w) – вероятность того, что пользователь мог использовать терм w (тут уже речь идёт про модель конкретного языка). Не будем уходить глубже в этом месте и пойдём дальше (хотя тут много интересных моментов есть, вроде того, что в языке постоянно появляются новые слова; что можно строить модели того, как пользователи ошибаются).🔥6❤1
#common
Исправление очепяток 2/2.
Для сокращения кол-ва термов, с которыми в итоге можно считать расстояние, также можно использовать n-граммы. Построим n-грамм индекс (отображение из n-граммы во множество термов в документах), а потом пройдёмся по нему и достанем те термы, которые имеют “много” общих n-грамм с запросом. Например у нас есть запрос bord и индекс над биграммами:
Уже обсуждавшимися методами можно пересечь множества термов для всех биграмм и при выборе кол-ва общих биграмм 2 получить результаты aboard, boardroom и border.
Т.к. выбор количества общих n-грамм сильно зависит от размеров строк, можно оперировать более общими понятиями вроде коэффициента Жаккара, означающим меру сходства множеств (упоминал его в посте про вероятностные сд).
В случае, если после нахождения ближайших термов получается несколько, можно брать более популярный. Например популярным можно назвать терм, который чаще встречается в индексированных документах. А ещё можно смотреть, как сами пользователи исправляют свои ошибки и выбирать ту версию, которую они выбирают чаще. Вот этот подход с популярностями юзается примерно в любом решении: от гугла до небольших самописных штук, которые я видел.
В этом месте кстати есть различные способы использовать это для юзера. Можно просто безусловно попробовать поиск по документам, учитывая исправления (как делаем мы), а можно явно предложить замену, как делают это крупные поисковики.
С точки зрения context-sensitive исправлений самым простым решением может быть попробовать изменить в запросе каждый отдельный терм и поискать результаты по всем подобным запросам, после чего на основании кол-ва результатов/их релевантности выбрать подходящую исправленную версию.
Конечно, количество подобных “исправленных” запросов может быть огромным. Потому тут опять же есть всякие эвристики. Например использовать только самые популярные формы термов (или сочетаний термов) с учётом действий пользователей.
Также важным инструментом является т.н. phonetic correction.
Основная идея – научиться генерировать “фонетический хеш” слов, который будет совпадать, если они произносятся одинаково, даже если пишутся по-разному. Подходы для подобных задач называются soundex алгоритмами. Тут можно вики почитать.
Исправление очепяток 2/2.
Для сокращения кол-ва термов, с которыми в итоге можно считать расстояние, также можно использовать n-граммы. Построим n-грамм индекс (отображение из n-граммы во множество термов в документах), а потом пройдёмся по нему и достанем те термы, которые имеют “много” общих n-грамм с запросом. Например у нас есть запрос bord и индекс над биграммами:
bo: aboard about boardroom border
or: border lord morbid sordid
rd: aboard ardent boardroom border
Уже обсуждавшимися методами можно пересечь множества термов для всех биграмм и при выборе кол-ва общих биграмм 2 получить результаты aboard, boardroom и border.
Т.к. выбор количества общих n-грамм сильно зависит от размеров строк, можно оперировать более общими понятиями вроде коэффициента Жаккара, означающим меру сходства множеств (упоминал его в посте про вероятностные сд).
В случае, если после нахождения ближайших термов получается несколько, можно брать более популярный. Например популярным можно назвать терм, который чаще встречается в индексированных документах. А ещё можно смотреть, как сами пользователи исправляют свои ошибки и выбирать ту версию, которую они выбирают чаще. Вот этот подход с популярностями юзается примерно в любом решении: от гугла до небольших самописных штук, которые я видел.
В этом месте кстати есть различные способы использовать это для юзера. Можно просто безусловно попробовать поиск по документам, учитывая исправления (как делаем мы), а можно явно предложить замену, как делают это крупные поисковики.
С точки зрения context-sensitive исправлений самым простым решением может быть попробовать изменить в запросе каждый отдельный терм и поискать результаты по всем подобным запросам, после чего на основании кол-ва результатов/их релевантности выбрать подходящую исправленную версию.
Конечно, количество подобных “исправленных” запросов может быть огромным. Потому тут опять же есть всякие эвристики. Например использовать только самые популярные формы термов (или сочетаний термов) с учётом действий пользователей.
Также важным инструментом является т.н. phonetic correction.
Основная идея – научиться генерировать “фонетический хеш” слов, который будет совпадать, если они произносятся одинаково, даже если пишутся по-разному. Подходы для подобных задач называются soundex алгоритмами. Тут можно вики почитать.
🔥5👍2❤1
#cpp #highload
1. Начался CppCon и первый доклад по традиции от Bjarne Stroustrup под названием Delivering Safe C++.
Говорил про заявление правительства США в отношении C/C++ (где обсуждалось неиспользование C++ как языка из-за его небезопасности), а ещё про то, что нужно уходить от модели языка C/C++ к С++ (т.е. что плюсы это отдельный язык, который хватит причислять к C).
Немножко говорил про то, что нельзя ломать совместимость ради новых фичей, т.к. это очень больно, но тем не менее язык должен развиваться. Цитата:
> We can’t break billions of lines of existing code. I say can’t, not shouldn’t. Because we can’t.
Много рассуждал про то, что такое безопасность и про то, что язык должен становиться безопаснее, потому что это то, чего от него сейчас хотят.
И показывал разные проблемы с рассуждениями.
Как обычно довольно абстрактно имхо. Но послушать можно.
Эх, ребят. На чём мы пишем.
2. Ещё из прикольного доклад от Herb Sutter с мыслями о том, “how we can refresh C++ itself” (то есть уже надо бы его refresh🙂 ). Позиционируется как продолжение прошлогоднего доклада про Cpp2, о котором я писал тут (п.1).
Сначала он рассказал о нескольких новых фичах, которые появились за год. Например:
- chained comparisons (причём это работает только для корректных в математическом смысле слова транзитивных условий):
- named
Дальше Herb рассказывал про метапрограммирование в Cpp2, только не вот это на шаблонах, а про нормальное вроде рефлексии и всего такого (и рядом про енамы (и flag_enum) и union’ы).
И дальше рассуждал про то, как безопаснее и эффективнее всего стоит переходить на новые технологии и как этого добиться. Мне понравилось.
3. Коротенькое видео про разницу между архитектурой и дизайном. Никогда про существование разницы не думал, а ещё там местами расплывчатые формулировки, но прикольно.
4. Небольшая статья про то, зачем на самом деле (не)нужны микросервисы.
1. Начался CppCon и первый доклад по традиции от Bjarne Stroustrup под названием Delivering Safe C++.
Говорил про заявление правительства США в отношении C/C++ (где обсуждалось неиспользование C++ как языка из-за его небезопасности), а ещё про то, что нужно уходить от модели языка C/C++ к С++ (т.е. что плюсы это отдельный язык, который хватит причислять к C).
Немножко говорил про то, что нельзя ломать совместимость ради новых фичей, т.к. это очень больно, но тем не менее язык должен развиваться. Цитата:
> We can’t break billions of lines of existing code. I say can’t, not shouldn’t. Because we can’t.
Много рассуждал про то, что такое безопасность и про то, что язык должен становиться безопаснее, потому что это то, чего от него сейчас хотят.
И показывал разные проблемы с рассуждениями.
Как обычно довольно абстрактно имхо. Но послушать можно.
Эх, ребят. На чём мы пишем.
2. Ещё из прикольного доклад от Herb Sutter с мыслями о том, “how we can refresh C++ itself” (то есть уже надо бы его refresh
Сначала он рассказал о нескольких новых фичах, которые появились за год. Например:
- chained comparisons (причём это работает только для корректных в математическом смысле слова транзитивных условий):
if min <= index < max {}- named
break/continue, чтобы можно было выходить сразу из нескольких циклов по метке. Дальше Herb рассказывал про метапрограммирование в Cpp2, только не вот это на шаблонах, а про нормальное вроде рефлексии и всего такого (и рядом про енамы (и flag_enum) и union’ы).
И дальше рассуждал про то, как безопаснее и эффективнее всего стоит переходить на новые технологии и как этого добиться. Мне понравилось.
3. Коротенькое видео про разницу между архитектурой и дизайном. Никогда про существование разницы не думал, а ещё там местами расплывчатые формулировки, но прикольно.
4. Небольшая статья про то, зачем на самом деле (не)нужны микросервисы.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍20❤1
#common
Аналитика на фронте 1/2.
Часто в разных продуктах можно встретить анализ каких-то пользовательских действий на клиенте (в нашем случае фронтенде), т.е. в приложении. Позже они используются для аналитических и не только штук. Как это используется и почему это нужно делать на клиенте, я сегодня верхнеуровнево и расскажу (с примерами из Лавки).
В основном для анализа важны агрегированные и анонимизированные данные о поведении пользователей – это позволяет нам делать приложение еще лучше и удобнее. Важно понимать, что даже агрегированные данные хранятся аккуратно и без лишней информации. Хотя для рекомендаций и персонализации, например, поиска иногда нужно понимать действия конкретного покупателя, но и это означает отсутствие открытых данных пользователей.
Теперь давайте поймём, почему данных на бекенде может быть недостаточно.
Взаимодействие фронтенд-бекенд обычно выглядит как дёрнули endpoint, получили данные и что-то отобразили пользователю. После этого пользователь может совершать множество разных действий, про которые на бекенде ничего не известно. Например тот факт, что клиент (фронтенд) запросил информацию от бекенда, не означает, что пользователь увидел эти данные; или что он в приложении что-то покликал и сделал какие-то важные для бизнеса действия; или невозможно на бекенде понять, как много пользователь провёл времени в приложении.
Какие пользовательские события можно анализировать?
Из полезного можно смотреть на просмотр контента пользователем. Если смотреть на сервисы вроде instagram/tiktok (у которых контент – основной инструмент привлечения пользователя) то им важно анализировать какой контент и как долго смотрит пользователь. От этого зависят их рекомендации – если пользователь долго смотрит видео с котиками, значит ему вероятно стоит показывать такого контента больше. Хотя конечно тут есть более сильные сигналы вроде лайка/дизлайка, которые также говорят, стоит ли подобное рекомендовать (однако я слышал, что в некоторых сервисах на дизлайки почти не смотрят). Но сегодня рексистемы у таких сервисов довольно мощные, чтобы суметь распознать ваши предпочтения по просмотрам (я например нигде ничего не лайкаю, но контентом наслаждаюсь).
Аналитика на фронте 1/2.
Часто в разных продуктах можно встретить анализ каких-то пользовательских действий на клиенте (в нашем случае фронтенде), т.е. в приложении. Позже они используются для аналитических и не только штук. Как это используется и почему это нужно делать на клиенте, я сегодня верхнеуровнево и расскажу (с примерами из Лавки).
В основном для анализа важны агрегированные и анонимизированные данные о поведении пользователей – это позволяет нам делать приложение еще лучше и удобнее. Важно понимать, что даже агрегированные данные хранятся аккуратно и без лишней информации. Хотя для рекомендаций и персонализации, например, поиска иногда нужно понимать действия конкретного покупателя, но и это означает отсутствие открытых данных пользователей.
Теперь давайте поймём, почему данных на бекенде может быть недостаточно.
Взаимодействие фронтенд-бекенд обычно выглядит как дёрнули endpoint, получили данные и что-то отобразили пользователю. После этого пользователь может совершать множество разных действий, про которые на бекенде ничего не известно. Например тот факт, что клиент (фронтенд) запросил информацию от бекенда, не означает, что пользователь увидел эти данные; или что он в приложении что-то покликал и сделал какие-то важные для бизнеса действия; или невозможно на бекенде понять, как много пользователь провёл времени в приложении.
Какие пользовательские события можно анализировать?
Из полезного можно смотреть на просмотр контента пользователем. Если смотреть на сервисы вроде instagram/tiktok (у которых контент – основной инструмент привлечения пользователя) то им важно анализировать какой контент и как долго смотрит пользователь. От этого зависят их рекомендации – если пользователь долго смотрит видео с котиками, значит ему вероятно стоит показывать такого контента больше. Хотя конечно тут есть более сильные сигналы вроде лайка/дизлайка, которые также говорят, стоит ли подобное рекомендовать (однако я слышал, что в некоторых сервисах на дизлайки почти не смотрят). Но сегодня рексистемы у таких сервисов довольно мощные, чтобы суметь распознать ваши предпочтения по просмотрам (я например нигде ничего не лайкаю, но контентом наслаждаюсь).
❤1
#common
Аналитика на фронте 2/2.
В нашем случае важными действиями для рекомендаций можно считать клики на конкретные товары (если пользователь кликнул на продукт, значит ему он интересен). Но есть и более сильные сигналы вроде добавления в корзину/покупки товара (добавить в корзину != купить). Подобную информацию можно также использовать, чтобы понимать, какие товары часто покупают вместе и учитывать это при рекомендациях.
Мы ещё используем данные о кликах (CTR) для ранжирования в поиске. Как мы писали в статье, мы учитываем, как часто пользователи кликают на конкретные товары для конкретного запроса. Логика простая: если большинству пользователей на фиксированном запросе понравился конкретный товар, то возможно текущему пользователю он тоже понравится, так что надо поднять его повыше.
Также подобную информацию можно использовать для различных оффлайн процессов. Если продолжать говорить про наш поиск, мы можем взять события просмотра поисковой выдачи и достать реальные пользовательские запросы. Далее мы можем получить выдачу от нашего поискового движка на этот конкретный запрос и отправить эти данные в Толоку. После того, как в Толоке данные будут размечены на (не)релевантность, мы можем собрать разные статистики и понять, насколько хорошо мы сейчас что-то ищем (тут правда стоит понимать, что в данной метрике речь идёт про качество (precision), а не полноту (recall)), собрать примеры нерелевантной выдачи и каким-то образом их починить.
Ну или можно посмотреть, как много пользователей смотрят вашу полную выдачу/полные рекомендации, чтобы понимать, стоит ли делать выдачу больше/рекомендовать больше товаров. То есть если вы показываете пользователю 100 товаров и при этом 50% долистывают до конца, можно сделать вывод, что пользователь не нашёл то, что хотел бы купить -> можем показать ещё сто товаров.
Ну и конечно это всё используется для аналитиков. Обычно эти данные уезжают в какое-то OLAP-хранилище, где можно выполнять сложные аналитические запросы. Это позволяет исследовать какие-то гипотезы про происходившее или находить новые зависимости (что иногда позволяет понимать, какие-то боли пользователей -> решать их и делать продукт лучше).
Аналитика на фронте 2/2.
В нашем случае важными действиями для рекомендаций можно считать клики на конкретные товары (если пользователь кликнул на продукт, значит ему он интересен). Но есть и более сильные сигналы вроде добавления в корзину/покупки товара (добавить в корзину != купить). Подобную информацию можно также использовать, чтобы понимать, какие товары часто покупают вместе и учитывать это при рекомендациях.
Мы ещё используем данные о кликах (CTR) для ранжирования в поиске. Как мы писали в статье, мы учитываем, как часто пользователи кликают на конкретные товары для конкретного запроса. Логика простая: если большинству пользователей на фиксированном запросе понравился конкретный товар, то возможно текущему пользователю он тоже понравится, так что надо поднять его повыше.
Также подобную информацию можно использовать для различных оффлайн процессов. Если продолжать говорить про наш поиск, мы можем взять события просмотра поисковой выдачи и достать реальные пользовательские запросы. Далее мы можем получить выдачу от нашего поискового движка на этот конкретный запрос и отправить эти данные в Толоку. После того, как в Толоке данные будут размечены на (не)релевантность, мы можем собрать разные статистики и понять, насколько хорошо мы сейчас что-то ищем (тут правда стоит понимать, что в данной метрике речь идёт про качество (precision), а не полноту (recall)), собрать примеры нерелевантной выдачи и каким-то образом их починить.
Ну или можно посмотреть, как много пользователей смотрят вашу полную выдачу/полные рекомендации, чтобы понимать, стоит ли делать выдачу больше/рекомендовать больше товаров. То есть если вы показываете пользователю 100 товаров и при этом 50% долистывают до конца, можно сделать вывод, что пользователь не нашёл то, что хотел бы купить -> можем показать ещё сто товаров.
Ну и конечно это всё используется для аналитиков. Обычно эти данные уезжают в какое-то OLAP-хранилище, где можно выполнять сложные аналитические запросы. Это позволяет исследовать какие-то гипотезы про происходившее или находить новые зависимости (что иногда позволяет понимать, какие-то боли пользователей -> решать их и делать продукт лучше).
❤1
#common #cpp #go #highload
Про время [и программирование].
Тут получилось чуть больше инфы, чем обычно. А ещё картинки есть. Потому в телеграфе.
https://telegra.ph/Ne-podskazhete-skolko-vremeni-10-28
Про время [и программирование].
Тут получилось чуть больше инфы, чем обычно. А ещё картинки есть. Потому в телеграфе.
https://telegra.ph/Ne-podskazhete-skolko-vremeni-10-28
Telegraph
Не подскажете, сколько времени?
Когда мы говорим про время, мы обычно имеем в виду физическое время -- время, которое идёт от какой-то общей точки отсчёта и для всех одно и то же. Правда уже тут начинаются проблемы. Например, человечество построило себе несколько разных осей времени:
👍12❤1😐1
#cpp
0. Я тут на днях увидел, что иногда форвардят не только какие-то аргументы при вызове
В
Зачем это делать для самого функтора?
Дело в том, что в пользовательском функторе
И если вы не форвардите сам функтор, вы теряете его категорию значений, что может привести к вызову не той перегрузки.
1. Доклад Andrei Alexandrescu с CppCon 2023 про улучшение бинарного поиска и размышления про ChatGPT. Как обычно, очень харизматичный чувак. И, как обычно, хороший доклад.
2. Маленький пост про заблуждения в распределённых системах. В целом довольно очевидный, но от этого не менее полезный.
0. Я тут на днях увидел, что иногда форвардят не только какие-то аргументы при вызове
operator() у функторов, но и и сами функторы. Пример из вероятной реализации std::apply:template<class F, class Tuple, std::size_t... I>
decltype(auto) apply_impl(F&& f, Tuple&& t, index_sequence<I...>) {
return std::forward<F>(f)(std::get<I>(std::forward<Tuple>(t))...);
}
template<class F, class Tuple>
decltype(auto) apply(F&& f, Tuple&& t) {
using Indices = make_index_sequence<std::tuple_size<Tuple>::value>;
return apply_impl(std::forward<F>(f), std::forward<Tuple>(t), Indices());
}В
apply_impl есть такая строчка:return std::forward<F>(f)(std::get<I>(std::forward<Tuple>(t))...);Зачем это делать для самого функтора?
Дело в том, что в пользовательском функторе
operator() могут быть перегружены по категории значения:operator()() & {…}
operator()() && {…}И если вы не форвардите сам функтор, вы теряете его категорию значений, что может привести к вызову не той перегрузки.
1. Доклад Andrei Alexandrescu с CppCon 2023 про улучшение бинарного поиска и размышления про ChatGPT. Как обычно, очень харизматичный чувак. И, как обычно, хороший доклад.
2. Маленький пост про заблуждения в распределённых системах. В целом довольно очевидный, но от этого не менее полезный.
👍7❤1
#common #highload
1. Пост Вадима Кравченко про привычки крутых разрабов.
Тут же есть ссылочка на прикольный доклад про навык приближённых вычислений (так называемую napkin math).
2. Конференция DUMP 2023 выложила записи докладов. Мне честно по темам как-то ничего не зашло, потому не смотрел. Но может вам что-то понравится.
3. Lessons Learned from Twenty Years of Site Reliability Engineering от инженеров Google.
4. Небольшая заметка про написание логов.
5. C++20, Spans, Threads and Fun.
6. Building a reliable notification system.
================================
Понедельник-вторник буду на HIghload++ 2023. Если вдруг зачем-то надо, можно найти меня на одном из стендов Яндекса : )
1. Пост Вадима Кравченко про привычки крутых разрабов.
Тут же есть ссылочка на прикольный доклад про навык приближённых вычислений (так называемую napkin math).
2. Конференция DUMP 2023 выложила записи докладов. Мне честно по темам как-то ничего не зашло, потому не смотрел. Но может вам что-то понравится.
3. Lessons Learned from Twenty Years of Site Reliability Engineering от инженеров Google.
4. Небольшая заметка про написание логов.
5. C++20, Spans, Threads and Fun.
6. Building a reliable notification system.
================================
Понедельник-вторник буду на HIghload++ 2023. Если вдруг зачем-то надо, можно найти меня на одном из стендов Яндекса : )
👍9🔥2❤1 1 1 1 1
#cpp #highload #common
0. У Константина Владимирова есть маленький пост про отличие ключевых слов
1. Trip report от Herb Sutter про собрание комитета C++ на Kona, Usa про прогресс C++26.
2. Новая статья от Вадима Кравченко: Security at Startup.
3. How Pinterest scaled to 11 million users with only 6 engineers.
0. У Константина Владимирова есть маленький пост про отличие ключевых слов
class и struct: t.me/cpp_lects_rus/146 . Развал. 1. Trip report от Herb Sutter про собрание комитета C++ на Kona, Usa про прогресс C++26.
2. Новая статья от Вадима Кравченко: Security at Startup.
3. How Pinterest scaled to 11 million users with only 6 engineers.
👍7❤1🤯1
Собрал посты за этот год.
2022: link.
Посты:
- ещё полезности из опыта;
- о шаблонах из доклада Alexandrescu;
- доклады с highload от 05.2022 и не только: первая часть, вторая часть;
- выжимка с открытой встречи РГ21 C++;
- про инициализацию;
- базово про кодировки;
- some cute tricks;
- про атрибуты;
- первоапрельский пост🤡;
- про проблемы с union и function-try-block;
- про ревью;
- несколько докладов с Saint Highload++ 2022;
- hashcash для пагинации;
- концептуально про рекомендательные системы;
- про разные оптимизации в C++;
- A/B-тестирование;
- чуть-чуть про содержимое gcc;
- С++ Zero Cost Conf 2023: Москва, Белград;
- проект моих ребят: 3music.app;
- про быстрое вычисление линейных дп матрицами;
- “обновил” пост про дженерики;
- про аналитику на фронте;
- про время;
- пачки фактов и ссылок: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14, 15, 16, 17, 18, 19;
Про поиск:
- про различные задачи поиска;
- что обычно есть в поисковых движках;
- boolean retrieval model;
- про исправление опечаток.
Одна cтатья:
- три движка для одной Лавки: как эволюционировала система поиска в сервисе.
Одно выступление:
- обработка ошибок и C++ на Intern Meetup Week.
Не техническое:
- как я себя мотивирую табличкой в экселе;
- мотивашки на каждый день.
====================================
И про остальное. Фулл версия тут: t.me/dzikart/42
Подался на highload и не прошёл. Зато сгонял на него посмотреть вживую. Раньше таких мероприятий не посещал.
Впервые за много лет выбрался за пределы привычной обстановки и немного (хотя непонятно, почти два месяца вне дома это много или мало) покатался заграницу. Очень сильно разгружает.
Почти весь год ходил к психологу и очень вкачал голову. Всё-таки, если с умом к этому подходить, можно ощутимо продвинуться.
Уволился из универа. Опыт замечательный, но хочется направить силы на более полезные на перспективу занятия.
В этом учебном году это скорее нерегулярная дополнительная активность, чем постоянная нагрузка.
Иногда пишу в @dzikart, иногда что-то пощу в @memesfromhole и недавно открыл @khdocs.
4 раза получал предложения что-то тут порекламить за денюжку. Не поддался (может быть пока).
Особо не болел. Занимался спортом. Наконец-то читал книжки и отрастил бороду.
Взял топ-1 на чемпионате по кикеру в минском офисе Яндекса😼
[Вроде пока] бросил [регулярное] употребление никотина❌
Новых татуировок нет.
Не умер, что особенно приятно.
2022: link.
Посты:
- ещё полезности из опыта;
- о шаблонах из доклада Alexandrescu;
- доклады с highload от 05.2022 и не только: первая часть, вторая часть;
- выжимка с открытой встречи РГ21 C++;
- про инициализацию;
- базово про кодировки;
- some cute tricks;
- про атрибуты;
- первоапрельский пост🤡;
- про проблемы с union и function-try-block;
- про ревью;
- несколько докладов с Saint Highload++ 2022;
- hashcash для пагинации;
- концептуально про рекомендательные системы;
- про разные оптимизации в C++;
- A/B-тестирование;
- чуть-чуть про содержимое gcc;
- С++ Zero Cost Conf 2023: Москва, Белград;
- проект моих ребят: 3music.app;
- про быстрое вычисление линейных дп матрицами;
- “обновил” пост про дженерики;
- про аналитику на фронте;
- про время;
- пачки фактов и ссылок: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14, 15, 16, 17, 18, 19;
Про поиск:
- про различные задачи поиска;
- что обычно есть в поисковых движках;
- boolean retrieval model;
- про исправление опечаток.
Одна cтатья:
- три движка для одной Лавки: как эволюционировала система поиска в сервисе.
Одно выступление:
- обработка ошибок и C++ на Intern Meetup Week.
Не техническое:
- как я себя мотивирую табличкой в экселе;
- мотивашки на каждый день.
====================================
И про остальное. Фулл версия тут: t.me/dzikart/42
Подался на highload и не прошёл. Зато сгонял на него посмотреть вживую. Раньше таких мероприятий не посещал.
Впервые за много лет выбрался за пределы привычной обстановки и немного (хотя непонятно, почти два месяца вне дома это много или мало) покатался заграницу. Очень сильно разгружает.
Почти весь год ходил к психологу и очень вкачал голову. Всё-таки, если с умом к этому подходить, можно ощутимо продвинуться.
Уволился из универа. Опыт замечательный, но хочется направить силы на более полезные на перспективу занятия.
В этом учебном году это скорее нерегулярная дополнительная активность, чем постоянная нагрузка.
Иногда пишу в @dzikart, иногда что-то пощу в @memesfromhole и недавно открыл @khdocs.
4 раза получал предложения что-то тут порекламить за денюжку. Не поддался (может быть пока).
Особо не болел. Занимался спортом. Наконец-то читал книжки и отрастил бороду.
Взял топ-1 на чемпионате по кикеру в минском офисе Яндекса
[Вроде пока] бросил [регулярное] употребление никотина
Новых татуировок нет.
Не умер, что особенно приятно.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥30❤4❤🔥4👍4
this->notes. pinned «Собрал посты за этот год. 2022: link. Посты: - ещё полезности из опыта; - о шаблонах из доклада Alexandrescu; - доклады с highload от 05.2022 и не только: первая часть, вторая часть; - выжимка с открытой встречи РГ21 C++; - про инициализацию; - базово…»
#cpp
С Новым Годом🥳 Начнём 2024й с простенького.
Curiously recurring template pattern.
CRTP -- типичный подход к реализации статического полиморфизма.
Давайте посмотрим на реализацию:
Тут мы завели родителя, который предоставляет некоторый интерфейс и умеет вызывать метод у ребёнка, кастуя себя к его типу. А вот у ребёнка происходит наследование от родителя, которого мы параметризовали этим самым ребёнком. Потому этот подход так и называется.
Ну и дальше можем использовать наше решение:
Из плюсов мы больше не тратим в рантайме время на то, чтобы прыгать по виртуальным таблицам и поиск нужного метода нужного ребёнка для вызова. Тут есть статья про реальную стоимость виртуальных вызовов, так что иногда это может быть полезной оптимизацией: The true price of virtual functions in C++.
С другой стороны, очевидно, вы не можете класть несколько таких детей в один вектор. Потому что родители разных детей с точки зрения компилятора это разные типы:
Другой тип тут нормально не положишь.
Пользоваться этим нужно аккуратно. Например в реализации выше следующий код -- ub:
А ещё легко словить проблемы, если вдруг вы отнаследуете разные классы от родителя с одним и тем же параметром в шаблоне.
И концептуально важный момент. Исходя из того, как устроен подход, это эмуляция наследования, когда ребёнок расширяет логику родителя (а не наоборот). Так что архитектурно этот подход не везде применим.
Где это используется?
Кроме кейсов выше популярна задача написания "миксинов" -- специальных классов, которые расширяют логику работы класса какими-то конкретными методами. Вообще концептуально подразумевается, что от миксинов не наследуются, а скорее они каким-то образом "инклудятся" в классы, но в плюсах (и других языках, например python), такие вещи всё же реализуют через наследование.
Из примеров подобного -- std::enable_shared_from_this. Представим, что мы хотим сделать метод, который будет возвращать std::shared_ptr на наш класс:
При каждом вызове этого метода будет создаваться новая компонента связности шеред птров, из-за чего будет как минимум double-free. Корректно сделать так:
Обычно такую структуру реализуют с std::weak_ptr внутри, который и раздаёт std::shared_ptr.
Можно продолжить в этом направлении и реализовать, например,
- миксин, который будет добавлять operator>, если у класса есть operator<;
- миксин, при наследовании от которого у вас автоматически считается количество живых в данный момент программы экземпляров ребёнка.
(это простые задачки, так что оставим упражнением).
Для первого даже в буст либу завезли (boost::operators), которая позволяет избежать бойлерплейта при написании операторов.
Тут можно посмотреть больше примеров использования CRTP.
============================
Хорошего года, ребят🥳 🥳 🥳
С Новым Годом
Curiously recurring template pattern.
CRTP -- типичный подход к реализации статического полиморфизма.
Давайте посмотрим на реализацию:
template <typename Child>
struct Parent {
int SomeFunc() {
return static_cast<Child*>(this)->SomeFunc();
}
};
struct Child : Parent<Child> {
int SomeFunc() { return 228; }
};
Тут мы завели родителя, который предоставляет некоторый интерфейс и умеет вызывать метод у ребёнка, кастуя себя к его типу. А вот у ребёнка происходит наследование от родителя, которого мы параметризовали этим самым ребёнком. Потому этот подход так и называется.
static_cast к указателю на ребёнка из this называется "Barton and Nickman trick".
Ну и дальше можем использовать наше решение:
Parent* p = new Child;
std::cout << p->SomeFunc();
Из плюсов мы больше не тратим в рантайме время на то, чтобы прыгать по виртуальным таблицам и поиск нужного метода нужного ребёнка для вызова. Тут есть статья про реальную стоимость виртуальных вызовов, так что иногда это может быть полезной оптимизацией: The true price of virtual functions in C++.
С другой стороны, очевидно, вы не можете класть несколько таких детей в один вектор. Потому что родители разных детей с точки зрения компилятора это разные типы:
std::vector<Parent<Child>> v;
Другой тип тут нормально не положишь.
Пользоваться этим нужно аккуратно. Например в реализации выше следующий код -- ub:
// Parent<Child> p; p.SomeFunc(); // CE!
А ещё легко словить проблемы, если вдруг вы отнаследуете разные классы от родителя с одним и тем же параметром в шаблоне.
И концептуально важный момент. Исходя из того, как устроен подход, это эмуляция наследования, когда ребёнок расширяет логику родителя (а не наоборот). Так что архитектурно этот подход не везде применим.
Где это используется?
Кроме кейсов выше популярна задача написания "миксинов" -- специальных классов, которые расширяют логику работы класса какими-то конкретными методами. Вообще концептуально подразумевается, что от миксинов не наследуются, а скорее они каким-то образом "инклудятся" в классы, но в плюсах (и других языках, например python), такие вещи всё же реализуют через наследование.
Из примеров подобного -- std::enable_shared_from_this. Представим, что мы хотим сделать метод, который будет возвращать std::shared_ptr на наш класс:
struct bad {
std::shared_ptr<bad> get() {
return std::shared_ptr<bad>(this);
}
};
При каждом вызове этого метода будет создаваться новая компонента связности шеред птров, из-за чего будет как минимум double-free. Корректно сделать так:
struct good : std::enable_shared_from_this<good> {
std::shared_ptr<good> get() {
return shared_from_this(); // from enable_shared_from_this
}
};
Обычно такую структуру реализуют с std::weak_ptr внутри, который и раздаёт std::shared_ptr.
Можно продолжить в этом направлении и реализовать, например,
- миксин, который будет добавлять operator>, если у класса есть operator<;
- миксин, при наследовании от которого у вас автоматически считается количество живых в данный момент программы экземпляров ребёнка.
(это простые задачки, так что оставим упражнением).
Для первого даже в буст либу завезли (boost::operators), которая позволяет избежать бойлерплейта при написании операторов.
Тут можно посмотреть больше примеров использования CRTP.
============================
Хорошего года, ребят
Please open Telegram to view this post
VIEW IN TELEGRAM
👍29🍌9❤6🔥2🥰2👎1🗿1
#algo #cpp #highload
0. Продолжаю отсматривать CppCon 2023. Пока закину один доклад, про который вы наверняка знаете от самого автора: A Long Journey of Changing std::sort Implementation at Scale - Danila Kutenin.
1. My favourite memory leak.
Короткий видос (всего 4 минуты), но какая красота..
2. Интересная статья про succinct data structures.
3. Architecture antipatterns.
4. Scrambling Eggs for Spotify with Knuth's Fibonacci Hashing.
Прикольный пост про перемешивание треков и разные подходы к этому.
0. Продолжаю отсматривать CppCon 2023. Пока закину один доклад, про который вы наверняка знаете от самого автора: A Long Journey of Changing std::sort Implementation at Scale - Danila Kutenin.
1. My favourite memory leak.
Короткий видос (всего 4 минуты), но какая красота..
2. Интересная статья про succinct data structures.
3. Architecture antipatterns.
4. Scrambling Eggs for Spotify with Knuth's Fibonacci Hashing.
Прикольный пост про перемешивание треков и разные подходы к этому.
👍3 3 2❤1 1
#highload
Я всё-таки пытаюсь взять себя в руки и разобрать огромную кучу тем, про которые хочется написать, потому
Рейтлимитинг.
https://telegra.ph/Rejtlimiting-01-14
Я всё-таки пытаюсь взять себя в руки и разобрать огромную кучу тем, про которые хочется написать, потому
Рейтлимитинг.
https://telegra.ph/Rejtlimiting-01-14
Telegraph
Рейтлимитинг
Зачем нужно лимитирование нагрузок? Пусть ответ на этот вопрос и является довольно понятным, давайте всё же посмотрим на несколько кейсов: ваш сервис участвует в некотором сезонном событии, которое потенциально приносит огромную нагрузку. Конечно в таком…
👍19 4❤1
#algo #cpp
🥳 Недавно понял, что в статье, где упоминал sparse set, не описал процесс удаления одного элемента из него.
Предположим, у нас есть такой sparse set:
Тут два случая:
- удаляемый элемент находится в конце. Тогда просто уменьшаем размер (удаляем 4):
Мб про sparse set как-нибудь статью на хабр накидаю.
😎 Дальше с CppCon 2023:
- Exceptionally Bad: The Misuse of Exceptions in C++ & How to Do Better;
- The Au C++ Units Library: Handling Physical Units Safely, Quickly, & Broadly;
- C++ Modules: Getting Started Today;
- std::linalg: Linear Algebra coming to Standard C++.
На последнем мы немножко остановимся и глянем, что же там такое есть. cppref с описанием того, что лежит в хедере (правда там все подстраницы пустые ещё).
Хедер включается так:
Докладчик рассказывает про несколько важных кусков, о которых думают, когда речь идёт о библиотеках для линала:
- многомерные массивы и итерация по ним (доступно сейчас в C++17 и расширяется с C++23 (mdspan) и C++26 (submdspan));
- работа и базовые операции с векторами (в математическом смысле) и матрицами (как раз то, что предполагается затянуть в новой либе);
- low-level math problems, такие как решение систем линейных уравнений, поиск собственных значений и прочее (сейчас нет пропозалов по этим кускам в язык, но есть различные third-party либы);
- higher-level math problems: statistical inference и другие штуки.
Единицей работы с объектами является std::mdspan. Из базовых операцией над матрицами вы можете делать:
- scale -- умножение на скаляр;
- conjugated -- получение сопряжённой;
- transposed -- неоижиданно, транспонирование;
- conjugate_transpose.
Для векторов: scale, add, dot, vector_sum_of_squares, vector_two_norm, vector_abs_sum и другие.
Для операций матрица-вектор: matrix_vector_product и другие умножения, а так же какие-то rank-1 update, которые я сходу не осознал ввиду скудности остаточных знаний в математике.
Для матрица-матрица кроме произведения аналогично много всяких других произведений и каких-то апдейтов. Только ещё есть произведение/решение систем для треугольных матриц.
В целом большая часть доклада это рассказ про "стандарт" BLAST, эффективные вычисления и прочее около. В конце чувак показывает, как можно сделать разложение Холецкого с помощью новой либы.
🙂 Хотел недавно на clang 16.xxx + libc++ поюзать
Круто, да? А вот хер там был! Почитайте пояснение. Так сказать, СМОТРЕТЬ ДО КОНЦА🤔 ❌ ❌
🤨 А ещё на днях не обнаружил у
Предположим, у нас есть такой sparse set:
dense: 0 1 2 3 4 |
sparse: 0 1 2 3 4
| показывает текущий конец сета. Тут два случая:
- удаляемый элемент находится в конце. Тогда просто уменьшаем размер (удаляем 4):
dense: 0 1 2 3 | 4
sparse: 0 1 2 3 4
- удаляемый элемент не в конце. Тогда меняем его местами с последним и опять уменьшаем размер (удаляем 1):dense: 0 3 2 | 1 4
sparse: 0 3 2 1 4
Готово! Сделал пр в folly. Мб про sparse set как-нибудь статью на хабр накидаю.
😎 Дальше с CppCon 2023:
- Exceptionally Bad: The Misuse of Exceptions in C++ & How to Do Better;
- The Au C++ Units Library: Handling Physical Units Safely, Quickly, & Broadly;
- C++ Modules: Getting Started Today;
- std::linalg: Linear Algebra coming to Standard C++.
На последнем мы немножко остановимся и глянем, что же там такое есть. cppref с описанием того, что лежит в хедере (правда там все подстраницы пустые ещё).
Хедер включается так:
#include <linalg>Докладчик рассказывает про несколько важных кусков, о которых думают, когда речь идёт о библиотеках для линала:
- многомерные массивы и итерация по ним (доступно сейчас в C++17 и расширяется с C++23 (mdspan) и C++26 (submdspan));
- работа и базовые операции с векторами (в математическом смысле) и матрицами (как раз то, что предполагается затянуть в новой либе);
- low-level math problems, такие как решение систем линейных уравнений, поиск собственных значений и прочее (сейчас нет пропозалов по этим кускам в язык, но есть различные third-party либы);
- higher-level math problems: statistical inference и другие штуки.
Единицей работы с объектами является std::mdspan. Из базовых операцией над матрицами вы можете делать:
- scale -- умножение на скаляр;
- conjugated -- получение сопряжённой;
- transposed -- неоижиданно, транспонирование;
- conjugate_transpose.
Для векторов: scale, add, dot, vector_sum_of_squares, vector_two_norm, vector_abs_sum и другие.
Для операций матрица-вектор: matrix_vector_product и другие умножения, а так же какие-то rank-1 update, которые я сходу не осознал ввиду скудности остаточных знаний в математике.
Для матрица-матрица кроме произведения аналогично много всяких других произведений и каких-то апдейтов. Только ещё есть произведение/решение систем для треугольных матриц.
В целом большая часть доклада это рассказ про "стандарт" BLAST, эффективные вычисления и прочее около. В конце чувак показывает, как можно сделать разложение Холецкого с помощью новой либы.
constexpr std::string. Хотелка в целом понятная и простая: завести constexpr переменную в global scope:constexpr std::string kSomeVal = "string";Круто, да? А вот хер там был! Почитайте пояснение. Так сказать, СМОТРЕТЬ ДО КОНЦА
std::stack метод clear. И что это!Please open Telegram to view this post
VIEW IN TELEGRAM
🔥7 2❤1👍1
#cpp #common
🤔 🤔 🤔
На днях пришла гениальная мысль стандартизировать
Вообще я помню свою небольшую эволюцию в подсчёте единичных битов. Очевидно, можно сделать втупую:
Потом я узнал, что можно считать за кол-во единичных битов (ого как мы ускорились!):
А потом я нашёл статью на хабре и понял, что не знаю ещё очень много. Впрочем, ничего нового.
Там оказывается подвезли много всего. Из понятно-полезного std::has_single_bit -- является ли число степенью двойки.
🤨 🤨 🤨
Ещё недавно решил поюзать
Круто, скажете вы!Не работает, скажу я. Можно почитать тут.
😏 😏 😏
Валера написал интересный пост про реализацию SharedMutex в yaclib: https://news.1rj.ru/str/reverse13/720
☕️ ☕️ ☕️
У Вадима Кравченко недавно вышел хороший пост про код-ревью.
Ну и хватит пока. И вам, и мне.
На днях пришла гениальная мысль стандартизировать
__builtin_popcount. Глупец! В C++20 уже есть std::popcount.Вообще я помню свою небольшую эволюцию в подсчёте единичных битов. Очевидно, можно сделать втупую:
while (n > 0) {
if (n & 1) ++cnt;
n >>= 1;
}Потом я узнал, что можно считать за кол-во единичных битов (ого как мы ускорились!):
while (n > 0) {
n &= n - 1;
}А потом я нашёл статью на хабре и понял, что не знаю ещё очень много. Впрочем, ничего нового.
Там оказывается подвезли много всего. Из понятно-полезного std::has_single_bit -- является ли число степенью двойки.
Ещё недавно решил поюзать
constexpr std::string. Основной кейс юзания у меня это завести константы вродеconstexpr std::string kSomeText = "short_text";Круто, скажете вы!
Валера написал интересный пост про реализацию SharedMutex в yaclib: https://news.1rj.ru/str/reverse13/720
У Вадима Кравченко недавно вышел хороший пост про код-ревью.
Ну и хватит пока. И вам, и мне.
Please open Telegram to view this post
VIEW IN TELEGRAM
#cpp #algo #pub
Написал пост про разреженные структуры данных в дополнение к инфе про sparse set.
https://habr.com/ru/articles/790844/
Написал пост про разреженные структуры данных в дополнение к инфе про sparse set.
https://habr.com/ru/articles/790844/
Хабр
Разреженные структуры данных
Разреженное небо над Дианой и Конём Боджеком Когда-то я писал пост про различные интересные структуры данных . Среди них был т.н. sparse set. Там мы описали его в общих чертах, опустив некоторые...
#cpp #common
0. Интересный докладик о C++20 Nicolai Josuttis с ACCU 2022: My Favourite Code Examples.
1. Прилетел доклад Антона Полухина с C++ Russia 2023: C++ трюки из userver.
Я вообще не то чтобы поклонник его докладов в последнее время, потому что он часто рассказывает примерно одно и то же + внутри слышу про разные штуки сильно раньше, чем снаружи. Повторение одного и того же конечно двигает продукт, о котором рассказывают (userver в данном случае), но никак не двигает сообщество вперёд. Стагнация какая-то. Но этот доклад зашёл. Прикона.
Ну и на осеннем хайлоаде был интересный. И на CppRussia в этом году тоже как будто интересный будет. Может всё не прям так, как я описываю.
2. Parsing Numbers At Compile Time with C++17, C++23, and C++26.
3. Прикольный лайтнинг про проблему нахождение среднего двух чисел: Finding the Average of 2 Integers. И в дополнение вот такой доклад, но уже побольше: std::midpoint? How Hard Could it Be?
не решение (вроде очевидно) и почему
тоже не решение.
4. How to (and how not to) design REST APIs.
0. Интересный докладик о C++20 Nicolai Josuttis с ACCU 2022: My Favourite Code Examples.
1. Прилетел доклад Антона Полухина с C++ Russia 2023: C++ трюки из userver.
Я вообще не то чтобы поклонник его докладов в последнее время, потому что он часто рассказывает примерно одно и то же + внутри слышу про разные штуки сильно раньше, чем снаружи. Повторение одного и того же конечно двигает продукт, о котором рассказывают (userver в данном случае), но никак не двигает сообщество вперёд. Стагнация какая-то. Но этот доклад зашёл. Прикона.
Ну и на осеннем хайлоаде был интересный. И на CppRussia в этом году тоже как будто интересный будет. Может всё не прям так, как я описываю.
2. Parsing Numbers At Compile Time with C++17, C++23, and C++26.
3. Прикольный лайтнинг про проблему нахождение среднего двух чисел: Finding the Average of 2 Integers. И в дополнение вот такой доклад, но уже побольше: std::midpoint? How Hard Could it Be?
std::midpoint -- функция для нахождения среднего двух чисел -- заехала в C++20. В докладе дед рассказывает, почему (a + b) / 2не решение (вроде очевидно) и почему
a + (b - a) / 2тоже не решение.
4. How to (and how not to) design REST APIs.
👍3❤1🤔1