Хранили ли вы просмотры в базе данных или использовали холодные просмотры?
Что проверяют
Понимаете ли вы, что счётчик просмотров это высокочастотная запись, и что отправлять её в ту же таблицу, где лежит контент, значит положить базу. Заодно проверяют, уточняете ли вы термин, если он звучит не общепринято: «холодные просмотры» в разных командах означают разное.
Как отвечать
Сначала уточните, что имеется в виду: счётчик, который живёт в кэше и периодически сбрасывается в базу, или старые данные, вынесенные в холодное хранилище. Дальше разложите по слоям.
- Горячий счётчик:
INCRв Redis по ключу видаviews:item:<id>, сброс в базу пачкой раз в несколько секунд, на странице показывается значение из кэша. - Сырые события: не
UPDATEпо строке контента, а поток или таблица только на добавление, из неё считаются агрегаты. - Аналитика: колоночное хранилище или файлы в объектном хранилище, разбор отдельным процессом, а не запросом из приложения.
- Честность цифры: окно дедупликации по паре пользователь и объект, приблизительный подсчёт уникальных через
HyperLogLog.
Главное, что хочет услышать интервьюер, это компромисс: точность против стоимости. Счётчик в памяти теряет часть инкрементов при рестарте, для просмотров это приемлемо, для биллинга нет, и решение зависит от того, кто потом читает эту цифру.
Где спотыкаются
Пишут UPDATE items SET views = views + 1 на каждый показ. Получают горячую строку, очередь блокировок на популярном объекте и распухание таблицы, за которым автовакуум не успевает. Тут же обычно выясняется, что кандидат не знает, почему в Postgres обновление создаёт новую версию строки.
Обещают точность до единицы там, где её нет. Если счётчик живёт в кэше, часть значений теряется при падении процесса, и это надо проговаривать вслух, а не выяснять на проде.
Смешивают слои: гоняют аналитические запросы с группировкой по дням за год по той же базе, которая обслуживает пользовательские запросы. Дальше обсуждение уходит в реплику для чтения, и полезно самому предложить её как первый дешёвый шаг.