我是如何进入阿里巴巴的-面向春招应届生Java面试指南(八)

Java基础

一、List 和 Set 的区别 List:1.能够容许重复的对象。    2.能够插入多个null元素。 3.是一个有序容器,保持了每一个元素的插入顺序,输出的顺序就是插入的顺序。 4.经常使用的实现类有 ArrayList、LinkedList 和 Vector。ArrayList 最为流行,它提供了使用索引的随意访问,而 LinkedList 则对于常常须要从 List 中添加或删除元素的场合更为合适。 Set: 1.不容许重复对象    2. 无序容器,你没法保证每一个元素的存储顺序,TreeSet经过 Comparator 或者 Comparable 维护了一个排序顺序。 3. 只容许一个 null 元素 4.Set 接口最流行的几个实现类是 HashSet、LinkedHashSet 以及 TreeSet。最流行的是基于 HashMap 实现的 HashSet;TreeSet 还实现了 SortedSet 接口,所以 TreeSet 是一个根据其 compare() 和 compareTo() 的定义进行排序的有序容器。java

二、HashSet 是如何保证不重复的mysql

HashSet是哈希表结构,当一个元素要存入HashSet集合时,首先经过自身的hashCode方法算出一个值,而后经过这个值查找元素在集合中的位置,若是该位置没有元素,那么就存入。若是该位置上有元素,那么继续调用该元素的equals方法进行比较,若是equals方法返回为真,证实这两个元素是相同元素,则不存。不然则在该位置上存储2个元素(通常不可能重复)因此当一个自定义的对象想正确存入HashSet集合,那么应该重写Object的hashCode和equals。HashSet是经过hashCode()和equals()方法确保元素无序不重复的react

公众号推荐

  • 全网惟一一个从0开始帮助Java开发者转作大数据领域的公众号~程序员

  • 大数据技术与架构或者搜索import_bigdata关注~web

  • 海量【java和大数据的面试题+视频资料】整理在公众号,关注后能够下载~面试

三、HashMap 是线程安全的吗,为何不是线程安全的(最好画图说明多线程环境下不安全)? 当多个线程同时检测到总数量超过门限值的时候就会同时调用resize操做,各自生成新的数组并rehash后赋给该map底层的数组table,结果最终只有最后一个线程生成的新数组被赋给table变量,其余线程的均会丢失。并且当某些线程已经完成赋值而其余线程刚开始的时候,就会用已经被赋值的table做为原始数组,这样也会有问题。 四、HashMap 的扩容过程 当HashMap的size达到临界值capacity * loadFactor - 1时,HashMap会进行扩容,将自身容量增长一倍。redis

