北京海致网聚

技术一面

介绍你项目中用到的技术,项目有什么亮点?

遇到过什么问题?是怎么解决的?

缓存击穿,缓存穿透,缓存雪崩是什么?解决措施?

  • 缓存的处理流程: 前台请求,后台先从缓存中取数据,取到直接返回结果,取不到时从数据库中取,数据库取到后更新缓存,并返回结果,数据库也没取到,那直接返回空结果。
  • 缓存穿透: 查询一个一定不存在的数据,由于缓存未命中时需要从数据库查询,查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到数据库去查询,进而给数据库带来压力。(查不到东西
措施描述
布隆过滤器它是一种数据结构,对所有可能查询的参数以hash形式存储,在控制层先进行校验,不符合则丢弃,从而避免了对底层存储系统的查询压力。
缓存空对象当存储层不命中后,即使返回的空对象也将其缓存起来,同时会设置一个过期时间,之后再访问这个数据将会从缓存中获取,保护了后端数据源。
  • 缓存击穿: 热点key在某个时间点过期的时候,而恰好在这个时间点对这个Key有大量的并发请求过来,从而大量的请求打到数据库上面。(相当于在一个墙壁上凿出一个洞
措施描述
设置热点数据永不过期从缓存层面来看,没有设置过期时间,所以不会出现热点 key 过期后产生的问题。
加互斥锁使用分布式锁,保证对于每个key同时只有一个线程去查询后端服务,其他线程没有获得分布式锁的权限,因此只需要等待即可。这种方式将高并发的压力转移到了分布式锁,因此对分布式锁的考验很大。
  • 缓存雪崩: 缓存中数据大批量到过期时间,而查询数据量巨大,引起数据库压力过大甚至宕机。(部分数据集中过期,很多数据都查不到
措施描述
redis高可用既然redis有可能挂掉,那就多增设几台redis,这样一台挂掉之后其他的还可以继续工作,其实就是搭建的集群。(异地多活!)
限流降级在缓存失效后,通过加锁或者队列来控制读数据库写缓存的线程数量。比如对某个key只允许一个线程查询数据和写缓存,其他线程等待。
数据预热在正式部署之前,我先把可能的数据先预先访问一遍,这样部分可能大量访问的数据就会加载到缓存中。在即将发生大并发访问前手动触发加载缓存不同的key,设置不同的过期时间,让缓存失效的时间点尽量均匀。

redis集群中,数据备份怎么做?

主从复制是什么?

(Master&Slave)也就是我们所说的主从复制,主机数据更新后根据配置和策略,自动同步到备机。Master以写为主,Slave以读为主。Redis主从复制可以根据是否是全量分为全量同步增量同步

  • Redis主从同步策略

主从刚刚连接的时候,进行全量同步;全同步结束后,进行增量同步。当然,如果有需要,slave 在任何时候都可以发起全量同步。redis 策略是,无论如何,首先会尝试进行增量同步,如不成功,要求从机进行全量同步。

redis集群的主节点有几个?

可以有多个主节点比如:一主二从,三主三从
结点最多可以有16384个

java中锁的类型有哪些?

  • 公平锁/非公平锁
  • 可重入锁
  • 独享锁/共享锁
  • 互斥锁/读写锁
  • 乐观锁/悲观锁
  • 分段锁
  • 偏向锁/轻量级锁/重量级锁
  • 自旋锁

synchronizedvolate解释一下

锁相关问题

CAS自旋锁,ABA问题描述一下

  • 非阻塞的实现CAS(compareandswap)
  1. CAS指令需要有3个操作数,分别是内存地址(在java中理解为变量的内存地址,用V表示)、旧的预期值(用A表示)和新值(用B表示)。
  2. CAS指令执行时,当且仅当V处的值符合旧预期值A时,处理器用B更新V处的值,否则它就不执行更新,但是无论是否更新了V处的值,都会返回V的旧值,上述的处理过程是一个原子操作。
  • CAS缺点
  1. ABA问题: 因为CAS需要在操作值的时候检查下值有没有发生变化,如果没有发生变化则更新,但是一个值原来是A,变成了B,又变成了A,那么使用CAS进行检查时会发现它的值没有发生变化,但是实际上却变化了。
  2. 使用版本号解决ABA问题: 在变量前面追加版本号,每次变量更新的时候把版本号加一,那么A-B-A就变成了1A-2B-3C。JDK的atomic包里提供了一个类AtomicStampedReference来解决ABA问题。这个类的compareAndSet方法作用是首先检查当前引用是否等于预期引用,并且当前标志是否等于预期标志,如果全部相等,则以原子方式将该引用和该标志的值设置为给定的更新值。
  3. 性能消耗大: 自旋CAS如果长时间不成功,会给CPU带来非常大的执行开销。

IOCAOP你怎么理解的?

  • IOC:创建对象和维护对象之间的关系是繁琐的,将这部分任务交给容器,传统上由程序代码操控的对象,有了IOC容器之后,将调用权交给容器,来实现对象组件的装配和管理。
  • AOP:OOP是面向对象,AOP是面向切面,将那些与业务无关,但是却对多个对象产生影响的逻辑抽取出来,封装成一个可重用的模块,这就是切面,减少重复代码,解耦,如权限认证,日志,事务处理。

Spring的事务是怎么实现的?

  • Spring事务的本质其实就是数据库对事务的支持,没有数据库的事务支持,spring是无法提供事务功能的。
  • 真正的数据库层的事务提交和回滚是通过binlog或者redo log实现的。

@aspect是什么原理,怎么实现的?

  • 可以简单地认为, 使用 @Aspect 注解的类就是切面。
  • aspect 由 pointcount 和 advice 组成,切面是通知切点的结合。 它既包含了横切逻辑的定义, 也包括了连接点的定义. Spring AOP 就是负责实施切面的框架, 它将切面所定义的横切逻辑编织到切面所指定的连接点中。
  • AOP 的工作重心在于如何将增强编织目标对象的连接点上, 包含两个工作
  1. 如何通过 pointcut 和 advice 定位到特定的 joinpoint 上
  2. 如何在 advice 中编写切面代码

BeanFactoryApplicationContext的异同?

  • BeanFactory和ApplicationContext是Spring的两大核心接口,都可以当做Spring的容器。其中ApplicationContext是BeanFactory的子接口。
  • BeanFactory需要手动注册,而ApplicationContext则是自动注册。
  • 依赖关系
  1. BeanFactory:是Spring里面最底层的接口,包含了各种Bean的定义,读取bean配置文档,管理bean的加载、实例化,控制bean的生命周期,维护bean之间的依赖关系。
  2. ApplicationContext接口作为BeanFactory的派生,除了提供BeanFactory所具有的功能外,还提供了更完整的框架功能
  • 加载方式
  1. BeanFactroy采用的是延迟加载形式来注入Bean的,即只有在使用到某个Bean时(调用getBean()),才对该Bean进行加载实例化。这样,我们就不能发现一些存在的Spring的配置问题。如果Bean的某一个属性没有注入,BeanFacotry加载后,直至第一次使用调用getBean方法才会抛出异常。

  2. ApplicationContext,它是在容器启动时,一次性创建了所有的Bean。这样,在容器启动时,我们就可以发现Spring中存在的配置错误,这样有利于检查所依赖属性是否注入。 ApplicationContext启动后预载入所有的单实例Bean,通过预载入单实例bean ,确保当你需要的时候,你就不用等待,因为它们已经创建好了。

  3. 相对于基本的BeanFactory,ApplicationContext 唯一的不足是占用内存空间。当应用程序配置Bean较多时,程序启动较慢。

hashmapconcurrentHashmap的实现,为什么使用分段锁?

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)数据,而另一个事务却在此时插入了新的几列数据,先前的事务在接下来的查询中,就会发现有几列数据是它先前所没有的。

算法题:给一个正数N,开根号,要求误差在0.1内,怎么实现?

冒泡排序,快速排序。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值