this->notes. – Telegram
this->notes.
4.53K subscribers
25 photos
1 file
330 links
О разработке, архитектуре и C++.

Tags: #common, #cpp, #highload и другие можно найти поиском.
Задачки: #poll.
Мои публикации: #pub.
Автор и предложка: @vanyakhodor.
GitHub: dasfex.
Download Telegram
#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 (причём это работает только для корректных в математическом смысле слова транзитивных условий):

if min <= index < max {}

- named break/continue, чтобы можно было выходить сразу из нескольких циклов по метке.

Дальше Herb рассказывал про метапрограммирование в Cpp2, только не вот это на шаблонах, а про нормальное вроде рефлексии и всего такого (и рядом про енамы (и flag_enum) и union’ы).

И дальше рассуждал про то, как безопаснее и эффективнее всего стоит переходить на новые технологии и как этого добиться. Мне понравилось.

3. Коротенькое видео про разницу между архитектурой и дизайном. Никогда про существование разницы не думал, а ещё там местами расплывчатые формулировки, но прикольно.

4. Небольшая статья про то, зачем на самом деле (не)нужны микросервисы.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍201
#common

Аналитика на фронте 1/2.

Часто в разных продуктах можно встретить анализ каких-то пользовательских действий на клиенте (в нашем случае фронтенде), т.е. в приложении. Позже они используются для аналитических и не только штук. Как это используется и почему это нужно делать на клиенте, я сегодня верхнеуровнево и расскажу (с примерами из Лавки).

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

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

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

Из полезного можно смотреть на просмотр контента пользователем. Если смотреть на сервисы вроде instagram/tiktok (у которых контент – основной инструмент привлечения пользователя) то им важно анализировать какой контент и как долго смотрит пользователь. От этого зависят их рекомендации – если пользователь долго смотрит видео с котиками, значит ему вероятно стоит показывать такого контента больше. Хотя конечно тут есть более сильные сигналы вроде лайка/дизлайка, которые также говорят, стоит ли подобное рекомендовать (однако я слышал, что в некоторых сервисах на дизлайки почти не смотрят). Но сегодня рексистемы у таких сервисов довольно мощные, чтобы суметь распознать ваши предпочтения по просмотрам (я например нигде ничего не лайкаю, но контентом наслаждаюсь).
1
#common

Аналитика на фронте 2/2.

В нашем случае важными действиями для рекомендаций можно считать клики на конкретные товары (если пользователь кликнул на продукт, значит ему он интересен). Но есть и более сильные сигналы вроде добавления в корзину/покупки товара (добавить в корзину != купить). Подобную информацию можно также использовать, чтобы понимать, какие товары часто покупают вместе и учитывать это при рекомендациях.

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

Также подобную информацию можно использовать для различных оффлайн процессов. Если продолжать говорить про наш поиск, мы можем взять события просмотра поисковой выдачи и достать реальные пользовательские запросы. Далее мы можем получить выдачу от нашего поискового движка на этот конкретный запрос и отправить эти данные в Толоку. После того, как в Толоке данные будут размечены на (не)релевантность, мы можем собрать разные статистики и понять, насколько хорошо мы сейчас что-то ищем (тут правда стоит понимать, что в данной метрике речь идёт про качество (precision), а не полноту (recall)), собрать примеры нерелевантной выдачи и каким-то образом их починить.
Ну или можно посмотреть, как много пользователей смотрят вашу полную выдачу/полные рекомендации, чтобы понимать, стоит ли делать выдачу больше/рекомендовать больше товаров. То есть если вы показываете пользователю 100 товаров и при этом 50% долистывают до конца, можно сделать вывод, что пользователь не нашёл то, что хотел бы купить -> можем показать ещё сто товаров.

Ну и конечно это всё используется для аналитиков. Обычно эти данные уезжают в какое-то OLAP-хранилище, где можно выполнять сложные аналитические запросы. Это позволяет исследовать какие-то гипотезы про происходившее или находить новые зависимости (что иногда позволяет понимать, какие-то боли пользователей -> решать их и делать продукт лучше).
1
#cpp

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. Маленький пост про заблуждения в распределённых системах. В целом довольно очевидный, но от этого не менее полезный.
👍71
#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. Если вдруг зачем-то надо, можно найти меня на одном из стендов Яндекса : )
👍9🔥211111
#cpp #highload #common

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.
👍71🤯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
🔥304❤‍🔥4👍4
this->notes. pinned «Собрал посты за этот год. 2022: link. Посты: - ещё полезности из опыта; - о шаблонах из доклада Alexandrescu; - доклады с highload от 05.2022 и не только: первая часть, вторая часть; - выжимка с открытой встречи РГ21 C++; - про инициализацию; - базово…»
#cpp

