深入理解Redis:数据类型、事务机制及其应用场景

在当今快速发展的技术领域中,Redis作为一种高性能的内存数据库,已经被广泛应用于各种场景,从简单的缓存实现到复杂的数据处理任务。其灵活性和高效性主要来源于对多种数据结构的支持以及强大的功能特性,如事务处理、持久化选项、高可用性和分布式模型等。本文旨在深入探讨Redis的核心概念,包括它提供的多种数据类型、事务机制的工作原理,以及这些特性的典型使用场景。通过对这些内容的学习,读者可以更好地理解如何利用Redis来优化自己的应用程序,提高系统的响应速度和可靠性。无论是对于开发人员还是系统架构师而言,掌握Redis的高级用法都将是一项非常有价值的技术投资。让我们开始这段Redis的探索之旅吧。

1. redis的数据类型,以及每种数据类型的使用场景

Redis 提供了多种数据类型,每种数据类型都有其特定的使用场景。以下是 Redis 支持的主要数据类型及其适用场景:

1. 字符串(String)

  • 描述:最基本的数据类型,可以存储字符串、整数或浮点数。
  • 适用场景
    • 缓存简单的值,如用户会话信息。
    • 计数器应用,比如网站访问次数。
    • 分布式锁实现。

2. 哈希(Hash)

  • 描述:哈希是一个键值对集合,适合用于存储对象。
  • 适用场景
    • 存储用户资料、产品详情等结构化数据。
    • 当需要更新对象的部分字段时非常有用,避免了整个对象的重写。

3. 列表(List)

  • 描述:一个有序的字符串列表,可以从两端进行插入和删除操作。
  • 适用场景
    • 实现队列系统,例如任务队列。
    • 最近浏览记录、最新消息等时间序列数据。
    • 简单的消息中间件。

4. 集合(Set)

  • 描述:无序且不重复的字符串集合。
  • 适用场景
    • 标签系统,为文章添加标签。
    • 维护好友列表,确保每个用户只出现一次。
    • 进行交集、并集、差集运算,适用于社交网络中的共同好友查找等功能。

5. 有序集合(Sorted Set)

  • 描述:类似于集合,但每个元素关联了一个分数(score),通过分数排序。
  • 适用场景
    • 排行榜系统,根据用户的积分来排名。
    • 定时任务调度,根据任务执行的时间顺序排列。
    • 按照优先级处理的任务队列。

6. Bitmaps

  • 描述:实际上不是一种独立的数据类型,而是字符串类型的特殊形式,允许以位为单位进行操作。
  • 适用场景
    • 用户在线状态跟踪,用一位表示一个用户是否在线。
    • 统计活跃用户数量,例如每日登录用户数。

7. HyperLogLogs

  • 描述:用于基数估计的算法,能够高效地估算集合中不同元素的数量。
  • 适用场景
    • 统计唯一访客数量,而不需要精确计数。
    • 大规模数据集中去重统计。

8. 地理空间索引(Geospatial Indexes)

  • 描述:支持地理坐标的位置存储,并提供基于位置的服务功能。
  • 适用场景
    • 附近地点搜索,如查找附近的餐馆或朋友。
    • 路径规划,计算两点之间的距离。

选择合适的数据类型对于最大化 Redis 的性能和效率至关重要。理解各种数据类型的特性和适用场景可以帮助你更有效地设计和实现应用程序。

2.redis的过期策略以及内存淘汰机制

Redis 提供了灵活的过期策略和内存淘汰机制,帮助用户管理数据的有效性和内存使用情况。下面详细介绍这两种机制。

过期策略

Redis 允许为每个键设置一个生存时间(TTL, Time To Live),当达到设定的时间后,该键将自动失效并被删除。Redis 实现了两种主要的过期策略来处理这些带有过期时间的键:

  1. 惰性删除

    • 当访问某个键时,Redis 会检查这个键是否已经过期。如果过期,则返回不存在,并从数据库中删除该键。
    • 这种方式的优点是节省 CPU 资源,因为只有在访问到特定键时才会进行检查;缺点是如果存在大量已过期但未被访问的键,则它们将继续占用内存直到被访问或通过其他方式清理。
  2. 定期删除

    • Redis 会周期性地随机检查一些设置了过期时间的键,并删除那些已经过期的键。
    • 定期删除试图平衡惰性删除带来的延迟问题,通过主动检查来释放不再需要的内存空间。

