#common
Узнал про такую штуку как hashcash. Он используется в различных криптоштуках в качестве proof-of-work. Но сейчас мы не будем останавливаться на битке и подобных вещах. Хочется рассказать о том, как такое можно использовать в житейских простых задачах вроде пагинации (писал немного про неё тут).
С реализацией пагинации могут быть некоторые проблемы, если выдача у вас нестабильная. То есть офсет и курсор это круто, если множество данных у вас плюс-минус фиксировано и их порядок не меняется (плюс-минус, потому что можно добрасывать новое в конец и ничего в моменте не сломать). Но такая ситуация не всегда. Например вы хотите сделать пагинацию для рекомендашек. При каждом запросе у вас происходит полный цикл процесса рекомендаций, в конце которого (в упрощённом случае) находится ранжирование. Т.к. это обычно машинки и фичей бывает очень много (а они ещё могут очень быстро меняться) сущность, которую вы отранжировали на 1ю позицию в первом запросе, при втором запросе может вполне себе отранжироваться на 21ю. И с курсором 20 во втором запросе вы получите в выдаче то, что уже показывали. Почти наверняка это плохое решение, потому что пользователь уже видел этот контент и деняк больше вы не заработаете. Да и выглядит стьюпидно.
В зависимости от реализации поискового движка может возникнуть та же проблема.
Получается, надо где-то сохранить инфу о том, что мы пользователю уже показывали. Учитывая, что эта инфа валидна только для конкретного юзера, почти наверняка придётся каким-то образом получать данные с клиента (читай фронта). Давайте тогда запихнём эту инфу в курсор, который теперь будет иметь немного более сложный вид: это будет конкатенированная строка хешей объектов, которые мы отдали. И собственно из рексистемы отдадим эту строку как курсор клиенту, после чего он может прислать этот курсор обратно, а мы уже поймём по нему, что мы показывали, а что нет.
Хешировать тут можно всё что хотите. Хорошим вариантом будет какой-нибудь уникальный для каждой сущности idшник, множество которых вы просто заджойните в одну длинную строку. Потом можно засплитить эту строку по разделителю в множество хешей и проверить, какие айтемы вы уже пользователю отдавали, а какие нет. Это конечно может быть долговато, но можно покрутить хеш-функцию.
Собственно примерно поэтому и называется hashcash: вы кешируете множество объектов с помощью кеширования каждого из них.
Ещё из проблем тут есть:
- т.к. хеширование двух различных объектов может давать один хеш, вы можете отсеять что-то, что на самом деле не показывали, но, насколько я могу понимать, это обычно не крит, потому что с таким же успехом товар мог отфильтроваться на каком-нибудь другом этапе рекомендаций (отбор кандидатов, после ранжирования оказаться слишком низко, реранкинг). Если такое возникает часто, опять же можно посмотреть в сторону других хеш-функций, которые дают более разнообразные результаты;
- т.к. с каждым запросом кол-во показанных сущностей растёт, сам курсор тоже будет расти. Тут можно выбрать какое-то ограничение для длины курсора с трейдоффом кол-во показанного юзеру контента <-> технические возможности вашей системы. Если вы понимаете, что из всех пользователей долистывает до 300ого айтема только полпроцента, может не так страшно не показывать больше 300 объектов? Ну и оч длинную строку парсить на бекенде не хочется, т.к. это потенциально таймауты (а ещё та же проблема на клиенте, а ещё нагрузка на сеть вырастает). Можно опять же выбрать хеш-функцию так, чтобы она давала более короткие хеши, но тут важно не переборщить, чтобы не получить прошлую проблему в большом объёме.
Концептуально про рекомендательные системы расскажу попозже.
Post #230
1.16K
- 👍 14
- ❤ 1
- 🤔 1
- 🤯 1