初识Redis

文章目录


第1关:Redis中的数据结构

编程要求

根据提示,打开命令行,启动 Redis 客户端并创建一些值:

使用默认配置后台启动 Redis 服务器

启动 Redis 客户端 redis-cli

设置字符串

键为 hello

值为 redis

设置列表,键为 educoder-list

从列表左侧推入元素 hello

从列表右侧推入元素 educoder

从列表右侧推入元素 bye

从列表右侧弹出一个元素

设置集合,键为 educoder-set

添加元素 c

添加元素 python

添加元素 redis

删除元素 c

设置哈希,键为 educoder-hash

添加键:python,值为:language

添加键:ruby,值为:language

添加键: redis,值为:database

删除键 ruby

设置有序列表,键为 educoder-zset

添加成员 jack,分值为 200

添加成员 rose,分值为 400

添加成员 lee,分值为 100

测试说明

我会对你编写的代码进行测试:

测试输入:无;

预期输出:

redis

{'python': 'language', 'redis': 'database'}

'hello', 'educoder'

set(['python', 'redis'])

('lee', 100.0), ('jack', 200.0), ('rose', 400.0)

这是整体的第一关代码,在这篇文章是分开的代码点击此处跳转至该文章

代码示例如下(第一关的代码是按行粘贴,在命令行输入的):

c 复制代码
redis-cli
set hello redis
lpush educoder-list hello
rpush educoder-list educoder
rpush educoder-list bye
rpop educoder-list
sadd educoder-set c
sadd educoder-set python redis
del educoder-set c
hset educoder-hash python language
hset educoder-hash ruby language
hset educoder-hash redis database
hdel educoder-hash ruby
zadd educoder-zset 200 jack
zadd educoder-zset 400 rose
zadd educoder-zset 100 lee
sadd educoder-set python redis

第2关:使用 Python 与 Redis 交互

编程要求

根据提示,在右侧Begin-End区域补充代码,实现使用 Python 编写程序与 Redis 交互:

使用方法2创建客户端r1连接到 Redis

设置下表中的两个字符串键:

键 值

test1 hello

test2 Redis

测试说明

我会对你编写的代码进行测试:

获取test1和test2键的值。

测试输入:无

测试输出:

hello

Redis

代码示例如下:

c 复制代码
#!/usr/bin/env python
#-*- coding:utf-8 -*-
import redis

def write_redis():
    #********* Begin *********#
    pool = redis.ConnectionPool(host='127.0.0.1', port=6379, decode_responses=True)
    r = redis.Redis(connection_pool=pool)
    r.set("test1", "hello")
    r.set("test2", "Redis")
    #********* End *********#

第3关:使用Python+Redis实现文章投票网站后端功能编程要求

根据提示,在右侧Begin-End区域补充代码,完成简化版文章投票网站的后端处理逻辑:

在 article_vote() 函数中:

该方法作用是:对文章投票

参数说明:

r:Redis 客户端

user_id:投票用户

article_id:被投票文章

已提供一周前 Unix 时间戳,存放在变量 cutoff

当满足以下条件时,为文章投一票:

该文章发布不超过一周

该用户没有为该文章投过票

在 post_article() 函数中:

该方法作用是:创建文章

参数说明:

r:Redis 客户端

user:发布用户

title:文章标题

link:文章链接

已提供:

article_id,新文章 ID

voted,新文章已投票用户名单存储键名

article,新文章详细信息存储键名

now,文章创建时间

按照 ID 递增的顺序依次创建文章

保证发布文章的用户不能给自己的文章投票

文章在发布一周后删除已投票用户名单

存储文章详细信息到 Redis 中,包括字段:

文章标题

文章链接

发布用户

存储文章的发布时间和初始投票数

初始投票数为 1

在 get_articles() 函数中:

该方法作用是:对文章进行排序

参数说明:

r:Redis 客户端

start:从排序为 start 的文章开始获取

end:到排序为 end 的文章结束获取

order:排序方式,分为两种:

time:按时间排序

score:按投票数排序

已提供文章信息空列表,articles

实现按时间/投票数排序

将排序后的文章及其全部信息组成一个列表:

按照不同排序规则取出排序在参数提供的区间范围内的文章

及每篇文章的全部信息,包括文章 ID

测试说明

我会对你编写的代码进行测试:

测试输入:无;

预期输出:

We posted a new article with id: 1