内存淘汰机制

当 Redis 使用的内存超过了配置的最大限制 (maxmemory) 时,它需要决定如何处理新来的写入请求。此时,Redis 可以根据预设的策略选择移除某些键以腾出空间。以下是几种常见的内存淘汰策略:

  • noeviction:默认策略,当内存达到上限时,任何写操作都会返回错误,但读操作仍然可以继续。
  • allkeys-lru:移除最近最少使用的键(LRU, Least Recently Used),适用于大多数缓存场景。
  • volatile-lru:仅移除设置了过期时间的键中最少使用的键。
  • allkeys-randomvolatile-random:随机移除键,前者针对所有键,后者只针对设置了过期时间的键。
  • allkeys-lfuvolatile-lfu:移除最不经常使用的键(LFU, Least Frequently Used),相比 LRU 更加考虑频率而非时间,需要 Redis 4.0 或更高版本支持。

选择哪种策略取决于你的应用需求。例如,如果你的应用对一致性要求较高,可能倾向于选择 volatile-lruallkeys-lru 来确保频繁访问的数据不会轻易丢失;而在不太关心数据一致性的场合下,allkeys-random 或者 volatile-random 可能就足够了。

此外,合理设置 maxmemory 参数以及结合使用 RDB 或 AOF 持久化策略,可以帮助更好地管理和保护 Redis 中的数据。同时,利用 Redis 的持久化功能可以在重启后恢复数据,进一步增强了系统的可靠性和稳定性。

3.Redis 为什么是单线程的

Redis 选择单线程模型主要是基于简化设计、提高性能和避免并发问题的考虑。以下是几个关键原因解释了为什么 Redis 采用单线程架构:

1. 简化并发控制

  • 避免锁竞争:在多线程环境中,为了保证数据的一致性和正确性,通常需要引入复杂的锁机制来管理并发访问。而单线程模型天然避免了这些问题,因为所有操作都是顺序执行的,不需要担心多个线程同时修改同一数据块导致的数据不一致或竞争条件。

2. 减少上下文切换开销

  • 降低CPU切换成本:多线程程序中,操作系统需要频繁地在线程间切换以分配处理器时间,这会带来额外的上下文切换开销。单线程则完全避免了这种开销,使得更多的计算资源可以专注于处理实际的任务。

3. 高效利用内存

  • 事件驱动I/O:Redis 使用非阻塞I/O模型,并通过事件驱动的方式(如 epoll/kqueue)高效地处理大量客户端连接请求。由于所有命令都是由一个线程按顺序执行,因此可以非常高效地管理和响应这些请求,最大限度地减少延迟。

4. 数据结构优化

  • 针对高性能优化的数据结构:Redis 实现了多种高度优化的数据结构(例如字符串、哈希表、列表、集合等),并为这些结构提供了快速的操作方法。由于是单线程运行,这些操作可以在没有锁争用的情况下迅速完成,从而提高了整体性能。

5. 内存驻留数据

  • 全内存操作:Redis 的核心功能是作为一个内存数据库运行,这意味着大部分操作都在内存中进行,速度极快。对于内存中的操作而言,单线程已经足够快,并且能够提供良好的可预测性和稳定性。

6. 扩展性与集群模式

  • 分布式扩展能力:虽然 Redis 单实例是单线程的,但它支持横向扩展,即通过增加更多 Redis 实例或者使用 Redis Cluster 来分布负载。这种方式允许系统根据需求灵活扩展,而不受限于单个实例的性能瓶颈。

综上所述,尽管 Redis 是单线程的,但由于其专注于内存中的高速数据访问、高效的 I/O 处理机制以及简洁的设计,它仍然能够在许多场景下提供卓越的性能表现。此外,Redis 也提供了诸如持久化、发布/订阅、事务等多种高级特性,进一步增强了它的实用性和灵活性。对于那些需要更高吞吐量的应用,可以通过部署多个 Redis 实例或使用 Redis Cluster 来满足需求。

4. Redis 常见性能问题和解决方案?

Redis 是一种高性能的内存数据库,但在实际应用中如果不正确地配置或使用它,可能会遇到性能瓶颈。以下是 Redis 常见的性能问题及其解决方案:

1. 内存使用过高

  • 原因:数据量过大、未设置合适的过期策略、未启用LRU(Least Recently Used)淘汰策略等。
  • 解决方案
    • 优化数据结构的选择和存储方式。
    • 合理设置 maxmemorymaxmemory-policy 参数,以控制内存使用并根据需要选择适当的淘汰策略。
    • 定期检查和清理不再使用的键。