好比对未指定capacity和loadFactor的HashMap,缺省容量和负载因子分别为16和0.75,所以当map中存储的元素数量达到16 * 0.75 - 1即为11时,该map会将自身容量扩大到2 * 16 = 32。 五、HashMap 1.7 与 1.8 的 区别,说明 1.8 作了哪些优化,如何优化的? JDK1.7中 使用一个Entry数组来存储数据,用key的hashcode取模来决定key会被放到数组里的位置,若是hashcode相同,或者hashcode取模后的结果相同(hash collision),那么这些key会被定位到Entry数组的同一个格子里,这些key会造成一个链表。 在hashcode特别差的状况下,比方说全部key的hashcode都相同,这个链表可能会很长,那么put/get操做均可能须要遍历这个链表 也就是说时间复杂度在最差状况下会退化到O(n) JDK1.8中 使用一个Node数组来存储数据,但这个Node多是链表结构,也多是红黑树结构 若是插入的key的hashcode相同,那么这些key也会被定位到Node数组的同一个格子里。 若是同一个格子里的key不超过8个,使用链表结构存储。 若是超过了8个,那么会调用treeifyBin函数,将链表转换为红黑树。 那么即便hashcode彻底相同,因为红黑树的特色,查找某个特定元素,也只须要O(log n)的开销 也就是说put/get的操做的时间复杂度最差只有O(log n) 六、final finally finalize final修饰符(关键字)。被final修饰的类,就意味着不能再派生出新的子类,不能做为父类而被子类继承。所以一个类不能既被abstract声明,又被final声明。将变量或方法声明为final,能够保证他们在使用的过程当中不被修改。被声明为final的变量必须在声明时给出变量的初始值,而在之后的引用中只能读取。被final声明的方法也一样只能使用,不能重载。 finally是在异常处理时提供finally块来执行任何清除操做。无论有没有异常被抛出、捕获,finally块都会被执行。try块中的内容是在无异常时执行到结束。catch块中的内容,是在try块内容发生catch所声明的异常时,跳转到catch块中执行。finally块则是不管异常是否发生,都会执行finally块的内容,因此在代码逻辑中有须要不管发生什么都必须执行的代码,就能够放在finally块中。 finalize是方法名。java技术容许使用finalize()方法在垃圾收集器将对象从内存中清除出去以前作必要的清理工做。这个方法是由垃圾收集器在肯定这个对象没有被引用时对这个对象调用的。它是在object类中定义的,所以全部的类都继承了它。子类覆盖finalize()方法以整理系统资源或者被执行其余清理工做。finalize()方法是在垃圾收集器删除对象以前对这个对象调用的。 七、强引用 、软引用、 弱引用、虚引用 强引用: 只要引用存在,垃圾回收器永远不会回收 Object obj = new Object(); //可直接经过obj取得对应的对象 如obj.equels(new Object()); 而这样 obj对象对后面new Object的一个强引用,只有当obj这个引用被释放以后,对象才会被释放掉,这也是咱们常常所用到的编码形式。 软引用: 非必须引用,内存溢出以前进行回收,能够经过如下代码实现 Object obj = new Object(); SoftReference sf = new SoftReference(obj); obj = null; sf.get();//有时候会返回null 这时候sf是对obj的一个软引用,经过sf.get()方法能够取到这个对象,固然,当这个对象被标记为须要回收的对象时,则返回null; 软引用主要用户实现相似缓存的功能,在内存足够的状况下直接经过软引用取值,无需从繁忙的真实来源查询数据,提高速度;当内存不足时,自动删除这部分缓存数据,从真正的来源查询这些数据。 弱引用: 第二次垃圾回收时回收,能够经过以下代码实现 Object obj = new Object(); WeakReference wf = new WeakReference(obj); obj = null; wf.get();//有时候会返回null wf.isEnQueued();//返回是否被垃圾回收器标记为即将回收的垃圾 弱引用是在第二次垃圾回收时回收,短期内经过弱引用取对应的数据,能够取到,当执行过第二次垃圾回收时,将返回null。 弱引用主要用于监控对象是否已经被垃圾回收器标记为即将回收的垃圾,能够经过弱引用的isEnQueued方法返回对象是否被垃圾回收器标记。 虚引用: 垃圾回收时回收,没法经过引用取到对象值,能够经过以下代码实现 Object obj = new Object(); PhantomReference pf = new PhantomReference(obj); obj=null; pf.get();//永远返回null pf.isEnQueued();//返回是否从内存中已经删除 虚引用是每次垃圾回收的时候都会被回收,经过虚引用的get方法永远获取到的数据为null,所以也被成为幽灵引用。 虚引用主要用于检测对象是否已经从内存中删除。算法

八、Java反射 一个程序员在写程序的时须要使用第二个程序员所写的类,但第二个程序员并没完成他所写的类。那么第一个程序员的代码是不能经过编译的。此时,利用Java反射的机制,就可让第一个程序员在没有获得第二个程序员所写的类的时候,来完成自身代码的编译。 Java的反射机制它知道类的基本结构,这种对Java类结构探知的能力,咱们称为Java类的“自审”。如eclipse中,一按点,编译工具就会自动的把该对象可以使用的全部的方法和属性所有都列出来,供用户进行选择。这就是利用了Java反射的原理,是对咱们建立对象的探知、自审。spring

九、Arrays.sort 实现原理和 Collection 实现原理 Collections.sort的实现是Arrays.sort,java中Arrays.sort使用了两种排序方法,快速排序和优化的合并排序。 快速排序主要是对哪些基本类型数据(int,short,long等)排序, 而合并排序用于对对象类型进行排序。 使用不一样类型的排序算法主要是因为快速排序是不稳定的,而合并排序是稳定的。这里的稳定是指比较相等的数据在排序以后仍然按照排序以前的先后顺序排列。对于基本数据类型,稳定性没有意义,而对于对象类型,稳定性是比较重要的,由于对象相等的判断可能只是判断关键属性,最好保持相等对象的非关键属性的顺序与排序前一直;另一个缘由是因为合并排序相对而言比较次数比快速排序少,移动(对象引用的移动)次数比快速排序多,而对于对象来讲,比较通常比移动耗时。 补充一点合并排序的时间复杂度是nlogn, 快速排序的平均时间复杂度也是nlogn,可是合并排序的须要额外的n个引用的空间sql