Its HASH looks like:

{'poster': 'username', 'link': 'http://www.google.com', 'title': 'A title'}

We voted for the article, it now has votes: 2

The currently highest-scoring articles are:

{'id': '1'}

代码示例如下:

c 复制代码
#!/usr/bin/env python
#-*- coding:utf-8 -*-

import time

ONE_WEEK_IN_SECONDS = 7 * 24 * 60 * 60

def article_vote(r, user_id, article_id):
    cutoff = time.time() - ONE_WEEK_IN_SECONDS

    # 请在下面完成要求的功能
    #********* Begin *********#
    if r.zscore('time', article_id) < cutoff:
        return
    if r.sadd('voted:' + article_id, user_id):
        r.zincrby('score', article_id, 1)

    #********* End *********#

def post_article(r, user, title, link):
    article_id = str(r.incr('article'))

    voted = 'voted:' + article_id
    r.sadd(voted, user)
    r.expire(voted, ONE_WEEK_IN_SECONDS)
    now = time.time()
    article = 'article:' + article_id
    # 请在下面完成要求的功能
    #********* Begin *********#
    r.hmset(article, {
        'title': title,
        'link': link,
        'poster': user,
    })
    r.zadd('score', article_id, 1)
    r.zadd('time', article_id, now)
  
    #********* End *********#

    return article_id

def get_articles(r, start, end, order='score'):
    ids = r.zrevrange(order, start, end)
    articles = []

    # 请在下面完成要求的功能
    #********* Begin *********#
    for id in ids:
        article_data = r.hgetall(id)
        article_data['id'] = id
        articles.append(article_data)


    #********* End *********#

    return articles

第4关:字符串、列表与集合

编程要求

根据提示,在右侧Begin-End区域补充代码,完成任务分配的后端处理逻辑:

在 task_empty() 方法中:

从 Redis 中获取列表 task_list 的长度,判断是否为 0

若为 0,则返回 True

若不为 0,则返回 False

在 get_task() 方法中:

从列表 task_list 的最右侧弹出一个元素,赋值给 task

将 task 的值设置到 Redis 的字符串键 current_task 中

在 get_unallocated_staff() 方法中:

从集合 unallocated_staff 中随机返回一个元素,赋值给 staff

将上面的 staff 从集合 unallocated_staff 移动到集合 allocated_staff 中

返回(return)staff 的值

在 allocate_task(staff) 方法中:

将参数 staff 的值追加到 Redis 字符串键 current_task 的尾部,中间以 : 间隔

将追加后的字符串键 current_task 从左侧推入列表 task_queue

将字符串键 current_task 的值设置为 "None"

测试说明

我会对你编写的代码进行测试:

测试输入:

task_1 task_2 task_3 task_4 task_5

staff_1 staff_2 staff_3 staff_4 staff_5

预期输出:

Init task list: ['task_1', 'task_2', 'task_3', 'task_4', 'task_5']

Init staff list: set(['staff_4', 'staff_5', 'staff_1', 'staff_2', 'staff_3'])

Cur task list is empty: False

Get new task: task_5

Current staff is allocated: True

Current staff is unallocated: False

Current task is: None

Allocated all tasks

Task queue length: 5

Task list is empty: True

Allocated_staff: set(['staff_4', 'staff_5', 'staff_1', 'staff_2', 'staff_3'])

Unallocated_staff: set([])

代码示例如下:

c 复制代码
#!/usr/bin/env python
#-*- coding:utf-8 -*-

import redis

conn = redis.Redis()

def task_empty():
    # 请在下面完成判断任务列表是否为空
    #********* Begin *********#
    return int(conn.llen("task_list")) == 0
    #********* End *********#

def get_task():
    # 请在下面完成获取一个任务
    #********* Begin *********#
    task = conn.rpop("task_list")
    conn.set("current_task",task)

    #********* End *********#

def get_unallocated_staff():
    # 请在下面完成获取一个未分配的员工
    #********* Begin *********#
    staff=conn.srandmember("unallocated_staff")
    conn.smove("unallocated_staff","allocated_staff",staff)
    return staff
    #********* End *********#

def allocate_task(staff):
    # 请在下面完成分配任务
    #********* Begin *********#
    conn.append("current_task",':'+str(staff))
    conn.lpush("task_queue",conn.get("current_task"))
    conn.set("current_task","None")

    #********* End *********#

第5关:哈希与有序集合