2. 持久化操作影响性能

  • 原因:RDB快照生成或者AOF重写过程中会占用大量I/O资源,可能导致短暂的服务不可用或响应变慢。
  • 解决方案
    • 调整 RDB 快照频率,避免过于频繁的快照生成。
    • 使用 AOF 持久化时,考虑关闭 fsync 操作或将 fsync 设置为每秒一次,减少对性能的影响。
    • 对于高可用性要求较高的场景,可以考虑使用主从复制来减轻持久化对主节点的压力。

3. 网络延迟

  • 原因:客户端与服务器之间的往返时间(RTT)较长,尤其是在跨数据中心部署的情况下。
  • 解决方案
    • 使用 Pipeline 批量处理命令以减少网络往返次数。
    • 在地理上分散的应用程序架构中,考虑在靠近用户的地方部署 Redis 实例或使用缓存代理。

4. 阻塞命令

  • 原因:某些 Redis 命令如 KEYS, SORT, SMEMBERS 等,在处理大数据集时可能会导致长时间阻塞主线程。
  • 解决方案
    • 尽量避免使用可能造成阻塞的命令;改用 SCAN 系列命令代替 KEYS 进行迭代查询。
    • 如果必须执行这类命令,确保它们不会在高峰期运行,并尽量限制结果集大小。

5. 客户端连接数过多

  • 原因:当客户端数量激增时,可能导致 Redis 的文件描述符耗尽,进而影响服务稳定性。
  • 解决方案
    • 增加系统级别的最大文件描述符限制。
    • 在 Redis 配置中调整 maxclients 参数以适应更高的并发需求。
    • 实施连接池技术,复用现有的连接而不是每次都创建新连接。

6. 数据库加载

  • 原因:当 Redis 启动并从磁盘加载数据库文件(RDB 或 AOF)时,这个过程可能会很慢,特别是在数据库文件很大时。
  • 解决方案
    • 优化持久化文件大小,定期清理不必要的数据,升级硬件配置提高读取速度。

7. 缓存穿透、击穿、雪崩等问题

  • 解决方案
    • 缓存穿透:使用布隆过滤器预先判断请求是否有效;对于不存在的数据也进行缓存。
    • 缓存击穿:热点数据不过期,或采用互斥锁防止同时重建缓存。
    • 缓存雪崩:通过随机化TTL、热点数据不过期等方式防止大量缓存同时失效。

8. 监控与预警

  • 建议:建立有效的监控系统,实时跟踪 Redis 的性能指标,包括但不限于内存使用率、CPU使用率、命中率、连接数等,并设置预警机制以便及时采取行动。

通过识别这些问题并采取相应的措施,可以显著提高 Redis 的性能和可靠性。持续关注 Redis 的最新发展和最佳实践也是保持高效运营的关键。

5.为什么Redis的操作是原子性的,怎么保证原子性的?

Redis 的操作之所以被认为是原子性的,主要是因为它采用了单线程模型来处理所有客户端请求。这意味着 Redis 在任意时刻只会执行一个命令,并且这个命令会从开始到结束完整地执行完毕,不会被其他命令打断。这种设计确保了命令的原子性,即每个命令都是作为一个不可分割的操作来执行的。

原子性保证

  1. 单线程执行

    • Redis 采用单线程执行所有命令,因此不存在多个命令同时修改同一数据的情况。这就保证了即使是复杂的复合命令(如 INCRDECR 等),也能保证其原子性。
  2. 内置原子操作

    • Redis 提供了一些专门设计为原子性的命令,比如计数器操作 (INCR, DECR) 和列表操作 (LPUSH, RPUSH) 等,这些命令在实现上就保证了它们是原子性的。
  3. 事务支持

    • Redis 支持事务通过 MULTIEXECDISCARDWATCH 等命令来实现。当使用 MULTI 开始一个事务后,直到 EXEC 被调用之前的所有命令会被放入队列中,然后由 EXEC 指令一次性按顺序执行。这样可以确保一系列命令要么全部成功执行,要么都不执行,从而保持一致性。
    • 注意:Redis 事务与传统数据库中的事务不同,它不支持回滚功能。
  4. Lua 脚本

    • Redis 允许用户编写 Lua 脚本来执行复杂逻辑。由于 Lua 脚本是在 Redis 单线程环境中运行的,因此整个脚本的执行也是原子性的。这使得你可以将一系列相关操作封装在一个 Lua 脚本中,确保这些操作作为一个整体被执行。
  5. 乐观锁机制

    • 使用 WATCH 命令可以监视一个或多个键,在执行事务前如果这些键没有被其他客户端修改,则事务可以正常提交;否则,事务将会失败。这种方法被称为乐观锁,适用于需要检测并发修改的情况。