十、LinkedHashMap的应用 LinkedHashMap是Map接口的哈希表和连接列表实现,具备可预知的迭代顺序。LinkedHashMap实现与HashMap的不一样之处在于,LinkedHashMap维护着一个运行于全部条目的双重连接列表。此连接列表定义了迭代顺序,该迭代顺序能够是插入顺序(insert-order)或者是访问顺序,其中默认的迭代访问顺序就是插入顺序,便可以按插入的顺序遍历元素,这点和HashMap有很大的不一样。 十一、cloneable接口实现原理 一、基本类型 若是变量是基本类型,则拷贝其值,好比:int、float、long等。 二、String字符串 这个比较特殊,拷贝的是地址,是个引用,可是在修改的时候,它会从字符串池(String Pool)中从新生成新的字符串,原有的字符串对象保持不变,此处能够认为String是个基本类型。 三、对象 若是变量时一个实例对象,则拷贝地址引用,也就是说此时新拷贝出的对象与原有对象共享该实例变量,不受访问权限的限制。这在Java中很疯狂,由于它突破了访问权限的定义,一个private修饰的变量,居然能够被两个实例对象访问。 十二、异常分类以及处理机制

1三、wait和sleep的区别 sleep 是让线程进入阻塞状态,必定时间以后回到非阻塞状态,从而能够从新得到 CPU。wait 调用的时候须要先得到该 Object 的锁,调用 wait 后,会把当前的锁释放掉同时阻塞住;当别的线程调用该 Object 的 notify/notifyAll 以后,有可能获得 CPU,同时从新得到锁。因为有如上描述锁的设计,只要在 notify 的时候首先得到锁,就能够保证 notify 的时候或者处于 wait 线程得到锁以前,或者正在 wait,从而保证不会丢掉此次 notify 信息。

1四、数组在内存中如何分配

一、简单的值类型的数组,每一个数组成员是一个引用(指针),引用到栈上的空间(由于值类型变量的内存分配在栈上)

二、引用类型,类类型的数组,每一个数组成员还是一个引用(指针),引用到堆上的空间(由于类的实例的内存分配在堆上) Java 并发 一、synchronized 的实现原理以及锁优化? 二、volatile 的实现原理? 三、Java 的信号灯? 四、synchronized 在静态方法和普通方法的区别?

  1. 修饰一个代码块,被修饰的代码块称为同步语句块,其做用的范围是大括号{}括起来的代码,做用的对象是调用这个代码块的对象;
  2. 修饰一个方法,被修饰的方法称为同步方法,其做用的范围是整个方法,做用的对象是调用这个方法的对象;
  3. 修改一个静态的方法,其做用的范围是整个静态方法,做用的对象是这个类的全部对象;
  4. 修改一个类,其做用的范围是synchronized后面括号括起来的部分,做用主的对象是这个类的全部对象。 五、怎么实现全部线程在等待某个事件的发生才会去执行?

六、CAS?CAS 有什么缺陷,如何解决?

七、synchronized 和 lock 有什么区别?

八、Hashtable 是怎么加锁的 ?

九、HashMap 的并发问题?

十、ConcurrenHashMap 介绍?1.8 中为何要用红黑树?

红黑树是不符合AVL树的平衡条件的,即每一个节点的左子树和右子树的高度最多差1的二叉查找树。可是提出了为节点增长颜色,红黑是用非严格的平衡来换取增删节点时候旋转次数的下降,任何不平衡都会在三次旋转以内解决,而AVL是严格平衡树,所以在增长或者删除节点的时候,根据不一样状况,旋转的次数比红黑树要多。因此红黑树的插入效率更高!

红黑树的查询性能略微逊色于AVL树,由于他比avl树会稍微不平衡最多一层,也就是说红黑树的查询性能只比相同内容的avl树最多多一次比较,可是,红黑树在插入和删除上完爆avl树,avl树每次插入删除会进行大量的平衡度计算,而红黑树为了维持红黑性质所作的红黑变换和旋转的开销,相较于avl树为了维持平衡的开销要小得多

十一、AQS