编程要求

根据提示,在右侧Begin-End区域补充代码,完成带优先级的队列系统的后端处理逻辑:

在 set_task_info(task_id) 方法中:

使用参数 task_id 作为域,初始状态 "init" 作为值构成域-值对,存放在 task_status 哈希键中。

在 add_task_to_queue(task_id, priority) 方法中:

参数说明:

task_id 为任务 ID

priority 为任务优先级。

将分值(优先级)为 priority 的成员 task_id 存入有序集合 task_queue 中。

注意将参数 priority 转换为整型

调用 set_task_info() 方法,传入参数 task_id

在 get_task() 方法中:

新建变量 task_list_by_priority,值为:

使用 ZREVRANGE 命令按照分值(优先级)从大到小顺序返回有序集合 task_queue 的全部成员。

新建变量 current_task,值为:

task_list_by_priority 中的第一个元素(下标为 0)

将成员 current_task 从有序集合 task_queue 中移除

修改哈希 task_status 中的 current_task 域的值为 "processing"

返回(return)current_task 的值

测试说明

我会对你编写的代码进行测试:

测试输入:

1 2 3 4 5 6 7 8 9 10

2 4 9 1 0 5 8 6 7 3

预期输出:

Add new task: 1, priority: 2, status: init

Add new task: 2, priority: 4, status: init

Add new task: 3, priority: 9, status: init

Add new task: 4, priority: 1, status: init

Add new task: 5, priority: 0, status: init

Add new task: 6, priority: 5, status: init

Add new task: 7, priority: 8, status: init

Add new task: 8, priority: 6, status: init

Add new task: 9, priority: 7, status: init

Add new task: 10, priority: 3, status: init

Before: task list is: ['3', '7', '9', '8', '6', '2', '10', '1', '4', '5']

Get new task: 3

After: task list is: ['7', '9', '8', '6', '2', '10', '1', '4', '5']

Current task status: processing

代码示例如下:

c 复制代码
#!/usr/bin/env python
#-*- coding:utf-8 -*-

import redis

conn = redis.Redis()

# 初始化任务信息到 Redis 中
def set_task_info(task_id):
    # 请在下面完成要求的功能
    #********* Begin *********#
    conn.hset("task_status",task_id,"init")
    #********* End *********#

# 将任务添加至任务队列
def add_task_to_queue(task_id, priority):
    # 请在下面完成要求的功能
    #********* Begin *********#
    conn.zadd("task_queue",task_id,int(priority))
    set_task_info(task_id)
    #********* End *********#

# 从任务队列中取出优先级最高的任务
def get_task():
    # 请在下面完成要求的功能
    #********* Begin *********#
    task_list_by_priority=conn.zrevrange('task_queue',0,-1)
    current_task=task_list_by_priority[0]
    conn.zrem('task_queue',current_task)
    conn.hset("task_status",current_task,"processing")
    return current_task
    #********* End *********#

第6关:Redis基本事务与其他命令

编程要求

根据提示,在右侧Begin-End区域补充代码,完成网络约车的后端处理逻辑:

在 request_cab(user_id, priority) 方法中:

判断是否存在哈希键 request:info:用户ID 的 time 域:

提示:可使用 HEXISTS 命令

若存在,则直接 return

若不存在,做如下操作

使用事务提交下列命令:

将参数 user_id 从最左侧推入列表 cab:queue

使用 HMSET 命令设置哈希键 request:info:用户ID:

域 time,值为 time.time()

域 priority,值为参数 priority

将上述哈希键的过期时间设置为 10分钟

在 allocate() 方法中:

使用 SORT 命令对列表 cab:queue 排序,并将结果赋值给 cab_queue:

使用 BY 参数

参考键为哈希键 request:info:*,其中 * 为占位符

使用上述参考键中的 priority 域

使用 DESC 参数做倒序排序

取出 cab_queue 的第一个元素(下标为 0)赋值给 current_respond

从列表 cab:queue 中移除变量 current_respond 中包含的元素

返回(return)current_respond

测试说明

我会对你编写的代码进行测试:

测试输入:

1 2 3 4 5 6 7 8 9

9 8 7 6 5 4 3 2 1

预期输出:

Receive new request: 1, priority: 9, is_expired? True

Receive new request: 2, priority: 8, is_expired? True

Receive new request: 3, priority: 7, is_expired? True