总结

Redis 通过单线程模型和特定的设计来保证命令的原子性。对于简单的命令,单线程模型自然地提供了原子性保障;而对于更复杂的场景,可以通过事务、Lua 脚本或者乐观锁机制来实现原子性操作。这样的设计不仅简化了并发控制,还提高了系统的可靠性和性能。然而,需要注意的是,虽然 Redis 的事务不同于传统的关系型数据库事务,不具备回滚能力,但它仍然能很好地满足大多数应用场景下的需求。

6.了解Redis的事务吗?

Redis 提供了事务支持,尽管与传统关系型数据库中的事务概念有所不同。Redis 事务通过 MULTIEXECDISCARDWATCH 等命令来实现。以下是 Redis 事务的基本概念和工作原理:

基本概念

  1. MULTI:标记一个事务块的开始。一旦调用了 MULTI,客户端发送的所有后续命令将不会立即执行,而是被放入队列中等待后续的 EXEC 命令来执行。

  2. EXEC:执行所有在 MULTI 命令之后入队的命令,并一次性返回所有这些命令的结果。当 EXEC 被调用时,Redis 会顺序执行事务队列中的每个命令。

  3. DISCARD:取消事务,放弃执行事务队列中的所有命令,并清空事务队列。

  4. WATCH:用于监视一个或多个键,在 EXEC 执行前如果这些键被其他客户端修改,则事务将不会被执行,EXEC 将返回一个错误指示事务失败。这是一种乐观锁机制,适用于需要检测并发修改的情况。

工作流程

  • 使用 MULTI 开始一个新的事务。
  • 发送希望在事务中执行的命令序列。这些命令不是立即执行,而是被放入队列中。
  • 最后使用 EXEC 提交事务,此时 Redis 会按顺序执行之前排队的所有命令,并返回每条命令的执行结果。
  • 如果在事务期间决定不执行这些命令,可以使用 DISCARD 来取消事务。
MULTI
INCR foo
INCR bar
EXEC

上述例子中,foobar 的增量操作会被原子地执行,要么全部成功,要么全部失败(除非遇到某些特殊的错误情况)。

注意事项

  • 无回滚机制:不同于传统数据库的事务,Redis 不支持回滚。如果事务中的某个命令执行失败,其余命令仍然会被执行。因此,应用程序层面需要对可能的错误进行处理。

  • 乐观锁(WATCH):为了防止在事务执行过程中数据被其他客户端修改而导致的数据一致性问题,可以使用 WATCH 命令。这允许你监控一个或多个键,如果在 EXEC 执行前这些键被其他客户端修改过,那么整个事务将会失败。

WATCH mykey
MULTI
INCR mykey
EXEC

在这个例子中,如果 mykeyWATCH 后到 EXEC 执行前被其他客户端修改了,EXEC 将返回 (nil) 表示事务未被执行。

总结

Redis 事务提供了一种方法来批量执行命令,确保这些命令作为一个整体被处理。虽然它缺乏传统数据库事务的完整功能集(如回滚),但对于许多应用场景来说,这种简单的事务模型已经足够,并且由于其简单性,通常能提供更好的性能表现。理解并正确使用 Redis 的事务特性可以帮助开发者构建更可靠的应用程序。

7.Redis 的数据类型及使用场景

Redis 支持多种数据类型,每种数据类型都有其特定的使用场景。以下是 Redis 的主要数据类型及其适用场景:

1. 字符串(String)

  • 描述:最基本的数据结构,可以存储字符串、整数或浮点数。
  • 适用场景
    • 缓存简单的值,如用户会话信息、配置设置等。
    • 计数器应用,例如网站点击计数。
    • 分布式锁实现。

2. 哈希(Hash)

  • 描述:键值对的集合,适合用于存储对象。
  • 适用场景
    • 存储用户资料、产品详情等结构化数据。
    • 当需要更新对象的部分字段时非常有用,避免了整个对象的重写。

