Redis的数据类型
Redis的数据类型因为Redis是非关系型数据库,所以Redis中存储数据都是使用键值对存储。 StringString类型是Redis最基本的类型。String类型是二进制安全的,也就是redis的String可以包含任何数据。 常用命令 命令 功能 set key value 设置key的值为value get key 获取key的值 setex key seconds value 设置key的过期时间,单位是秒 expire key seconds 设置key的过期时间,单位是秒 ttl key 获取key的剩余过期时间,单位是秒 incr key 将key的值增加1 decr key 将key的值减少1 HashRedis中的Hash类型是键值对集合,他由key filed value组成,适合存储对象 常用命令 命令 功能 hset key field value 设置key的field的值为value hget key field 获取key的field的值 hgetall key 获取key的所有field和...
Redis为什么快
Redis为什么快?首先我们要知道,Redis是基于内存存储。这也是他快的主要原因。但是你如果说Redis快,不能只说Redis基于内存。还要说他是单线程模型(无锁竞争)还要说他的IO多路复用(网络模型)更要说他的高效的数据结构* 单线程模型多线程竞争共享数据需要加锁。没有线程切换,没有死锁。代码简单高效。 高效的数据结构Redis为每种数据结构做了底层的优化 String List Hash Set ZSet IO多路复用传统的IO模型是阻塞IO,即一个线程处理一个连接。当一个连接处理完毕,会阻塞等待下一个连接。线程切换消耗CPU,而且read也会阻塞等待数据到达后在处理 IO多路复用则是创建一个调度中心,将多个连接注册到调度中心,当有连接有数据到达时,调度中心会通知对应的线程处理。
Redis缓存预热
Redis缓存预热详解为什么要缓存预热 为了放置缓存击穿:如果系统重启,Redis是空的。大量用户请求热点数据时,缓存未命中,大量请求会直接压到数据库导致数据库挂掉。 提升用户体验:预热后,加载时间大大降低 简单来说,缓存预热就是空间换时间 怎么做 启动时同步预热 @Componentpublic class CacheWarmUp { @PostConstruct public void warmUpCache() { // 从数据库查询热点数据,并批量写入Redis List<Product> hotProducts = productMapper.getHotProducts(); hotProducts.forEach(p -> redisTemplate.opsForValue().set("product:" + p.getId(), p)); }} 项目启动阶段,使用@PostConstruct或者ApplicationRu...
公平锁与非公平锁详解
公平锁与非公平锁详解Java锁的两员大将 synchronized ReentrantLock 核心思想:假设在银行内,有一个服务窗口,有很多线程想去办理业务 非公平锁新来的线程不关心是否有人排队,他会直接冲向窗口。如果此时窗口正好空着,他就能直接办理。这就是synchronized和ReentrantLock的默认模式。他的好处是效率高,减少线程切换的开销。但可能导致先来的线程一直不能运行。(饥饿) 公平锁银行设立了一个叫号机。每个新来的线程都必须取号排队。这就是 ReentrantLock(true)。他保证了绝对的先来后到,公平性最好,但是增加了线程调度的开销,所以性能可能比较低。 synchronized和ReentrantLock的区别 synchronized:线程进入方法就自动上锁,退出自动解锁,无法干预,实现简单,不容易出错,单一(内置锁) ReentrantLock:可以手动上锁,手动解锁,可以设置公平锁,可以设置可重入锁,可以设置锁超时,可以设置锁中断,实现复杂,易出错,可扩展(API锁)
关于锁升级机制详解
锁升级机制详解锁是什么锁是保证并发操作数据安全,防止数据不一致的工具。使用synchronized关键字修饰的方法,默认情况下,JVM会为这个方法创建一个锁。 关于synchronized的三种锁机制一共有3种锁: 偏向锁 轻量级锁 重量级锁 为什么要有锁升级机制?其实锁升级机制的核心思想就是为了减少获得锁和释放锁带来的性能开销,JVM才对锁进行了分级优化。目的就是在不牺牲性能的前提下保证线程安全 偏向锁就像你长期租用了一个固定的柜子,柜子上贴上了“老王专用”,大部分时间只有你来用。管理员(JVM)看到是你的名字就直接让你用了,省去了开锁的流程。核心场景主要就是优化了绝大多数情况下,锁只被一个线程访问的场景 轻量级锁你今天准备来开你的柜子,但是发现小李准备用你的柜子(发生竞争)。但是小李可能就是过来试一下能不能开开所,或者用一下就走。这个时候你俩就会进行沟通(比如CAS自旋)。避免惊动JVM。核心场景主要是优化了锁竞争程度很低,或基本不竞争(交替运行),且线程持有时间很短的场景。 重量级锁如果捏柜子变得很抢手,还有更多的人都要围过来用你的柜子(激烈竞争)。这个时候简单的沟通就...
MQ消息可靠性
MQ消息可靠性是什么首先我们要知道。MQ是消息中间件,MQ的消息的发送是异步的。其主要步骤是: 生产者 -> 交换机 -> 队列 -> 消费者 其中有3个传输数据的地方,任意一个步骤出错都有可能导致数据丢失。那么我们怎么保证消息的可靠性呢? 为什么其实消息可靠性是根据业务场景来进行要求的 金融支付:丢消息就是丢钱 订单系统:丢消息就是损失收入 日志采集:可允许少量丢失,保证速度快 实时监控:允许部分丢失,保证延迟低 怎么做第一步:生产者确认机制(Publisher Confirms)首先我们保证消息成功到达Broker(RabbitMQ服务器) // 1. 开启生产者确认channel.confirmSelect();// 2. 发送消息channel.basicPublish("exchange", "routingKey", new AMQP.BasicProperties.Builder() .deliveryMode(2) // 持久化消息 ...
Spring的事务传播等级以及事务失效
Spring的事务传播等级以及事务失效是什么事务其实就是多个人一起去干同一件事情,如果其中一个人出现问题,那么整个事务就会回滚,也就是回退到事务开始前的状态。 首先明确Spring中一共有7种事务传播等级: REQUIRED(默认) SUPPORTS MANDATORY REQUIRES_NEW NOT_SUPPORTED NEVER NESTED 我们需要去理解然后记忆 记忆方法可以理解为舍友买饭。Required就是舍友如果买饭回来了,就跟他一起吃;如果舍友没有买饭就自己去买饭Support是舍友如果买饭回来了就一起吃,他没买我也不吃了Mandatory是舍友必须买饭,如果舍友没有买饭我就生气抛异常Requires_new是不管舍友买没买饭,我都自己买饭Not_supported是不管舍友买不买饭我都不吃Never是如果舍友买饭了我就报错Nested是如果舍友买饭了,我就买点小吃。但是和Required的区别在于,我这个小吃成功失败并不重要,但是如果舍友的饭报错了,我的小吃也会回滚。 但是其实我们没有必要照本宣科,在面试的时候全都讲出来。我们可以根据我们项目的实际情况,挑...
微服务相关知识点
一、微服务 1.1 Spring Cloud五大组件 注册中心 Nacos 负载均衡 Ribbon 远程调用 Feign 服务保护 sentinel 网关 Gateway 1.2 Spring Cloud 如何实现服务注册发现注册中心核心作用是:服务注册与发现注册中心会保存 服务名称 ip 端口等 服务注册:服务启动时,将服务信息注册到注册中心 服务提供者: 临时实例(默认):服务注册时,将服务信息注册到注册中心,服务提供者向nacos发送心跳,服务停止时,将服务信息从注册中心删除 永久实例:服务注册时,将服务信息注册到注册中心,nacos主档询问是否健康,若非健康状态也不会剔除,除非手动注销或者nacos重启 服务消费者: 定时拉取服务(Pull):服务消费者定时从注册中心拉取服务信息 主动推送服务(Push):若服务提供者信息发生变更,注册中心会主动推送给服务消费者 nacos集群默认采用AP模式(最终一致性),当集群存在非临时实例是,采用CP模式(强一致性) nacos还有配置中心 有一台服务中心挂了?心跳续约机制:每30秒一次,由服务端向注...
框架相关知识点
一、Spring框架Spring框架概述1.1 Spring中的单例bean是线程安全的吗? 答:不是线程安全的Spring框架有一个@Scope注解,默认的值就是singleton(单例bean)。因为一般在Spring的bean中都是注入无状态的对象(如:Service DAO),没有线程安全问题;但是如果在bean中定义了可修改的成员变量,就要考虑线程安全问题了,可以使用多例:prototype或加锁来解决。 1.2 AOP是什么?AOP(Aspect Oriented Programming),即面向切面编程,用于将那些与业务无关的代码抽离出来,如:日志、事务、权限验证等。封装为一个可重用的模块,称之为切面,减少系统的重复代码,降低模块的耦合度,提高系统的可维护性。 常见使用场景: 日志记录 数据缓存 性能监控 事务管理 权限验证 异常处理 业务逻辑解耦 Spring中的事务是如何实现的?Spring中的事务是通过AOP(Aspect Oriented Programming)实现的。 声明式事务:使用@Transactional注解在方法上声明事务,Spring会自...
Spring相关知识点
Spring配置文件1. Bean的解耦调用 2. Bean的创建时机 3. Bean的生命周期 4. Bean实例化的三种方式 Spring依赖注入1.UserDao怎么注入都UserService 构造方法 set方法 2.Bean的依赖注入的数据类型 普通数据类型 集合数据类型 引用数据类型 Spring相关ApiApplicationContext的实现类 getBean()方法使用 第一种是通过id获取(允许当前容器存在多个相同类型的bean) 第二种是通过class获取(只能当前容器存在一个相同类型的bean) Spring配置数据源数据源(连接池)的作用 提高程序性能 实现实例化数据源 初始化部分连接资源 使用连接资源时从数据源获取 使用完毕将连接资源归还给数据源 常见数据源:DBCP、C3P0、Druid 数据源的开发步骤 导入数据源坐标和数据库驱动坐标 创建数据源对象 设置数据源基本的连接数据 驱动 地址 用户名 密码 使用数据源,归还数据源资源 以上参数可以放到yml里 Spring注解开发原始注解 新注解 AOPAOP的原理实现...