Receive new request: 4, priority: 6, is_expired? True

Receive new request: 5, priority: 5, is_expired? True

Receive new request: 6, priority: 4, is_expired? True

Receive new request: 7, priority: 3, is_expired? True

Receive new request: 8, priority: 2, is_expired? True

Receive new request: 9, priority: 1, is_expired? True

Before: request queue: ['1', '2', '3', '4', '5', '6', '7', '8', '9']

Allocate new request: 1

After: request queue: ['2', '3', '4', '5', '6', '7', '8', '9']

Repeat request in few seconds:

Before: request queue length: 8

After: request queue length: 8

代码示例如下:

c 复制代码
#!/usr/bin/env python
#-*- coding:utf-8 -*-

import time
import redis

conn = redis.Redis()

# 用户端发起派车请求
def request_cab(user_id, priority):
    # 请在下面完成要求的功能
    #********* Begin *********#
    if conn.hexists('request:info:' + str(user_id), 'time'):
        return
    pipe = conn.pipeline()
    pipe.lpush('cab:queue', user_id)
    pipe.hmset('request:info:'+str(user_id), {'time': time.time(), 'priority':priority})
    pipe.expire('request:info:'+ str(user_id), 10 * 60)
    pipe.execute()
    #********* End *********#

# 平台选择优先级最高的派车请求并派车
def allocate():
    # 请在下面完成要求的功能
    #********* Begin *********#
    cab_queue=conn.sort('cab:queue',by='request:info:*->priority',desc=True)
    current_respond=cab_queue[0]
    conn.lrem('cab:queue', current_respond, 1)
    return current_respond
    #********* End *********#

# 用户端取消派车请求
def cancel_cab(user_id):
    conn.expire('request:info:' + str(user_id), 0)
    conn.lrem('cab:queue', user_id)

第7关:使用Redis管理登录令牌

编程要求

根据提示,在右侧Begin-End区域补充代码,完成令牌管理的后端处理逻辑:

在 check_token(token) 方法中:

使用 hget() 方法从哈希 login 中取出参数 token 域的值

返回(return)上述值

在 update_token(token, user_id) 方法中:

参数说明:

token 为令牌

user_id 为该令牌对应的用户 ID

获得当前时间并赋值给 timestamp

使用事务提交下列命令:

将域 token 与值 user_id 对存入哈希键 login 中

将成员 token 存入有序集合 recent:token 中,分值为 timestamp

在 clean_tokens() 方法中:

使用当前时间减去 86400 得到一周前时间戳,并赋值给 one_week_ago_timestamp

使用 zrangebyscore 方法获取有序集合 recent:token 中

分值大于等于 0

小于等于 one_week_ago_timestamp 的所有成员

并赋值给变量 expired_tokens

使用 zremrangebyscore 方法移除有序集合 recent:token 中

分值大于等于 0

小于等于 one_week_ago_timestamp 的所有成员

移除哈希 login 中所有与变量 expired_tokens 中相同的域

使用指针形式传入参数 *expired_tokens

测试说明

我会对你编写的代码进行测试:

测试输入:1,2,3,4,5

预期输出:

loged user: []

ADD!\]User 1 add token Login with 1's token, match user: 1, have_timestamp: True loged user: \['1'

ADD!\]User 2 add token Login with 2's token, match user: 2, have_timestamp: True loged user: \['1', '2'

ADD!\]User 3 add token Login with 3's token, match user: 3, have_timestamp: True loged user: \['1', '2', '3'

ADD!\]User 4 add token Login with 4's token, match user: 4, have_timestamp: True loged user: \['1', '2', '3', '4'