3. 列表(List)

  • 描述:一个有序的字符串列表,可以从两端进行插入和删除操作。
  • 适用场景
    • 实现队列系统,例如任务队列。
    • 最近浏览记录、最新消息等时间序列数据。
    • 简单的消息中间件。

4. 集合(Set)

  • 描述:无序且不重复的字符串集合。
  • 适用场景
    • 标签系统,为文章添加标签。
    • 维护好友列表,确保每个用户只出现一次。
    • 进行交集、并集、差集运算,适用于社交网络中的共同好友查找等功能。

5. 有序集合(Sorted Set)

  • 描述:类似于集合,但每个元素关联了一个分数(score),通过分数排序。
  • 适用场景
    • 排行榜系统,根据用户的积分来排名。
    • 定时任务调度,根据任务执行的时间顺序排列。
    • 按照优先级处理的任务队列。

6. Bitmaps

  • 描述:实际上不是一种独立的数据类型,而是字符串类型的特殊形式,允许以位为单位进行操作。
  • 适用场景
    • 用户在线状态跟踪,用一位表示一个用户是否在线。
    • 统计活跃用户数量,例如每日登录用户数。

7. HyperLogLogs

  • 描述:用于基数估计的算法,能够高效地估算集合中不同元素的数量。
  • 适用场景
    • 统计唯一访客数量,而不需要精确计数。
    • 大规模数据集中去重统计。

8. 地理空间索引(Geospatial Indexes)

  • 描述:支持地理坐标的位置存储,并提供基于位置的服务功能。
  • 适用场景
    • 附近地点搜索,如查找附近的餐馆或朋友。
    • 路径规划,计算两点之间的距离。

总结

选择合适的数据类型对于最大化 Redis 的性能和效率至关重要。理解各种数据类型的特性和适用场景可以帮助你更有效地设计和实现应用程序。例如,当你需要快速查询最近的N条记录时,可以考虑使用列表;当需要处理具有唯一性要求的数据集合时,可以使用集合;而当你需要对数据项按照某种评分进行排序时,有序集合将是理想的选择。合理利用这些数据类型可以使你的 Redis 应用更加高效和灵活。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/70740.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

k8s集群3主5从高可用架构(kubeadm方式安装k8s)