С Новым Годом🥳 Начнём 2024й с простенького.

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🍌96🔥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.
Прикольный пост про перемешивание треков и разные подходы к этому.
👍33211
#algo #cpp

🥳 Недавно понял, что в статье, где упоминал sparse set, не описал процесс удаления одного элемента из него.
Предположим, у нас есть такой 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, эффективные вычисления и прочее около. В конце чувак показывает, как можно сделать разложение Холецкого с помощью новой либы.

🙂 Хотел недавно на clang 16.xxx + libc++ поюзать constexpr std::string. Хотелка в целом понятная и простая: завести constexpr переменную в global scope:

constexpr std::string kSomeVal = "string";

Круто, да? А вот хер там был! Почитайте пояснение. Так сказать, СМОТРЕТЬ ДО КОНЦА🤔

🤨 А ещё на днях не обнаружил у std::stack метод clear. И что это!
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥721👍1
#cpp #common

🤔🤔🤔
На днях пришла гениальная мысль стандартизировать __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
17👍141
#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?

std::midpoint -- функция для нахождения среднего двух чисел -- заехала в C++20. В докладе дед рассказывает, почему

(a + b) / 2

не решение (вроде очевидно) и почему

a + (b - a) / 2

тоже не решение.

4. How to (and how not to) design REST APIs.
👍31🤔1
#common

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

2. И у вастрика новый пост про отличия инди и корпоратов! Пишет конечно хорошо.

Ну и хватит сегодня. Не буду душить количеством.
❤‍🔥4👍41🐳11
#common #highload

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

Что же это за данные, как мы всё починили и немножко базы можно почитать по ссылке : )

https://telegra.ph/Nebolshaya-arhitekturnaya-istoriya-iz-Lavki-03-04
👍15🤔5❤‍🔥2🔥2🤡2211
#cpp

Получился очень загруженный месяц. Чтобы не уходить в новый с одним постом закидываю второй😂

0. C++26 — прогресс и новинки от ISO C++.

1. На reddit есть тред про то, как сложно заставить вектор освободить память.

Давайте предположим, что у нас есть какой-то вектор с данными. Мы хотим его почистить.

Естественным желанием будет вызвать clear(). Но clear() только установит size_ в ноль (ну конечно ещё почистит объекты). Это в целом логично и естественно, т.к. помогает писать более производительный код.

operator= тоже не чистит память. Например можно глянуть на __assign_with_size (одна из веток в операторе копирования).

Ну можно ещё попробовать shrink_to_fit(). И хотя обычно компиляторы честно чистят ненужную память, стандарт говорит, что это non-binding метод (i.e. необязательный). С другой стороны, ну говорит и говорит. Компиляторы обычно чистят, значит норм.

Стопроцентным вариантом будет просто присвоить пустой вектор:

vec = std::vector<T>{};

Ну или деструктор явно позвать🥳

> Пока копался c вектором, обнаружил новый метод в std::list: prepend_range (C++23). В других контейнерах подобные тоже подъехали.

2. [видео] Eric Landström: The bugs I remember.

3. Core Guidelines are not Rules.

4. И выцепил пару пропозалов из февральской рассылки:
- inplace_vector
- std::constexpr_v
- std::unitialized<T>

==============================
Там выходит C++Russia 2023 на ютубчик. Не хочу выкладывать по докладу. Подождём ещё какое-то время, пока появятся все доклады, которые мне понравились, и закину пачкой.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍15411
#highload

Две недели не читал статьи! Нагоняем.

0. Серия статей про backend for frontend.
Я когда писал про него коротенький пост и на тот момент ещё не прям понимал, зачем такое делать. Сейчас преисполнился чуть больше. Основные юзкейсы, которые я видел, были про формирование готовой разметки для клиента. Почему это не может делать бекенд? Ну может. Есть же всякие разные server side ui и прочее, но в среднем это скорее про околофронтовые знания, которые тесно связаны с нативом, отображением и около. Короче это про хорошее разделение зон ответственности.
Ну и про другие плюсы можно почитать как раз в статьях.

1. Новый пост (ну как, двухнедельной давности) Вадима Кравченко: Mental Health in Software Engineering.

2. Microservices Design Principles You Really Need To Learn.
Вроде понятные штуки, но вдруг кто-то что-то для себя найдёт.

3. Guide on Structured Logs.
Я в целом про такое задумывался, как такое можно сделать и будет ли полезно. Оказывается есть отдельное название и тулзы. Но у нас как будто такое будет не очень полезно.

4. Optimizing Postgres Column Order.
Звучит хорошо конечно, но такое иногда сложно поддерживать. У нас есть таблички, в которые хотя бы раз в месяц добавляется новая колонка. И непонятно, как меинтейнить порядок в случае такой ситуации.
Ну и как будто может понятность страдать, если вдруг в табличку часто смотрят глазами, но наверное это не то, про что стоит думать при проектировании.
1👍1🤔1