十二、如何检测死锁?怎么预防死锁?

1三、Java 内存模型?

1四、如何保证多线程下 i++ 结果正确?

1五、线程池的种类,区别和使用场景?

1六、分析线程池的实现原理和线程的调度过程?

1七、线程池如何调优,最大数目如何确认?

1八、ThreadLocal原理,用的时候须要注意什么?

1九、CountDownLatch 和 CyclicBarrier 的用法,以及相互之间的差异?

20、LockSupport工具

2一、Condition接口及其实现原理

2二、Fork/Join框架的理解

2三、分段锁的原理,锁力度减少的思考

2四、八种阻塞队列以及各个阻塞队列的特性

Spring

一、BeanFactory 和 FactoryBean?

实现 BeanFactory 接口的类代表此类事一个工厂,做用就是配置、新建、管理 各类Bean。

而 实现 FactoryBean 的类代表此类也是一个Bean,类型为工厂Bean(Spring中共有两种bean,一种为普通bean,另外一种则为工厂bean)。顾名思义,它也是用来管理Bean的,而它自己由spring管理。

二、Spring IOC 的理解,其初始化过程?

Spring IOC的核心是BeanFactory

其实SpringIOC初始化的过程就是准备好BeanFactory的过程。

(1)定位并获取资源文件 ClassPathResource res = new ClassPathResource("my/applicationContext.xml"); 由于对象和对象之间的关系存储在xml或properties等语义化配置文件中,首先要定位到配置文件。用资源加载器ResourceLoader将资源文件路径转换为对应的Resource

(2)解析资源文件 XmlBeanFactory bf = new XmlBeanFactory(res);

(3)注册 DefaultListableBeanDefiniton.registerBeanDefiniton利用解析好的BeanDefinition对象完成最终的注册。将beanName和BeanDefinition做为键值放到了beanFactory的map中

三、BeanFactory 和 ApplicationContext?

若是说BeanFactory是Spring的心脏,那么ApplicationContext就是完整的躯体了,ApplicationContext由BeanFactory派生而来,提供了更多面向实际应用的功能。在BeanFactory中,不少功能须要以编程的方式实现,而在ApplicationContext中则能够经过配置实现。

BeanFactorty接口提供了配置框架及基本功能,可是没法支持spring的aop功能和web应用。而ApplicationContext接口做为BeanFactory的派生,于是提供BeanFactory全部的功能。并且ApplicationContext还在功能上作了扩展.

四、Spring Bean 的生命周期,如何被管理的?

Spring上下文中的Bean也相似,【Spring上下文的生命周期】

  1. 实例化一个Bean,也就是咱们一般说的new
  2. 按照Spring上下文对实例化的Bean进行配置,也就是IOC注入
  3. 若是这个Bean实现了BeanNameAware接口,会调用它实现的setBeanName(String beanId)方法,此处传递的是Spring配置文件中Bean的ID
  4. 若是这个Bean实现了BeanFactoryAware接口,会调用它实现的setBeanFactory(),传递的是Spring工厂自己(能够用这个方法获取到其余Bean)
  5. 若是这个Bean实现了ApplicationContextAware接口,会调用setApplicationContext(ApplicationContext)方法,传入Spring上下文,该方式一样能够实现步骤4,但比4更好,觉得ApplicationContext是BeanFactory的子接口,有更多的实现方法
  6. 若是这个Bean关联了BeanPostProcessor接口,将会调用postProcessBeforeInitialization(Object obj, String s)方法,BeanPostProcessor常常被用做是Bean内容的更改,而且因为这个是在Bean初始化结束时调用After方法,也可用于内存或缓存技术
  7. 若是这个Bean在Spring配置文件中配置了init-method属性会自动调用其配置的初始化方法
  8. 若是这个Bean关联了BeanPostProcessor接口,将会调用postAfterInitialization(Object obj, String s)方法 注意:以上工做完成之后就能够用这个Bean了,那这个Bean是一个single的,因此通常状况下咱们调用同一个ID的Bean会是在内容地址相同的实例
  9. 当Bean再也不须要时,会通过清理阶段,若是Bean实现了DisposableBean接口,会调用其实现的destroy方法
  10. 最后,若是这个Bean的Spring配置中配置了destroy-method属性,会自动调用其配置的销毁方法 以上10步骤能够做为面试或者笔试的模板,另外咱们这里描述的是应用Spring上下文Bean的生命周期,若是应用Spring的工厂也就是BeanFactory的话去掉第5步就Ok了 五、Spring Bean 的加载过程是怎样的? 六、若是要你实现Spring AOP,请问怎么实现? 七、若是要你实现Spring IOC,你会注意哪些问题? 八、Spring 是如何管理事务的,事务管理机制? 九、Spring 的不一样事务传播行为有哪些,干什么用的? 十、Spring 中用到了那些设计模式? 十一、Spring MVC 的工做原理? 十二、Spring 循环注入的原理? 1三、Spring AOP的理解,各个术语,他们是怎么相互工做的? 1四、Spring 如何保证 Controller 并发的安全?

