文章目录
- 技术一面
- 介绍你项目中用到的技术,项目有什么亮点?
- 遇到过什么问题?是怎么解决的?
- 缓存击穿,缓存穿透,缓存雪崩是什么?解决措施?
- `redis`集群中,数据备份怎么做?
- 主从复制是什么?
- `redis`集群的主节点有几个?
- `java`中锁的类型有哪些?
- `synchronized`和`volate`解释一下
- `CAS`自旋锁,`ABA问题`描述一下
- `IOC`和`AOP`你怎么理解的?
- `Spring`的事务是怎么实现的?
- `@aspect`是什么原理,怎么实现的?
- `BeanFactory`和`ApplicationContext`的异同?
- `hashmap`和`concurrentHashmap`的实现,为什么使用分段锁?
- 数据库的引擎有哪些,区别是什么?
- 数据库引擎的索引是怎么实现的?
- 聚簇索引和非聚簇索引,主键索引的区别
- 事务的隔离级别有哪些?都解决了什么问题?
- 脏读,幻读,重复读分别是什么?
- 算法题:给一个正数N,开根号,要求误差在0.1内,怎么实现?
- 冒泡排序,快速排序。
技术一面
介绍你项目中用到的技术,项目有什么亮点?
遇到过什么问题?是怎么解决的?
缓存击穿,缓存穿透,缓存雪崩是什么?解决措施?
- 缓存的处理流程: 前台请求,后台先从缓存中取数据,取到直接返回结果,取不到时从数据库中取,数据库取到后更新缓存,并返回结果,数据库也没取到,那直接返回空结果。
- 缓存穿透: 查询一个一定不存在的数据,由于缓存未命中时需要从数据库查询,查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到数据库去查询,进而给数据库带来压力。(
查不到东西)
| 措施 | 描述 |
|---|---|
| 布隆过滤器 | 它是一种数据结构,对所有可能查询的参数以hash形式存储,在控制层先进行校验,不符合则丢弃,从而避免了对底层存储系统的查询压力。 |
| 缓存空对象 | 当存储层不命中后,即使返回的空对象也将其缓存起来,同时会设置一个过期时间,之后再访问这个数据将会从缓存中获取,保护了后端数据源。 |
- 缓存击穿: 热点
key在某个时间点过期的时候,而恰好在这个时间点对这个Key有大量的并发请求过来,从而大量的请求打到数据库上面。(相当于在一个墙壁上凿出一个洞)
| 措施 | 描述 |
|---|---|
| 设置热点数据永不过期 | 从缓存层面来看,没有设置过期时间,所以不会出现热点 key 过期后产生的问题。 |
| 加互斥锁 | 使用分布式锁,保证对于每个key同时只有一个线程去查询后端服务,其他线程没有获得分布式锁的权限,因此只需要等待即可。这种方式将高并发的压力转移到了分布式锁,因此对分布式锁的考验很大。 |
- 缓存雪崩: 缓存中数据大批量到过期时间,而查询数据量巨大,引起数据库压力过大甚至宕机。(
部分数据集中过期,很多数据都查不到)
| 措施 | 描述 |
|---|---|
| redis高可用 | 既然redis有可能挂掉,那就多增设几台redis,这样一台挂掉之后其他的还可以继续工作,其实就是搭建的集群。(异地多活!) |
| 限流降级 | 在缓存失效后,通过加锁或者队列来控制读数据库写缓存的线程数量。比如对某个key只允许一个线程查询数据和写缓存,其他线程等待。 |
| 数据预热 | 在正式部署之前,我先把可能的数据先预先访问一遍,这样部分可能大量访问的数据就会加载到缓存中。在即将发生大并发访问前手动触发加载缓存不同的key,设置不同的过期时间,让缓存失效的时间点尽量均匀。 |
redis集群中,数据备份怎么做?
主从复制是什么?
(Master&Slave)也就是我们所说的主从复制,主机数据更新后根据配置和策略,自动同步到备机。Master以写为主,Slave以读为主。Redis主从复制可以根据是否是全量分为全量同步和增量同步。
Redis主从同步策略
主从刚刚连接的时候,进行全量同步;全同步结束后,进行增量同步。当然,如果有需要,slave 在任何时候都可以发起全量同步。redis 策略是,无论如何,首先会尝试进行增量同步,如不成功,要求从机进行全量同步。
redis集群的主节点有几个?
可以有多个主节点比如:一主二从,三主三从
结点最多可以有16384个
java中锁的类型有哪些?
- 公平锁/非公平锁
- 可重入锁
- 独享锁/共享锁
- 互斥锁/读写锁
- 乐观锁/悲观锁
- 分段锁
- 偏向锁/轻量级锁/重量级锁
- 自旋锁
synchronized和volate解释一下
CAS自旋锁,ABA问题描述一下
- 非阻塞的实现CAS(compareandswap)
- CAS指令需要有3个操作数,分别是
内存地址(在java中理解为变量的内存地址,用V表示)、旧的预期值(用A表示)和新值(用B表示)。 - CAS指令执行时,当且仅当V处的值符合旧预期值A时,处理器用B更新V处的值,否则它就不执行更新,但是无论是否更新了V处的值,都会返回V的旧值,上述的处理过程是一个原子操作。
- CAS缺点
ABA问题:因为CAS需要在操作值的时候检查下值有没有发生变化,如果没有发生变化则更新,但是一个值原来是A,变成了B,又变成了A,那么使用CAS进行检查时会发现它的值没有发生变化,但是实际上却变化了。使用版本号解决ABA问题:在变量前面追加版本号,每次变量更新的时候把版本号加一,那么A-B-A就变成了1A-2B-3C。JDK的atomic包里提供了一个类AtomicStampedReference来解决ABA问题。这个类的compareAndSet方法作用是首先检查当前引用是否等于预期引用,并且当前标志是否等于预期标志,如果全部相等,则以原子方式将该引用和该标志的值设置为给定的更新值。性能消耗大:自旋CAS如果长时间不成功,会给CPU带来非常大的执行开销。
IOC和AOP你怎么理解的?
- IOC:创建对象和维护对象之间的关系是繁琐的,将这部分任务交给容器,传统上由程序代码操控的对象,有了IOC容器之后,将调用权交给容器,来实现对象组件的装配和管理。
- AOP:OOP是面向对象,AOP是面向切面,将那些与业务无关,但是却对多个对象产生影响的逻辑抽取出来,封装成一个可重用的模块,这就是切面,减少重复代码,解耦,如权限认证,日志,事务处理。
Spring的事务是怎么实现的?
- Spring事务的本质其实就是数据库对事务的支持,没有数据库的事务支持,spring是无法提供事务功能的。
- 真正的数据库层的事务提交和回滚是通过binlog或者redo log实现的。
@aspect是什么原理,怎么实现的?
- 可以简单地认为, 使用
@Aspect注解的类就是切面。 - aspect 由 pointcount 和 advice 组成,切面是
通知和切点的结合。 它既包含了横切逻辑的定义, 也包括了连接点的定义. Spring AOP 就是负责实施切面的框架, 它将切面所定义的横切逻辑编织到切面所指定的连接点中。 - AOP 的工作重心在于如何将增强编织目标对象的连接点上, 包含两个工作
- 如何通过 pointcut 和 advice 定位到特定的 joinpoint 上
- 如何在 advice 中编写切面代码
BeanFactory和ApplicationContext的异同?
- BeanFactory和ApplicationContext是Spring的两大核心接口,都可以当做Spring的容器。其中ApplicationContext是BeanFactory的子接口。
- BeanFactory需要手动注册,而ApplicationContext则是自动注册。
- 依赖关系
- BeanFactory:是Spring里面最底层的接口,包含了各种Bean的定义,读取bean配置文档,管理bean的加载、实例化,控制bean的生命周期,维护bean之间的依赖关系。
- ApplicationContext接口作为BeanFactory的派生,除了提供BeanFactory所具有的功能外,还提供了更完整的框架功能
- 加载方式
-
BeanFactroy采用的是延迟加载形式来注入Bean的,即只有在使用到某个Bean时(调用getBean()),才对该Bean进行加载实例化。这样,我们就不能发现一些存在的Spring的配置问题。如果Bean的某一个属性没有注入,BeanFacotry加载后,直至第一次使用调用getBean方法才会抛出异常。
-
ApplicationContext,它是在容器启动时,一次性创建了所有的Bean。这样,在容器启动时,我们就可以发现Spring中存在的配置错误,这样有利于检查所依赖属性是否注入。 ApplicationContext启动后预载入所有的单实例Bean,通过预载入单实例bean ,确保当你需要的时候,你就不用等待,因为它们已经创建好了。
-
相对于基本的BeanFactory,ApplicationContext 唯一的不足是占用内存空间。当应用程序配置Bean较多时,程序启动较慢。
hashmap和concurrentHashmap的实现,为什么使用分段锁?
hashmap源码分析
concurrentHashmap源码分析
数据库的引擎有哪些,区别是什么?
数据库引擎的索引是怎么实现的?
- 索引的原理:索引用来快速地寻找那些具有特定值的记录。如果没有索引,一般来说执行查询时遍历整张表。就是把无序的数据变成有序的查询。
- 索引的数据结构和具体存储引擎的实现有关
- 在MySQL中使用较多的索引有Hash索引,B+树索引等,而我们经常使用的InnoDB存储引擎的默认索引实现为:B+树索引。
- 对于哈希索引来说,底层的数据结构就是哈希表,因此在绝大多数需求为单条记录查询的时候,可以选择哈希索引,查询性能最快;其余大部分场景,建议选择BTree索引。
聚簇索引和非聚簇索引,主键索引的区别
- 全文索引: 是目前搜索引擎使用的一种关键技术
- 普通索引: 基本的索引类型,没有唯一性的限制,允许为NULL值。
- 主键索引: 数据列不允许重复,不允许为NULL,一个表只能有一个主键。
- 唯一索引: 数据列不允许重复,允许为NULL值,一个表允许多个列创建唯一索引。
- 聚簇索引: 将数据存储与索引放到了一块,找到索引也就找到了数据
- 非聚簇索引: 将数据存储于索引分开结构,索引结构的叶子节点指向了数据的对应行,myisam通过key_buffer把索引先缓存到内存中,当需要访问数据时(通过索引访问数据),在内存中直接搜索索引,然后通过索引找到磁盘相应数据,这也就是为什么索引不在key buffer命中时,速度慢的原因
事务的隔离级别有哪些?都解决了什么问题?
读未提交: 最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读。
读已提交: 允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生。
可重复读: 对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。
可串行化: 最高的隔离级别,完全服从ACID的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。
脏读,幻读,重复读分别是什么?
脏读(Drity Read):某个事务已更新一份数据,另一个事务在此时读取了同一份数据,由于某些原因,前一个RollBack了操作,则后一个事务所读取的数据就会是不正确的。不可重复读(Non-repeatable read):在一个事务的两次查询之中数据不一致,这可能是两次查询过程中间插入了一个事务更新的原有的数据。幻读(Phantom Read):在一个事务的两次查询中数据笔数不一致,例如有一个事务查询了几列(Row)数据,而另一个事务却在此时插入了新的几列数据,先前的事务在接下来的查询中,就会发现有几列数据是它先前所没有的。
2万+

被折叠的 条评论
为什么被折叠?