关键步骤说明 环境准备阶段 系统更新:所有节点执行yum/apt update确保软件包最新时间同步:通过ntpdate time.windows.com或部署NTP服务器网络规划:明确划分Service网段(默认10.96.0.0/12)和Pod网段(如Flann…

Dify部署无法拉取镜像

Dify部署无法摘取镜像 sudo docker compose up -d [] Running 10/10✘ nginx Error Get "https://registry-1.docker.io/v2/": net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiti... 15.2s✘ we…

科技快讯 | L3自动驾驶之风吹向全球 2025年或成商业化关键;DeepSeek商标遭恶意抢注

消息称AMD拟以40亿美元出售数据中心工厂,部分台企成潜在买家 2月24日,彭博社报道,AMD正与包括台湾广达电子、英业达、和硕联合以及纬创资通在内的亚洲企业谈判,出售其去年收购的数据中心制造工厂,总价值可能在30-40亿美…

06C语言——指针

一、指针入门 (1)、准备知识 0、图解: 1、内存地址 字节:字节是内存的容量单位,英文称为 byte,一个字节有8位,即 1byte(0000 0000 --- 1111 1111) 8bits(0 --- 1) 地址:系统为了便于区分每一个字节而对…

Python爬虫selenium验证-中文识别点选+图片验证码案例

1.获取图片 import re import time import ddddocr import requests from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.chrome.service import Service from selenium.webdriver.support.wait import WebDriverWait from …

OpenCV(6):图像边缘检测

图像边缘检测是计算机视觉和图像处理中的一项基本任务,它用于识别图像中亮度变化明显的区域,这些区域通常对应于物体的边界。是 OpenCV 中常用的边缘检测函数及其说明: 函数算法说明适用场景cv2.Canny()Canny 边缘检测多阶段算法,检测效果较…

电子科技大学考研复习经验分享

电子科技大学考研复习经验分享 本人情况:本科就读于电科软院,24年2月开始了解考研,24年3月开始数学,9月决定考本院(开始全天候图书馆学习)并开始专业课学习,11月底开始政治学习,最后…

go基础语法

go基础语法 先下载安装go,然后到vscode下载go插件 1. 基础 输入输出 package main import "fmt" func main(){a:1var b2 var c int //不给初始值得标出变量类型 c3var d stringfmt.Scanf("%s",&d) //接收用户输入fmt.Printf("Hell…

硬件基础(3):三极管(1):理论基础

目录 一、背景 二、定义 三、分类 四、工作原理 NPN三极管工作原理 基本工作原理 电流放大倍数(增益) 输入特性 1. 输入特性的基本概念 2. 输入特性曲线的形态 3. 输入特性曲线的具体分析 输出特性 1. 输出特性图的基本概念 2. 输出特性曲…

Git最佳实践指南(Windows/Linux双系统详解)

Git最佳实践指南:从入门到熟练(Windows/Linux双系统详解) 一、环境搭建与基础配置(适用Windows/Linux) 1.1 Git安装与验证 # Windows系统安装(推荐Chocolatey包管理) # 直接下载git二进制文件…

吃一堑长一智

工作中经历,有感触记录下 故事一 以前在一家公司时,自己是一名开发人员,遇到问题请教领导解决方案,当时领导给了建议,后来上线后出问题了,背了锅。心里想的是领导说这样做的呀,为什么出问题还…

联想 SR590 服务器 530-8i RAID 控制器更换损坏的硬盘

坏了的硬盘会自动亮黄灯。用一个空的新盘来替换,新盘最好不要有东西。但是有东西可能也没啥,因为我看 RAID 控制器里有格式化的选项 1. 从 IPMI 把服务器关机,电源键进入绿色闪烁状态 2. 断电,推开塑料滑块拉出支架,…

前端浏览器开发中的浏览器兼容问题【持续更新】

目录 一、什么是浏览器兼容问题 二、JavaScript兼容问题及解决方案 2.1addEventListener与attachEvent的区别 2.2集合类对象问题 2.3自定义属性问题 2.4event.x与event.y问题 2.5window.location.href问题 2.6事件委托方法 三、CSS兼容问题及解决方案 3.1浏览器CSS样式初…

【c语言】字符函数和字符串函数(1)

一、字符分类函数 c语言中有部分函数是专门做字符分类的,也就是一个字符是属于什么类型的字符,这些函 数的使用要包含一个头文件ctype.h中。 其具体如下图所示: 这些函数的使用方式都类似,下面我们通过一个函数来看其…

LeetCodehot 力扣热题100 全排列

这段代码的目的是计算给定整数数组的所有全排列(permutations),并返回一个包含所有排列的二维数组。 思路解析 在这段代码中,采用了 深度优先搜索(DFS) 和 回溯 的方法来生成所有的排列。 关键步骤&#xf…

【Qt源码】窥视信号槽实现机制

为了便于通过调试进源码探究下Qt信号槽实现原理,这里简单写一段代码如下所示。 1.自定义信号槽连接 MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow) {ui->setupUi(this);QObject::connect(ui->pushButton,&QPu…

六十天前端强化训练之第二天CSS选择器与盒模型深度解析

欢迎来到编程星辰海的博客讲解 目录 一、CSS 核心概念 1. 三种引入方式 2. CSS 注释 3. 常见单位系统 二、CSS选择器核心知识 1. 基础选择器类型 2. 组合选择器 3. 伪类选择器(部分示例) 4. 优先级计算规则 三、盒模型深度解析 1. 标准盒模型图…

【DeepSeek】-macOS本地终端部署后运行DeepSeek如何分析图片

【DeepSeek】-macOS本地终端部署后运行DeepSeek如何分析图片 根据您的需求,目前需要了解以下几个关键点及分步解决方案: --- 一、现状分析 1. Ollama 的限制: - 目前Ollama主要面向文本大模型,原生不支持直接上传/处理图片 …

【音视频】音视频录制、播放原理

一、音视频录制原理 通常,音视频录制的步骤如下图所示: 我们分别从音频和视频开始采样,通过麦克风和摄像头来接受我们的音频信息和图像信息,这通常是同时进行的,不过,通常视频的采集会比音频的采集慢&…

解锁养生密码,拥抱健康生活

在快节奏的现代生活中,养生不再是一种选择,而是我们保持活力、提升生活质量的关键。它不是什么高深莫测的学问,而是一系列融入日常的简单习惯,每一个习惯都在为我们的健康加分。 早晨,当第一缕阳光洒进窗户&#xff0c…