Netty

一、BIO、NIO和AIO

I/O能够分为两种:同步IO和异步IO,同步I/O最多见的是 BIO(Blocking IO)、NIO(Non-Blocking IO)

BIO:是当发起I/O的读或写操做时,均为阻塞方式,直到应用程序读到了流或者将流写入数据。

NIO:基于事件驱动思想,常采用reactor(反应器)模式。当发起 IO请求时,应用程序是非阻塞的。当SOCKET有流可读或写的时候,

由操做系统通知应用程序,应用程序再将流读取到缓冲区或者写入系统。

AIO:一样基于事件驱动的思想,一般采用Proactor(前摄器模式)实现。在进行I/O操做时,直接调用API的read或write,这两种方法

均为异步。对于读操做,操做系统将数据读到缓冲区,并通知应用程序,对于写操做,操做系统将write方法传递的流写入并主动通知

应用程序。它节省了NIO中遍历事件通知队列的代价。 二、Netty 的各大组件

三、Netty的线程模型 netty经过Reactor模型基于多路复用器接收并处理用户请求(能讲就多讲一点),内部实现了两个线程池,boss线程池和work线程池,其中boss线程池的线程负责处理请求的accept事件,当接收到accept事件的请求时,把对应的socket封装到一个NioSocketChannel中,并交给work线程池,其中work线程池负责请求的read和write事件

四、TCP 粘包/拆包的缘由及解决方法

一、发送端给每一个数据包添加包首部,首部中应该至少包含数据包的长度,这样接收端在接收到数据后,经过读取包首部的长度字段,便知道每个数据包的实际长度了。

二、发送端将每一个数据包封装为固定长度(不够的能够经过补0填充),这样接收端每次从接收缓冲区中读取固定长度的数据就天然而然的把每一个数据包拆分开来。

三、能够在数据包之间设置边界,如添加特殊符号,这样,接收端经过这个边界就能够将不一样的数据包拆分开。

五、了解哪几种序列化协议?包括使用场景和如何去选择 xml / json / protobuf/ thtift 六、Netty的零拷贝实现

七、Netty的高性能表如今哪些方面

分布式相关 一、Dubbo的底层实现原理和机制

服务容器负责启动,加载,运行服务提供者。

服务提供者在启动时,向注册中心注册本身提供的服务。

服务消费者在启动时,向注册中心订阅本身所需的服务。

注册中心返回服务提供者地址列表给消费者,若是有变动,注册中心将基于长链接推送变动数据给消费者。

服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,若是调用失败,再选另外一台调用。

服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心

二、描述一个服务从发布到被消费的详细过程

本地有对远程方法的描述,包括方法名、参数、返回值,在dubbo中是远程和本地使用一样的接口;而后呢,要有对网络通讯的封装,要对调用方来讲通讯细节是彻底不可见的,网络通讯要作的就是将调用方法的属性经过必定的协议(简单来讲就是消息格式)传递到服务端;服务端按照协议解析出调用的信息;执行相应的方法;在将方法的返回值经过协议传递给客户端;客户端再解析;在调用方式上又能够分为同步调用和异步调用;简单来讲基本就这个过程

三、分布式系统怎么作服务治理

四、接口的幂等性的概念

幂等性是系统的接口对外一种承诺(而不是实现), 承诺只要调用接口成功, 外部屡次调用对系统的影响是一致的. 声明为幂等的接口会认为外部调用失败是常态, 而且失败以后必然会有重试.

五、消息中间件如何解决消息丢失问题

RabbitMQ引入了消息确认机制,当消息处理完成后,给Server端发送一个确认消息,来告诉服务端能够删除该消息了,若是链接断开的时候,Server端没有收到消费者发出的确认信息,则会把消息转发给其余保持在线的消费者。

