Этот случай входит вGitHub.com/Программист-NDS…
Я также был интервьюером и собеседовал многих претендентов.Поскольку я набирал людей и использовал их сам, я бы не смотрел на то, насколько хороши претенденты в строительстве ракет, а только смотрел на умение трахаться. Ведь это будет единое целое в будущем, и команде будет сложно всех тащить вниз. Вопросы на собеседовании, как правило, не так уж сложны, как и вопросыRedis, я просто хотел убедиться, что он действительно использовал его достаточно.RedisВы должны знать 5 основных структур данных и простые операции, самые основные требования.Если он может рассказать общие сценарии применения каждой структуры данных в это время, то это должно быть бонусом, по крайней мере, по сравнению с теми, кто может только назвать немного После структуры данных гораздо сильнее смотреть и ждать, пока я задам следующий вопрос, так что не стойте на месте.
Любой, кто хочет обменяться техническим опытом или опытом интервью, может добавить меняVX:xinzhifu521, вы должны знать все, так что давайте так много говорить и перейти к делу!
Каковы основные структуры данных Redis?
1. Строка
В любом языке программирования строкиStringсамые простые структуры данных, задумывались ли вы когда-нибудь оRedisКакие операции выполняются для сохранения строки в ?
существуетRedisсерединаStringможно изменить, назвать动态字符串(Simple Dynamic Stringкороткое имяSDS)(Быстро возьмите небольшую книгу, чтобы запомнить существительные, чтобы проверить), который называется строкой, но его внутренняя структура больше похожа наArrayList, который поддерживает внутренний массив байтов и предварительно выделяет в нем определенное пространство, чтобы уменьшить частое выделение памяти.
RedisМеханизм выделения памяти таков:
-
Когда длина строки меньше 1 МБ, каждое расширение удваивает существующее пространство.
-
Если длина строки превышает 1 МБ, при каждом расширении будет увеличиваться только 1 МБ пространства.
Это не только гарантирует, что места в памяти достаточно, но и не приводит к пустой трате памяти.Максимальная длина строки512MB..
Вышеуказанные фотографии взяты из Интернета, если есть какие-либо нарушения, пожалуйста, свяжитесь с нами, чтобы удалить
На приведенном выше рисунке показана базовая структура строки, в которойcontentОн хранит содержимое строки,0x\0так как конечный символ не будет учитыватьсяlenсередина.
Анализировать структуру данных строк
struct SDS{
T capacity; //数组容量
T len; //实际长度
byte flages; //标志位,低三位表示类型
byte[] content; //数组内容
}
capacityа такжеlenОба свойства являются общими, почему бы не использовать их напрямуюint类型? потому чтоRedisСуществует множество схем внутренней оптимизации, чтобы более разумно использовать память, строки разной длины представляются разными типами данных, и при создании строкlenИ воляcapacityТот же размер, избыточное пространство не создается, поэтомуStringЗначения могут быть строками, числами (целыми, с плавающей запятой) или двоичными.
1. Сценарии применения:
Сохраняйте пары ключ-значение, это относительно просто и не будем вдаваться в подробности.
2, String (String) часто используемые команды:
set [key] [value] 给指定key设置值(set 可覆盖老的值)
get [key] 获取指定key 的值
del [key] 删除指定key
exists [key] 判断是否存在指定key
mset [key1] [value1] [key2] [value2] ...... 批量存键值对
mget [key1] [key2] ...... 批量取key
expire [key] [time] 给指定key 设置过期时间 单位秒
setex [key] [time] [value] 等价于 set + expire 命令组合
setnx [key] [value] 如果key不存在则set 创建,否则返回0
incr [key] 如果value为整数 可用 incr命令每次自增1
incrby [key] [number] 使用incrby命令对整数值 进行增加 number
2. список (список)
Redisсерединаlistа такжеJavaсерединаLinkedListТак же, как нижний слой представляет собой структуру связанного списка,listОперации вставки и удаления выполняются очень быстро, а временная сложность равна 0 (1), в отличие от операций вставки и удаления структуры массива, которые требуют перемещения данных.
как возвращение домой, ноredisсерединаlistНижний слой не так прост, как двусвязный список.
Когда объем данных невелик, его основная структура хранения представляет собой непрерывную память, называемуюziplist(压缩列表), он хранит все элементы рядом друг с другом и выделяет непрерывную память; когда объем данных велик, он станетquicklist(快速链表)структура.
Но простой связанный список также несовершенен, передний и задний указатели связанного спискаprevа такжеnextЭто займет больше памяти, будет тратить больше места и увеличит фрагментацию памяти. После redis 3.2 они все переключились наziplist+链表смешанная структура, называемаяquicklist(快速链表).
Подробно представлены следующие два типа связанных списков.
ziplist (список zip)
Первый взглядziplistструктура данных,
struct ziplist<T>{
int32 zlbytes; //压缩列表占用字节数
int32 zltail_offset; //最后一个元素距离起始位置的偏移量,用于快速定位到最后一个节点
int16 zllength; //元素个数
T[] entries; //元素内容
int8 zlend; //结束位 0xFF
}
int32 zlbytes: количество байтов, занимаемых сжатым спискомint32 zltail_offset: смещение последнего элемента от начальной позиции, используемое для быстрого поиска последнего узла.int16 zllength: количество элементовT[] entries: содержимое элементаint8 zlend: конечный бит 0xFF
Для поддержки двунаправленного обхода сжатый список будет иметьztail_offsetЭто поле используется для быстрого поиска последней
элементы, а затем вернуться назад
Вышеуказанные фотографии взяты из Интернета, если есть какие-либо нарушения, пожалуйста, свяжитесь с нами, чтобы удалить
entryСтруктура данных:
struct entry{
int<var> prevlen; //前一个 entry 的长度
int<var> encoding; //元素类型编码
optional byte[] content; //元素内容
}
entryэтоprevlenполе указывает предыдущийentryДлина байта, когда сжатый список просматривается в обратном направлении, он должен передать это
поле для быстрого перехода к позиции следующего элемента.
1. Сценарии применения:
Поскольку список представляет собой список, отсортированный по порядку вставки, существует относительно много сценариев применения, например:
-
очередь сообщений:
lpopа такжеrpush(или наоборот,lpushа такжеrpop) может реализовать функцию очереди -
Список лайков, список комментариев и таблица лидеров в кругу друзей:
lpushкоманда иlrangeКоманда может реализовать функцию последнего списка, каждый раз черезlpushкоманда для вставки нового элемента в список, затем передатьlrangeКоманда для чтения последнего списка элементов.
2. Общее наименование операций со списками:
rpush [key] [value1] [value2] ...... 链表右侧插入
rpop [key] 移除右侧列表头元素,并返回该元素
lpop [key] 移除左侧列表头元素,并返回该元素
llen [key] 返回该列表的元素个数
lrem [key] [count] [value] 删除列表中与value相等的元素,count是删除的个数。 count>0 表示从左侧开始查找,删除count个元素,count<0 表示从右侧开始查找,删除count个相同元素,count=0 表示删除全部相同的元素
(PS: index 代表元素下标,index 可以为负数, index= 表示倒数第一个元素,同理 index=-2 表示倒数第二 个元素。)
lindex [key] [index] 获取list指定下标的元素 (需要遍历,时间复杂度为O(n))
lrange [key] [start_index] [end_index] 获取list 区间内的所有元素 (时间复杂度为 O(n))
ltrim [key] [start_index] [end_index] 保留区间内的元素,其他元素删除(时间复杂度为 O(n))
Три, решетка (словарь)
RedisсерединаHashи JavaHashMapболее похожи, оба数组+链表структуры, при возникновении коллизии хэшей элементы будут присоединяться к связанному списку.Стоит отметить, что вRedisизHashсерединаvalueМожет быть только строкой.
hset books java "Effective java" (integer) 1
hset books golang "concurrency in go" (integer) 1
hget books java "Effective java"
hset user age 17 (integer) 1
hincrby user age 1 #单个 key 可以进行计数 和 incr 命令基本一致 (integer) 18
Hashа такжеStringможет использоваться для хранения информации о пользователе, но разницаHashКаждое поле пользовательской информации может храниться отдельно;StringОн хранит сериализованную строку всей информации о пользователе.Если вы хотите изменить поле пользователя, вы должны запросить все строки информации о пользователе, разобрать их на соответствующие объекты информации о пользователе и сериализовать их в строки после модификации. И хэш может изменять только определенное поле, тем самым экономя сетевой трафик, но использование памяти хэша больше, чемString,ЭтоhashНедостатки.
1. Сценарии применения:
- корзина:
hset [key] [field] [value]команда, которая может быть реализована с помощью用户Id,商品Idзаfield, количество товараvalue, что в точности соответствует 3 элементам корзины. - Объект хранения:
hashТип(key, field, value)структура и объект(对象id, 属性, 值)Структура похожа и также может использоваться для хранения объектов.
2. Общие команды работы с хешем:
hset [key] [field] [value] 新建字段信息
hget [key] [field] 获取字段信息
hdel [key] [field] 删除字段
hlen [key] 保存的字段个数
hgetall [key] 获取指定key 字典里的所有字段和值 (字段信息过多,会导致慢查询 慎用:亲身经历 曾经用过这个这个指令导致线上服务故障)
hmset [key] [field1] [value1] [field2] [value2] ...... 批量创建
hincr [key] [field] 对字段值自增
hincrby [key] [field] [number] 对字段值增加number
Четыре, сет (коллекция)
Redisсерединаsetа такжеJavaсерединаHashSetВ некотором роде его внутренние пары ключ-значение неупорядочены и уникальны. Его внутренняя реализация эквивалентна специальному словарю, все значения в словаре являются значением NULL. Когда последний элемент в коллекции удаляется, структура данных автоматически удаляется, а память освобождается.
1. Сценарии применения:
- Коллекция друзей, подписчиков, поклонников и заинтересованных людей:
-
sinterКоманда может получить общих друзей пользователей A и B; -
sismemberКоманда может определить, является ли A другом B; -
scardКоманда может получить количество друзей; - Обращая внимание,
smoveКоманда может перенести B из коллекции поклонников A в коллекцию друзей A.
-
- Случайное отображение домашней страницы: на домашней странице Meituan есть много рекомендуемых продавцов, но не все из них могут отображаться.Тип набора подходит для хранения всего контента, который необходимо отобразить.
srandmemberКоманды можно получить случайным образом из нескольких. - Сохраняйте идентификатор пользователя, выигравшего в лотерею, в определенном действии.Благодаря функции дедупликации можно гарантировать, что один и тот же пользователь не выиграет в лотерею дважды.
2. Общие команды set:
sadd [key] [value] 向指定key的set中添加元素
smembers [key] 获取指定key 集合中的所有元素
sismember [key] [value] 判断集合中是否存在某个value
scard [key] 获取集合的长度
spop [key] 弹出一个元素
srem [key] [value] 删除指定元素
Пять, zset (упорядоченный набор)
zsetТакже известен какSortedSetС одной стороны этоset, что обеспечивает уникальность внутреннего значения, с другой стороны, каждому значению может присваивать значениеscore, представляющий вес сортировки этого значения. Его внутренняя реализация использует метод под названием "跳跃列表" структура данных.
1. Сценарии применения:
zsetМожет использоваться как таблица лидеров, но сlistразница в томzsetНапример, он может выполнять динамическую сортировку: его можно использовать для хранения списка поклонников, значением является идентификатор пользователя поклонника, а оценка — это время подписки.Мы можем отсортировать список подписчиков в соответствии со временем подписки.
zsetЕго также можно использовать для хранения оценок учащихся,valueЗначение - идентификатор студента,scoreЭто его результаты тестов. Мы можем получить его рейтинг, отсортировав баллы по баллам.
2. Общие рабочие команды для упорядоченных наборов zset:
zadd [key] [score] [value] 向指定key的集合中增加元素
zrange [key] [start_index] [end_index] 获取下标范围内的元素列表,按score 排序输出
zrevrange [key] [start_index] [end_index] 获取范围内的元素列表 ,按score排序 逆序输出
zcard [key] 获取集合列表的元素个数
zrank [key] [value] 获取元素再集合中的排名
zrangebyscore [key] [score1] [score2] 输出score范围内的元素列表
zrem [key] [value] 删除元素
zscore [key] [value] 获取元素的score
Суммировать
Многие концепции в этой статье были переданы только для того, чтобы дать вам примерное представление о пяти основных структурах данных и сценариях приложений Redis, чтобы дать небольшим партнерам направление для подготовки к интервью, и мы продолжим публиковать статьи Redis в будущем, Добро пожаловать, обратите внимание, давайте научимся делать предложение вместе.
Разобраны и розданы друзьям сотни различных технических электронных книг. Подпишитесь на официальный аккаунт, чтобы ответить【666] Самовывоз. Мы создали группу технического обмена с друзьями, чтобы обсуждать технологии и делиться технической информацией, стремясь вместе учиться и развиваться. Если вам интересно, присоединяйтесь к нам!