B站面试
-
Java根底
-
ArrayList与LinkedList的区别?
- ArrayList是基于动静数组实现,LinedList是基于链表构造实现的
- 对于随机的拜访ArrayList要优先于Linkedist,linkedList须要挪动指针
- 对于插入、删除数据LinkedList只须要扭转前后的指针援用即可,ArrayList须要挪动插入/删除的元素 比拟耗时
-
-
AQS简述其中一些罕用的技术(ReentrantLock)
-
AQS(AbstracyQueueSynchronizer)形象队列同步器
state(int) Queue(null)次要实现的原理波及的2个参数
-
-
引申:Synchronized与ReentrantLock的区别?
- Synchronized锁的转换,偏差锁(无锁->偏差锁->轻量级锁->重量级锁)?
-
Synchronized是Java关键字,是JVM层面的锁,在代码块/办法中通过notify/wait来实现,ReentrantLock是jdk原生的锁,底层原理是CAS
- 是否能够手动开释:Synchronized不能够手动开释锁,必须代码块/办法执行实现后才能够开释锁,ReentrantLock如果遗记了开释锁就会始终持有锁导致死锁,所以个别将开释锁的操作放在finally中执行开释unlock()操作。
- 是否能够中断:Synchronized是不可中断的锁,必须是线程执行实现/代码中出现异常。ReentrantLock是能够中断的,tryLock(timeout,TimeUnit)设置超时办法或者将lockInterruptibly()放到代码块中,调用interrupt办法进行中断
- 是否偏心:synchronized为非偏心锁 ReentrantLock则即能够选偏心锁也能够选非偏心锁,通过构造方法new ReentrantLock时传入boolean值进行抉择,为空默认false非偏心锁,true为偏心锁
- 锁的唤醒的准确:synchronized不能绑定; ReentrantLock通过绑定Condition联合await()/singal()办法实现线程的准确唤醒,而不是像synchronized通过Object类的wait()/notify()/notifyAll()办法要么随机唤醒一个线程要么唤醒全副线程。
- 锁的对象:synchronzied锁的是对象,锁是保留在对象头外面的,依据对象头数据来标识是否有线程取得锁/争抢锁;ReentrantLock锁的是线程,依据进入的线程和int类型的state标识锁的取得/争抢
-
多线程的应用形式?(线程池应用及一些外围参数简介及线程数如何设置)
-
多线程个别应用ThreadPoolExecutor来创立自定义线程池,线程池参数
- coreSize:外围线程数
- maxSize:最大线程数
- time:外围线程存活的最长工夫
- timeUnit:存活的工夫单位
- queue:存储新来的工作的队列
- abortPolicy:回绝策略
- factory:创立线程的自定义工厂
-
线程数的创立个别是依据业务的性质决定线程数的配置,个别是CPU密集型/IO密集型
个别是依据这个公式进行计算:线程数=[(线程等待时间+线程解决工夫)/线程解决工夫]Ncpu数,CPU密集型线程的IO耗时根本为0,也就是计算的后果就是Ncpu数,IO密集型线程期待阻塞工夫是线程解决工夫的倍数,假如等待时间与解决工夫相等那个就是2Ncpu数
-
-
Spring中罕用的设计模式简介?(代理模式、工厂模式、单例模式)
- 代理模式:AOP切面(JDK动静代理模式&CGlib代理模式)
- 工厂模式:FactoryBean(定义一个创立工厂的接口,对象的创立实例化交由工厂来实现)
- 单例模式:保障实例化的bean只有一个,能够通过singleton=“true|false” 或者 scope=“?”来指定
- 观察者模式:一种一对多的依赖关系,当一个对象的状态产生扭转时,所有依赖于它的对象都失去告诉并被自动更新,spring中Observer模式罕用的中央是listener的实现。如ApplicationListener
- 策略模式:定义一系列的算法,把它们一个个封装起来,并且使它们可互相替换。本模式使得算法可独立于应用它的客户而变动
-
volatile和final关键字
- volatile
-
final(能够润饰类、办法、变量)
- final润饰类:那么这个类是不能被继承的,这个类中的所有的办法隐式的会变成final
- final润饰办法:那么该办法不能被子类重写,须要留神的一点是:因为重写的前提是子类能够从父类中继承此办法,如果父类中final润饰的办法同时访问控制权限为private,将会导致子类中不能间接继承到此办法,因而,此时能够在子类中定义雷同的办法名和参数,此时不再产生重写与final的矛盾,而是在子类中从新定义了新的办法。(注:类的private办法会隐式地被指定为final办法。
-
final润饰变量:只能被赋值一次,赋值后不再扭转,当final润饰一个根本数据类型时,示意该根本数据类型的值一旦在初始化后便不能发生变化;
- 如果final润饰一个援用类型时,则在对其初始化之后便不能再让其指向其余对象了,但该援用所指向的对象的内容是能够发生变化的。实质上是一回事,因为援用的值是一个地址,final要求值,即地址的值不发生变化。
- final润饰一个成员变量(属性),必须要显示初始化。这里有两种初始化形式,一种是在变量申明的时候初始化;第二种办法是在申明变量的时候不赋初值,然而要在这个变量所在的类的所有的构造函数中对这个变量赋初值。
- 当函数的参数类型申明为final时,阐明该参数是只读型的。即你能够读取应用该参数,然而无奈扭转该参数的值
-
ThreadLocal的应用,以及应用的留神点?为什么会内存透露?
- ThreadLocal是多线程状况下避免对同一变量进行操作,每个线程有本人的本地变量进行操作,不相互影响.
- ThreadLocal的存储形式相似Map构造key和value,存储set,取值get,删除remove,key为以后线程的援用
- ThreadLocal的key是软援用,因为ThreadLcoal的存储构造是Entry,而Entry继承了WeakReference<ThreadLocal<?>>,当存储数据的时候new进去的实例Entry,存储的key就是弱援用,这样会导致一个内存溢出的问题,当内存不足的时候JVM会进行GC,GC会将软援用进行回收,那么key被回收了,value会始终存在,这会使得内存一直的扩充但又无奈进行回收。所以 在应用ThreadLocal的时候应用实现后肯定要在finally块中进行remove
-
Java中对象的援用分为哪几类?
- 强援用(StrongReference)
最强悍的个别都是new进去的实例对象 - 软援用(SoftReference)
它的作用是通知垃圾回收器,程序中的哪些对象是不那么重要,当内存不足的时候是能够被临时回收的。当JVM中的内存不足的时候,垃圾回收器会开释那些只被软援用所指向的对象。如果全副开释完这些对象之后,内存还有余,才会抛出OutOfMemory谬误。软援用非常适合于创立缓存。当零碎内存不足的时候,缓存中的内容是能够被开释的 - 弱援用(WeakReferene)
它的作用是援用一个对象,然而并不阻止该对象被回收。如果应用一个强援用的话,只有该援用存在,那么被援用的对象是不能被回收的。弱援用则没有这个问题。在垃圾回收器运行的时候,如果一个对象的所有援用都是弱援用的话,该对象会被回收。弱援用的作用在于解决强援用所带来的对象之间在存活工夫上的耦合关系。弱援用最常见的用途是在汇合类中,尤其在哈希表中。哈希表的接口容许应用任何Java对象作为键来应用。当一个键值对被放入到哈希表中之后,哈希表对象自身就有了对这些键和值对象的援用。如果这种援用是强援用的话,那么只有哈希表对象自身还存活,其中所蕴含的键和值对象是不会被回收的。如果某个存活工夫很长的哈希表中蕴含的键值对很多,最终就有可能消耗掉JVM中全副的内存 - 虚援用(PhantomReference)
在Object类外面有个finalize办法,其设计的初衷是在一个对象被真正回收之前,能够用来执行一些清理的工作。因为Java并没有提供相似C++的析构函数一样的机制,就通过 finalize办法来实现。然而问题在于垃圾回收器的运行工夫是不固定的,所以这些清理工作的理论运行工夫也是不能预知的。幽灵援用(phantom reference)能够解决这个问题。在创立幽灵援用PhantomReference的时候必须要指定一个援用队列。当一个对象的finalize办法曾经被调用了之后,这个对象的幽灵援用会被退出到队列中。通过查看该队列外面的内容就晓得一个对象是不是曾经筹备要被回收了.
程序能够通过判断援用队列中是否曾经退出了虚援用,来理解被援用的对象是否将要被垃圾回收。如果程序发现某个虚援用曾经被退出到援用队列,那么就能够在所援用的对象的内存被回收之前采取必要的口头.
- 强援用(StrongReference)
- ConcurrentHashMap与Map的区别以及ConcurrentHashMap的实现原理?
- 多路复用IO的原理?
-
中间件
-
redis的根本数据结构?
- String、Set、Sorted Set、Map、List
-
redis根本数据类型联合具体的场景?
- 实现购物车用什么数据结构类型? — Map
- 实现随机取出3个获奖名单?– set,应用set的pop弹出命令
- 实现排名的前3名?– Sorted Set的ZRang命令排序取前3个数值
- 取一个人的独特好友? — Set,应用set的union命令
-
redis为什么很快?
- 单线程,无需线程的上下文切换
- 内存操作
- 多路复用IO模型
-
-
redis实现分布式锁?
- redis实现分布式锁形式是setnx命令,也就是多线程在并发的时候对同一个key进行设置数值,其余的线程在进行抢占锁的时候会发现这个key曾经存在数值,那么就会放弃这个抢占锁的操作
-
redis的分布式锁的实现会遇到很多坑:
- A线程在setnx之后始终解决业务不开释锁,就会导致其余的线程始终期待 无奈拿到锁,这样线程池就会被打满,所以线程在设置锁时候须要增加锁的超时工夫,当锁的执行超过了工夫就会被动开释锁
-
A线程在执行过程中在规定的超时工夫内实现业务解决并发送了开释了锁的del命令,然而因为零碎负荷/网络起因导致命令没有发送胜利,到了超时工夫,被动开释了锁,那么B线程拿到了锁,B线程在处理过程中进行,此时A的命令重试胜利删除了锁,那么B这个会有不可预计的谬误.所以咱们在del的时候要先拿到这个key对应的value,value的值不要惟一这样会呈现误删除锁的状况,并且get和del的操作要保障原子性(Lua脚本来编写,lua脚本只是一行操作命令开始和完结两头无论多少操作,都是一次性执行)
- zookeeper与eureka的区别?应用注册核心的优缺点?
- 两个都是先实现服务注册的中间件
- CAP实践:C:一致性 A:可用性 P:分区容错性
-
zookeeper只能保障CAP实践中的CP,一致性其实并不一定是强一致性而是最终一致性,P分区容错型也就是就集群的高可用,这个是分布式系统的根底,因为zk的选举机制会导致zk的集群的不可用,当zk的主挂了之后进行选举的时候 整个集群是不可用的这个在分布式系统是致命的,能够容忍数据的不统一然而不可用这个无论那个零碎业务都无奈接受的(当master节点因为网络故障与其余节点失去分割时,残余节点会从新进行leader选举。问题在于,选举leader的工夫太长,30 ~ 120s, 且选举期间整个zk集群都是不可用的,这就导致在选举期间注册服务瘫痪)。
- eureka保障了CAP中的AP:P就不说了这是根底,C也不是强一致性保障最终一致性即可,A:可用性,Eureka还有一种自我爱护机制,如果在15分钟内超过85%的节点都没有失常的心跳,那么Eureka就认为客户端与注册核心呈现了网络故障:1.Eureka不再从注册列表中移除因为长时间没收到心跳而应该过期的服务2.Eureka依然可能承受新服务的注册和查问申请,然而不会被同步到其它节点上(即保障以后节点仍然可用)3.当网络稳固时,以后实例新的注册信息会被同步到其它节点中(Eureka领有客户端缓存技术:Eureka分为客户端程序与服务器端程序两个局部,客户端程序负责向外提供注册与发现服务接口)。 所以即使Eureka集群中所有节点都生效,或者产生网络宰割故障导致客户端不能拜访任何一台Eureka服务器;Eureka服务的消费者依然能够通过 Eureka客户端缓存来获取现有的服务注册信息。甚至最极其的环境下,所有失常的Eureka节点都不对申请产生相应,也没有更好的服务器解决方案来解 决这种问题时;得益于Eureka的客户端缓存技术,消费者服务依然能够通过Eureka客户端查问与获取注册服务信息)
- zookeeper来实现分布式锁?
- 首先zk有4个节点类型:长久节点、长久程序节点、长期节点、长期程序节点
-
zk实现分布式锁的节点就是利用了长期程序节点的个性,实现zk的分布式锁一个长久节点作为root节点,在该节点下新建长期程序节点,比方Client-A在/root/lock1节点,CLient-B在目录下新建/root/lock2节点,所有的节点都是程序递增的,那么客户端在获取锁的时候判断本人的节点是否是以后节点汇合中的最小节点,是就获取到锁,不是就在以后节点的上个节点增加watcher来监听lock1节点是否存在,CLient-C则监听lock2,记得不是监听第一个节点,如果监听第一个节点,当节点删除后,所有的长期节点都会收到这个音讯,多个节点又同时去争抢这个锁(羊群效用),当变动产生时,ZooKeeper会触发一个特定的znode节点的变动导致的所有监督点的汇合。如果有1000个客户端通过exists操作监督这个znode节点,那么当znode节点创立后就会发送1000个告诉,因此被监督的znode节点的一个变动会产生一个尖峰的告诉,该尖峰可能带来影响,例如,在尖峰时刻提交的操作提早。可能的话,咱们倡议在应用ZooKeeper时,防止在一个特定节点设置大量的监督点,最好是每次在特定的znode节点上,只有大量的客户端设置监督点,现实状况下最多只设置一个.
- 音讯的反复生产如何解决?音讯来实现分布式事务?
-
数据库
-
Mysql应用的引擎是什么?有什么区别?
- InnerDB/MySlamDB
- MySlam:不反对事务也不反对外键,不反对行级锁,只反对并发插入的表锁,MyISAM也是应用B+tree索引然而和Innodb的在具体实现上有些不同(优缺点:MyISAM的劣势在于占用空间小,处理速度快。毛病是不反对事务的完整性和并发性)
- InnerDB反对事务,提供自增长列,反对外键指出MVCC行级锁反对的索引类型是B+树(InnoDB的劣势在于提供了良好的事务处理、解体修复能力和并发管制。毛病是读写效率较差,占用的数据空间绝对较大)
-
Mysql中的索引的数据结构是什么?B+树与Hash索引的区别?
- InnerDB应用的是B+数构造
-
Mysql索引生效以及最左匹配准则?
- mysql查问优化器会判断纠正这条sql语句该以什么样的程序执行效率最高,最初才生成真正的执行打算。所以,当然是咱们能尽量的利用到索引时的查问程序效率最高咯,所以mysql查问优化器会最终以这种程序进行查问执行。
- explain select * from test where b<10 and c <10;
explain select * from test where a<10 and c <10;
为什么 b<10 and c <10,没有用到索引?而 a<10 and c <10用到了?
当b+树的数据项是复合的数据结构,比方(name,age,sex)的时候,b+数是依照从左到右的程序来建设搜寻树的,比方当(a,b,c)这样的数据来检索的时候,b+树会优先比拟name来确定下一步的所搜方向,如果name雷同再顺次比拟age和sex,最初失去检索的数据;但当(b,c)这样的没有name的数据来的时候,b+树就不晓得下一步该查哪个节点,因为建设搜寻树的时候name就是第一个比拟因子,必须要先依据name来搜寻能力晓得下一步去哪里查问。比方当(a,c)这样的数据来检索时,b+树能够用name来指定搜寻方向,但下一个字段age的缺失,所以只能把名字等于张三的数据都找到,而后再匹配性别是F的数据了, 这个是十分重要的性质,即索引的最左匹配个性.
-
引申想到 ACID的实现原理?数据库的隔离级别?数据库的乐观锁?
-
ACID:
- A(原子性):一个事务中多个操作要么都胜利要么都失败
- C(一致性):在一个事务执行的前后,必须保障从一个统一状态变成另一个统一状态,举个例子:A和B两者的钱一共400元,A和B来回转账,不管转几次,怎么转最终后果都是A和B总计400元
- I(隔离性):一个事务的操作与其余事务的操作是互不影响互相隔离的
- D(持久性):对一个事务进行提交,如果提交胜利,那么数据肯定永恒保留下来,即使系统故障了,复原当前数据应该仍在。
-
隔离级别
- 读未提交:啥玩意不是
- 读已提交:可防止脏读
- 可反复读:可防止脏读,不可反复读,这是Mysql默认的隔离级别
- 序列化:可防止脏读,不可反复读,幻读
- oracle只有读已提交(默认)和串型化2种隔离级别
- 脏读:指当一个事务正在拜访数据,并且对数据进行了批改,而这种数据还没有提交到数据库中,这时,另外一个事务也拜访这个数据,而后应用了这个数据。因为这个数据还没有提交那么另外一个事务读取到的这个数据咱们称之为脏数据。根据脏数据所做的操作肯能是不正确的。
- 不可反复读:指在一个事务内,屡次读同一数据。在这个事务还没有执行完结,另外一个事务也拜访该同一数据,那么在第一个事务中的两次读取数据之间,因为第二个事务的批改第一个事务两次读到的数据可能是不一样的,这样就产生了在一个事物内两次间断读到的数据是不一样的,这种状况被称为是不可反复读。
- 幻象读:一个事务先后读取一个范畴的记录,但两次读取的纪录数不同,咱们称之为幻象读(两次执行同一条 select 语句会呈现不同的后果,第二次读会减少一数据行,并没有说这两次执行是在同一个事务中
-
-
-
数据结构
- 红黑数与均衡二叉树的区别?
- 红黑树的最长门路与最短门路的关系?
- 引申–Map的数据结构的变动由之前的链表构造–>红黑树的转换?
发表回复