六、Dubbo的服务请求失败怎么处理

1.超时设置

DUBBO消费端设置超时时间须要根据业务实际状况来设定, 若是设置的时间过短,一些复杂业务须要很长时间完成,致使在设定的超时时间内没法完成正常的业务处理。 这样消费端达到超时时间,那么dubbo会进行重试机制,不合理的重试在一些特殊的业务场景下可能会引起不少问题,须要合理设置接口超时时间。 好比发送邮件,可能就会发出多份重复邮件,执行注册请求时,就会插入多条重复的注册数据。

2.重连机制

dubbo在调用服务不成功时,默认会重试2次。 Dubbo的路由机制,会把超时的请求路由到其余机器上,而不是本机尝试,因此 dubbo的重试机器也能必定程度的保证服务的质量。 可是若是不合理的配置重试次数,当失败时会进行重试屡次,这样在某个时间点出现性能问题,调用方再连续重复调用, 系统请求变为正常值的retries倍,系统压力会大增,容易引发服务雪崩,须要根据业务状况规划好如何进行异常处理,什么时候进行重试。

七、重连机制会不会形成错误

八、对分布式事务的理解

九、如何实现负载均衡,有哪些算法能够实现?

十、Zookeeper的用途,选举的原理是什么?

十一、数据的垂直拆分水平拆分。

十二、zookeeper原理和适用场景

1三、zookeeper watch机制

一个Watch事件是一个一次性的触发器,当被设置了Watch的数据发生了改变的时候,则服务器将这个改变发送给设置了Watch的客户端,以便通知它们 1四、redis/zk节点宕机如何处理

1五、分布式集群下如何作到惟一序列号

1六、如何作一个分布式锁

1七、用过哪些MQ,怎么用的,和其余mq比较有什么优缺点,MQ的链接是线程安全的吗

1八、MQ系统的数据如何保证不丢失

1九、列举出你能想到的数据库分库分表策略;分库分表后,如何解决全表查询的问题

20、zookeeper的选举策略

2一、全局ID

数据库

一、mysql分页有什么优化

第二种方法,在查询下一页时把上一页的行id做为参数传递给客户端程序,而后sql就改为了 select * from table where id>3000000 limit 10; 这条语句执行也是在毫秒级完成的,id>300w其实就是让mysql直接跳到这里了,不用依次在扫描全面全部的行 若是你的table的主键id是自增的,而且中间没有删除和断点,那么还有一种方式,好比100页的10条数据 select * from table where id>100*10 limit 10;

二、悲观锁、乐观锁

三、组合索引,最左原则

多列字段作索引,state/city/zipCode,想要索引生效的话,只能使用以下的组合 state/city/zipCode state/city state

其余方式(如city,city/zipCode),则索引不会生效 这种现象是怎么致使的?和索引的存储方式有关吗?

本人页参考了下其余网友的观点,我的认为,所谓最左前缀原则就是先要看第一列,在第一列知足的条件下再看左边第二列,以此类推。有位网友描述得很形象: 你能够认为联合索引是闯关游戏的设计

例如你这个联合索引是state/city/zipCode

那么state就是第一关 city是第二关, zipCode就是第三关

你必须匹配了第一关,才能匹配第二关,匹配了第一关和第二关,才能匹配第三关 你不能直接到第二关的

索引的格式就是第一层是state,第二层才是city

索引是由于B+树结构 因此查找快 若是单看第三列 是非排序的。 四、mysql 的表锁、行锁

五、mysql 性能优化

六、mysql的索引分类:B+,hash;什么状况用什么索引

七、事务的特性和隔离级别

缓存

一、Redis用过哪些数据数据,以及Redis底层怎么实现

二、Redis缓存穿透,缓存雪崩

三、如何使用Redis来实现分布式锁

四、Redis的并发竞争问题如何解决

1.独占锁 2.乐观锁(版本号办法)

3.采用排队的机制进行。将全部须要对同一个key的请求进行入队操做,而后用一个消费者线程从队头依次读出请求,并对相应的key进行操做。

五、Redis持久化的几种方式,优缺点是什么,怎么实现的

六、Redis的缓存失效策略

七、Redis集群,高可用,原理

八、Redis缓存分片

范围分片 hash分片 一致性hash

