面试八股文

Q:进程与线程

A:区别&联系:线程是程序执行的最小单位,而进程是操作系统分配资源的最小单位;一个进程由一个或多个线程组成,线程是一个进程中代码的不同执行路线;进程之间相互独立,但同一进程下的各个线程之间共享程序的内存空间(包括代码段,数据集,堆等)及一些进程级的资源(如打开文件和信

号等),某进程内的线程在其他进程不可见;调度和切换:线程上下文切换比进程上下文切换要快得多;通信方式差异::进程间通信:管道通信;信号量;消息队列;信号;共享内存;套接字;线程间通信:锁机制:包括互斥锁、条件变量、读写锁;信号量机制;信号机制;

Q:Redis为什么快?为什么单线程?

A:快----数据库的工作模式按存储方式可分为:硬盘数据库和内存数据库。Redis 将数据储存在内存里面,读写数据的时候都不会受到硬盘 I/O 速度的限制,所以速度极快;1、完全基于内存,绝大部分请求是纯粹的内存操作,非常快速。数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1);2、数据结构简单,对数据操作也简单,Redis中的数据结构是专门进行设计的;3、采用单线程,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗 CPU,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗;4、使用多路I/O复用模型,非阻塞IO;5、使用底层模型不同,它们之间底层实现方式以及与客户端之间通信的应用协议不一样,Redis直接自己构建了VM 机制 ,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求;单线程-----官方FAQ表示,因为Redis是基于内存的操作,CPU不是Redis的瓶颈,Redis的瓶颈最有可能是机器内存的大小或者网络带宽。既然单线程容易实现,而且CPU不会成为瓶颈,那就顺理成章地采用单线程的方案了(毕竟采用多线程会有很多麻烦!);Redis的多线程部分只是用来处理网络数据的读写和协议解析,执行命令仍然是单线程。

Q:缓存穿透、缓存击穿、缓存雪崩和解决方案

A:缓存穿透:缓存和数据库中都没有的数据,而用户不断发起请求,如发起为id为“-1”的数据或id为特别大不存在的数据,导致数据库压力过大

        解决方案:接口层增加校验;key-value对写为key-null,缓存有效时间可以设置短点,如30秒

        缓存击穿:缓存中没有但数据库中有的数据(一般是缓存时间到期),这时由于并发用户特别多,同时读缓存没读到数据,又同时去数据库去取数据,引起数据库压力瞬间增大,造成过大压力

        解决方案:设置热点数据永远不过期;加互斥锁,100ms休眠

        缓存雪崩:当缓存服务器重启或者大量缓存集中在某一个时间段失效,给后端系统(比如DB)带来很大压力

        解决方案:设置热点数据永远不过期;缓存数据的过期时间设置随机,防止同一时间大量数据过期现象发生;分布式下均匀分布;DB加锁排队

Q:JVM分代回收方式以及各种回收算法

A:很完整的一篇文章: JVM分代回收机制和垃圾回收算法_羽毛的博客-CSDN博客_jvm分代回收

Q:NoSql和关系型数据库的区别,优势

A:见下文:关系型数据库与非关系型数据库Nosql区别汇总_渴望飞的鱼的博客-CSDN博客_nosql和关系型数据库的区别

Q:事务ACID,隔离级别

A:原子性(atomicity):事务包含的所有操作要么全部成功,要么全部失败回滚--->undolog(回滚日志,当事务对数据库进行修改时,InnoDB会生成对应的undo log;如果事务执行失败或调用了rollback,导致事务需要回滚,便可以利用undo log中的信息将数据回滚到修改之前的样子)

        一致性(consistency):事务必须使数据库从一个一致性状态----> 另一个一致性状态,也就是说一个事务执行之前和执行之后都必须处于一致性状态

        隔离性(isolation):隔离性是当多个用户并发访问数据库时,比如操作同一张表时,数据库为每一个用户开启的事务,不能被其他事务的操作所干扰,多个并发事务之间要相互隔离----->(锁机制、MVCC),隐藏列:InnoDB中每行数据都有隐藏列,隐藏列中包含了本行数据的事务id、指向undo log的指针;基于undo log的版本链;ReadView快照

        持久性(durability):事务一旦提交,它对数据库的改变就应该是永久性的,接下来的其他操作或故障不应该对其有任何影响;Mysql中,为了解决CPU和磁盘速度不一致问题,Mysql是将磁盘上的数据加载到内存,对内存进行操作,然后再回写磁盘,如果中间出现断电,那么久有可能没有将数据写入---->redo log(redo log被引入解决buffer pool丢失问题:当数据修改时,除了修改Buffer Pool中的数据,还会在redo log记录这次操作;当事务提交时,会调用fsync接口对redo log进行刷盘。如果MySQL宕机,重启时可以读取redo log中的数据,对数据库进行恢复。redo log采用的是WAL(Write-ahead logging,预写式日志),所有修改先写入日志,再更新到Buffer Pool,保证了数据不会因MySQL宕机而丢失,从而满足了持久性要求)

        隔离级别相关问题:

        脏读:A读取B事务尚未提交的事务,并修改了B的数据,然后B对事务执行回滚,那么A读取到的数据为脏读

        不可重复读:事务A读取数据,然后事务B对事务A的数据进行了修改,此后,事务A再次读取数据,这时为不可重复读,最后A提交事务。所以在A的一次事务中,两次读取到的数据不一致

        幻读:事务A查询数据,查询一切符合查询条件的行,这时B新增加一个行数据,A事务再次查询时,发现与第一次查询相比,新增加了一行

事务隔离级别脏读不可重复读幻读
读未提交(read-uncommitted
读已提交(read-committed)×
可重复读(repeatable-read)××
串行化(serializable)×××

深入学习MySQL事务:ACID特性的实现原理 - 编程迷思 - 博客园

Q:SQL优化方案

A:SQL语言 - SQL语句优化 | Java 全栈知识体系

Q:分布式锁

A:基于数据库组合唯一约束的排他锁;基于Redis,setIfAbsent(k,v),最后再删除,可能会出现宕机,无法释放锁的情况;见文章:三种实现分布式锁的方式_vincent-CSDN博客_分布式锁

Q:消息中间件的应用场景

A:应用解耦:如,一个服务调用多个服务的业务场景,只需要推送,而不关心结果,不关心其他服务的处理情况,使用消息中间件,由其他服务主动订阅处理,降低服务之间的耦合性;流量削峰:大量请求进行同一接口调用,导致超过后端承载能力上限,可以将请求丢入消息中间件,在后端最大处理能力内限制消费中间件消息;日志处理:ELK+Kafka-----aop日志--->kafka topic--->logstash--->elasticsearch存储--->kibana连接索引访问;分布式事务:聊聊分布式事务,再说说解决方案 - Savorboard - 博客园

Q:内存溢出和内存泄漏;内存泄漏、内存溢出的多种场景

A:内存溢出:程序申请内存时,没有足够的内存供申请者使用,场景:内存中加载的数据量过于庞大,如一次从数据库取出过多数据;集合类中有对对象的引用,使用完后未清空,使得JVM不能回收;代码中存在死循环或循环产生过多重复的对象实体;使用的第三方软件中的BUG;启动参数设定的过小。。。。。内存泄漏:程序在申请内存后,无法释放已申请的内存空间,场景:大量使用static变量;资源未关闭导致内存泄漏;hashcode数据结构产生的内存泄漏;

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值