ADD!\]User 5 add token Login with 5's token, match user: 5, have_timestamp: True Login with expired token User not_exist_user add token Clean Tokens Login with expired token, match user: None 代码示例如下: ```c #!/usr/bin/env python #-*- coding:utf-8 -*- import time import redis conn = redis.Redis() # 核对令牌,并返回该令牌对应的用户 ID def check_token(token): # 请在下面完成要求的功能 #********* Begin *********# return conn.hget('login', token) #********* End *********# # 更新令牌,同时存储令牌的创建时间 def update_token(token, user_id): # 请在下面完成要求的功能 #********* Begin *********# timestamp = time.time() pipe = conn.pipeline() pipe.hset('login', token, user_id) pipe.zadd('recent:token', token, timestamp) pipe.execute() #********* End *********# # 清理过期令牌 def clean_tokens(): # 请在下面完成要求的功能 #********* Begin *********# one_week_ago_timestamp = time.time() - 86400 expired_tokens = conn.zrangebyscore('recent:token', 0, one_week_ago_timestamp) conn.hdel('login', *expired_tokens) #********* End *********# ``` ![在这里插入图片描述](https://file.jishuzhan.net/article/1733057043469701121/96b373bdcb0a7cf145290513b3742a6f.webp) ## 第8关:使用Redis实现购物车 编程要求 根据提示,在右侧Begin-End区域补充代码,实现购物车的后端处理逻辑: 在 add_item(name, price) 方法中: 使用 item_id 键自增作为商品 ID 商品信息键名为 item:*:info,其中* 为商品ID 为商品信息哈希键设置: 域为 "name",值为参数 name 域为 "price",值为参数 price 为商品信息哈希键设置过期时间:30 天后 返回(return)商品 ID 在 add_to_cart(user_id, item, count) 方法中: 如果参数 count 大于 0: 为哈希键 cart:*,其中* 为参数 user_id 设置: 域为参数 item 值为参数 count 否则: 移除哈希键 cart:*,其中* 为参数 user_id 中: 参数为 item 的域 在 get_cart_info(user_id) 方法中: 获取 user_id 对应用户的购物车信息并返回(return) 测试说明 我会对你编写的代码进行测试: 测试输入: pen 2.5 car 20000 shirt 99 user:1 3 2 user:2 1 8 预期输出: Add item 1! Infos: {'price': '2.5', 'name': 'pen'}, have_ttl? True Add item 2! Infos: {'price': '20000.0', 'name': 'car'}, have_ttl? True Add item 3! Infos: {'price': '99.0', 'name': 'shirt'}, have_ttl? True Add item 3 to cart user:1, count: 2, info: {'3': '2'} Add item 1 to cart user:2, count: 8, info: {'1': '8'} 代码示例如下: ```c #!/usr/bin/env python #-*- coding:utf-8 -*- import redis conn = redis.Redis() # 添加商品 def add_item(name, price): # 请在下面完成要求的功能 #********* Begin *********# item_id = conn.incr('item_id') item_info_key = 'item:' + str(item_id)+ ":info" conn.hmset(item_info_key,{"name":name,"price":price}) conn.expire(item_info_key,30 * 24 * 60 * 60) return item_id #********* End *********# # 加入购物车 def add_to_cart(user_id, item, count): # 请在下面完成要求的功能 #********* Begin *********# if count > 0: conn.hset("cart:"+user_id,item,count) else: conn.hrem('cart:'+user_id,item) #********* End *********# # 获取购物车详情 def get_cart_info(user_id): # 请在下面完成要求的功能 #********* Begin *********# return conn.hgetall("cart:"+user_id) #********* End *********# ``` ![在这里插入图片描述](https://file.jishuzhan.net/article/1733057043469701121/2a57a53e509bbb9c331ca4f6cb22ec5a.webp) ## 第9关:使用Redis做页面缓存 编程要求 根据提示,在右侧Begin-End区域补充代码,实现使用Redis缓存网页: 创建变量 page_key,值为: 对参数 request_url 哈希编码并转化成字符串 使用字符串 cache: 与上述字符串前后拼接 尝试从 Redis 中读取字符串键,键名为 page_key 的值 若读取成功,则返回该键中的值 若读取失败,则: 创建变量 content,值为: 使用字符串 content for 与参数 request_url 前后拼接 使用 SETEX 命令将变量 content 存至字符串键: 键名为 page_key 的值 生存时间为 600 秒 测试说明 我会对你编写的代码进行测试: 测试输入:无; 预期输出: Cache: request http://example.educoder.net/?productId=X, content: content for http://example.educoder.net/?productId=X, have_ttl? True Get response: 'content for http://example.educoder.net/?productId=X' Cache the request again! Get response: 'content for http://example.educoder.net/?productId=X' Cache: request http://example.educoder.net/?productId=X, content: content for http://example.educoder.net 代码示例如下: ```c #!/usr/bin/env python #-*- coding:utf-8 -*- import redis conn = redis.Redis() # 使用 Redis 做页面缓存 def cache_request(request_url): # 请在下面完成要求的功能 #********* Begin *********# page_key = 'cache:' + str(hash(request_url)) content = conn.get(page_key) if not content: content = "content for " + request_url conn.setex(page_key, content, 600) return content #********* End *********# ``` ![在这里插入图片描述](https://file.jishuzhan.net/article/1733057043469701121/21deeaa2c25cc6d48f5e5d8ce5df713f.webp) ## 第10关:使用Redis做数据缓存 编程要求 根据提示,在右侧Begin-End区域补充代码,实现使用Redis实现数据缓存: 在 add_cache_list(data_id, delay) 方法中: 参数说明: data_id 是需要缓存的数据的唯一标识 delay 是该数据的更新周期 将分值为 delay 的成员 data_id 存入有序集合 cache:delay 中 将分值为当前时间 time.time() 的成员 data_id 存入有序集合 cache:list 中 在 cache_data() 方法中: 获取到有序集合 cache:list 中根据分值排序的第一个元素并赋值给变量 next 获取当前时间 time.time() 并赋值给变量 now 若 next 不存在或 next 的第一个元素的分值大于 now: 等待 100 毫秒 从 next 中取出第一个元素的成员值并赋值给变量 data_id 根据 data_id 从有序集合 cache:delay 中取出它的更新周期并赋值给变量 delay 判断 delay 是否大于 0: 若小于等于 0: 从有序集合 cache:list 中移除 data_id 成员 从有序集合 cache:delay 中移除 data_id 成员 删除该数据对应的缓存键 cache:data:*,其中* 的值为data_id 若大于 0: 构建哈希 {'id': data_id, 'data': 'fake data'} 并赋值给变量 data,作为待缓存的伪造数据 将分值为当前时间+更新周期的成员 data_id 加入有序集合 cache:list 中 更新该成员的缓存键 cache:data:\*,值为:data 编码成 JSON 格式 json(dumps(data)) 测试说明 我会对你编写的代码进行测试: 测试输入:无; 预期输出: Schedule caching of itemX every 5 seconds Cache list looks like: \['itemX'