九、Redis的数据淘汰策略 最大缓存 在 redis 中,容许用户设置最大使用内存大小 server.maxmemory,默认为0,没有指定最大缓存,若是有新的数据添加,超过最大内存,则会使redis崩溃,因此必定要设置。redis

内存数据集大小上升到必定大小的时候,就会实行数据淘汰策略。

主键失效

做为一种按期清理无效数据的重要机制,在 Redis 提供的诸多命令中,EXPIRE、EXPIREAT、PEXPIRE、PEXPIREAT 以及 SETEX 和 PSETEX 都可以用来设置一条 Key-Value 对的失效时间,而一条 Key-Value 对一旦被关联了失效时间就会在到期后自动删除(或者说变得没法访问更为准确)

淘汰机制

随着不断的向redis中保存数据,当内存剩余空间没法知足添加的数据时,redis 内就会施行数据淘汰策略,清除一部份内容而后保证新的数据能够保存到内存中。 内存淘汰机制是为了更好的使用内存,用必定得miss来换取内存的利用率,保证redis缓存中保存的都是热点数据。 redis 提供 6种数据淘汰策略: voltile-lru:从已设置过时时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰 volatile-ttl:从已设置过时时间的数据集(server.db[i].expires)中挑选将要过时的数据淘汰 volatile-random:从已设置过时时间的数据集(server.db[i].expires)中任意选择数据淘汰 allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰 allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰 no-enviction(驱逐):禁止驱逐数据

JVM

一、详细jvm内存模型 原子性 可见性 有序性

二、讲讲什么状况下回出现内存溢出,内存泄漏? java 堆溢出 java栈溢出3. 方法区和运行时常量池溢出(PemGen)

三、说说Java线程栈

四、JVM 年轻代到年老代的晋升过程的判断条件是什么呢? 年龄达到必定值(年龄阈值,能够经过-XX:MaxTenuringThreshold来设置)的对象会被移动到年老代中

五、JVM 出现 fullGC 很频繁,怎么去线上排查问题?

六、类加载为何要使用双亲委派模式,有没有什么场景是打破了这个模式? 系统安全性:Java类随着加载它的类加载器一块儿具有了一种带有优先级的层次关系。好比,Java中的Object类,它存放在rt.jar之中,不管哪个类加载器要加载这个类,最终都是委派给处于模型最顶端的启动类加载器进行加载,所以Object在各类类加载环境中都是同一个类。若是不采用双亲委派模型,那么由各个类加载器本身取加载的话,那么系统中会存在多种不一样的Object类。 tomcat打破了这一模型,先Classpath, 而后War包,当前工程, 最后才是Tomcat相关目录.

七、类的实例化顺序

有父类的状况

  1. 加载父类 1.1 为静态属性分配存储空间并赋初始值 1.2 执行静态初始化块和静态初始化语句(从上至下)
  2. 加载子类 2.1 为静态属性分配存储空间 2.2 执行静态初始化块和静态初始化语句(从上至下)
  3. 加载父类构造器 3.1 为实例属性分配存数空间并赋初始值 3.2 执行实例初始化块和实例初始化语句 3.3 执行构造器内容
  4. 加载子类构造器 4.1 为实例属性分配存数空间并赋初始值 4.2 执行实例初始化块和实例初始化语句 4.3 执行构造器内容

八、JVM垃圾回收机制,什么时候触发MinorGC等操做 Minor GC触发条件:当Eden区满时,触发Minor GC。

Full GC触发条件:

(1)调用System.gc时,系统建议执行Full GC,可是没必要然执行

(2)老年代空间不足

(3)方法去空间不足

(4)经过Minor GC后进入老年代的平均大小大于老年代的可用内存

(5)由Eden区、From Space区向To Space区复制时,对象大小大于To Space可用内存,则把该对象转存到老年代,且老年代的可用内存小于该对象大小

九、JVM 中一次完整的 GC 流程(从 ygc 到 fgc)是怎样的

十、各类回收器,各自优缺点,重点CMS、G1

十一、各类回收算法

十二、OOM错误,stackoverflow错误,permgen space错误

公众号推荐

  • 全网惟一一个从0开始帮助Java开发者转作大数据领域的公众号~

  • 大数据技术与架构或者搜索import_bigdata关注~

  • 海量【java和大数据的面试题+视频资料】整理在公众号,关注后能够下载~

相关文章
相关标签/搜索