Cached data looks like:

'{"data": "fake data", "id": "itemX"}'

Force delete cache

The cache was cleared? True

代码示例如下:

c 复制代码
#!/usr/bin/env python
#-*- coding:utf-8 -*-

import time
import json
import redis

conn = redis.Redis()

# 将数据加入缓存队列
def add_cache_list(data_id, delay):
    # 请在下面完成要求的功能
    #********* Begin *********#
    conn.zadd('cache:delay', data_id, delay)
    conn.zadd('cache:list', data_id, time.time())
    #********* End *********#

# 缓存数据
def cache_data():
    # 请在下面完成要求的功能
    #********* Begin *********#
    next = conn.zrange('cache:list', 0, 0, withscores=True)
    now = time.time()
    if not next or next[0][1] > now:
        time.sleep(0.1)
    data_id = next[0][0]
    delay = conn.zscore('cache:delay', data_id)
    if delay <= 0:
        conn.zrem('cache:delay', data_id)
        conn.zrem('cache:list', data_id)
        conn.delete('cache:data:' + data_id)
    else:
        data = {'id': data_id, 'data': 'fake data'}
        conn.zadd('cache:list', data_id, now + delay)
        conn.set('cache:data:' + data_id, json.dumps(data))



    #********* End *********#

相关推荐
咖丨喱1 小时前
【Action帧简要分析】
服务器·数据库·asp.net
没饭吃!1 小时前
NHibernate案例
数据库·hibernate
泷羽Sec-静安1 小时前
OSCP官方靶场-Solstice WP
服务器·网络·数据库
IvanCodes1 小时前
Oracle 视图
大数据·数据库·sql·oracle
德育处主任Pro2 小时前
「py数据分析」04如何将 Python 爬取的数据保存为 CSV 文件
数据库·python·数据分析
都叫我大帅哥2 小时前
🔥 Redis缓存击穿:从“崩溃现场”到“高并发防弹衣”的终极指南
redis
许白掰2 小时前
Linux入门篇学习——Linux 编写第一个自己的命令
linux·运维·数据库·嵌入式硬件·学习
打不了嗝 ᥬ᭄2 小时前
文件系统----底层架构
linux·运维·数据库
都叫我大帅哥2 小时前
🌪️ Redis缓存穿透:当数据库被“空气”攻击时,如何优雅防御?
redis
亲爱的非洲野猪3 小时前
Oracle与MySQL详细对比
数据库·mysql·oracle