Interview Key Points Details

同步YunNote

 

 一、提及Java相关的性能调优层次,主要包括哪几个方面?

性能的优化在于掌握各部分组件性能的平衡点。

 

1、设计调优 :

优秀的设计结构可以规避很多潜在的性能问题,对系统性能的影响可能远远大于代码的优化.

(见二、常用的与性能相关的设计模式  四、常用设计优化的组件和相关思想方法

 

2、代码调优:

与设计优化相比,程序级别的优化更具技巧性。高效而精炼的代码,正确的函数使用方法和优良的软件开发习惯也对应用程序的整体性能有着决定性的影响。代码层次的优化是每个程序员的必修课,它也至始至终贯穿整个软件的编码过程。见(五、Java程序优化)

 

3、JVM调优

4、数据库调优

5、操作系统调优

 

二、常用的与性能相关的设计模式 

1、单例模式:是一种对象创建模式,用于产生一个对象的具体实例,它可以确保系统中一个类只产生一个实例。

 

      1.1:单例模式是如何提高系统整体性能的?

 单例模式保证确保系统中一个类只产生一个实例,在Java语言中,这样的行为能带来两大好处:

 

1)对于频繁使用的对象,可以省略创建对象所花费的时间,这对于那些创建重量级对象而言,是非常可观的一笔系统开销。

2)由于new操作的次数减少,因为对系统内存的使用频率也会降低,这将减轻GC压力,缩短GC停顿时间。

 

      1.2:性能最高且多线程安全的单例模式是怎样的?

 

public class StaticSingleton {

	private StaticSingleton() {
		System.out.println("StaticSingleton is create");
	}
	private static class SingletonHolder {
		private static StaticSingleton instance = new StaticSingleton();
	}

	public static StaticSingleton getInstance() {
		return SingletonHolder.instance;
	}
	public static void createString() {
		System.out.println("createString in Singleton");
	}
}

 

       在这个实现中,单例模式使用内部类来维护单例的实例,当StaticSignleton被加载时,其内部类不会被初始化,故可以确保当StaticSingleton类被载入JVM时,不会初始化单例类,而当getInstance()方法被调用时,才会加载SingletonHolder,从而初始化instance.同时,由于实例的建立是在类加载时完成,故天生对多线程友好,getInstance()方法也不需要使用同步关键字。

       因此,这种实现方式同时兼备以上两种实现的优点。使用内部类的方式实现单例,既可以做到延迟加载,也不必使用同步关键字,是一种比较完善的实现。  

 

       1.3:有什么例外的情况,可以导致系统生成多个实例?

1)不合法方法:在代码中,通过反射机制,强行调用单例类的私有构造函数,生成多个单例。

2)合法的方法:序列化和反序列化可能会破坏单例。一般来说,对单例进行序列化和反序列化的场景并不多见,但如果存在,就要多加注意。

 

2、代理模式:代理模式是一种很常见的设计模式。它使用代理对象完成用户请求,屏蔽用户对真实对象的访问。

 

        2.1:代理模式的应用场合主要有哪些?

        1)延迟加载:如系统启动的时候,需要去数据库查询相关数据的功能,可以使用代理模式,使用代理类,封装对数据库查询中的初始化操作,当系统启动时,初始化这个代理类,而非真实的数据库查询类,即代理类其实什么都没有做,他的构造是相当迅速的,即在系统启动时,将消耗资源最多的方法都使用代理模式分离,就可以加快系统的启动速度,减少用户的等待时间。而在用户真正做查询操作时,再由代理类,单独去加载真实的数据库查询类,完成用户的请求。这个过程就是使用代理模式实现了延迟加载。

 

其中在Hibernate框架中对实体类的动态代理是代理模式用于延迟加载的经典实现。 

 

        2)代理模式还可用于远程调用的网络代理

 

        3)考虑安全因素的安全代理。

 

 

        2.2:代理模式的类别:静态代理和动态代理,动态代理是指在运行时,动态生成代理类,静态代理变更维护成本高,动态代理使用字节码动态生成加载技术,在运行时生成并加载类。

 

         2.3:动态代理的实现方式:JDK自带的动态代理、GCLIB、Javassit或者ASM库。

 

         2.4:动态代理实现的基本步骤:

1)根据指定的回调类生成动态代理类的Class字节码,并保存在byte数组中。

2)通过反射方法ReflectUtils.defineClass(),调用ClassLoader.defineClass()方法,将字节码定义为类即将字节码装载到 ClassLoader中,完成类的加载。

3)使用反射机制ReflectUtils.newInstance()方法生成该类的实例。

 

 3、享元模式:享元模式是设计模式中少数几个以提高系统系统性能为目的的模式之一,它的核心思想是:如果一个系统中存在多个相同的对象,那么只需要共享一份对象的拷贝,而不必为每一次使用都创建新的对象。在享元模式中,由于需要构造和维护这些可以共享的对象,因此常常会出现一个工厂类,用于维护和创建对象。

【可以理解为工厂模式或者工厂模式的大杂烩】

 

          3.1:享元模式是如何提高系统性能的?

1)可以节省重复创建对象的开销,因为被享元模式维护的相同对象只会被创建一次,当创建对象比较耗时时,便可以大量节省时间。【即复用大对象,重量级对象以节省内存空间和对象创建时间】

2)由于创建对象的数量减少,所以对系统的内存要求也减少,这将使得GC的压力也相应地降低,进而使得系统拥有一个更健康的内存结构和更快的反应速度。享元模式的主要角色由享元工厂、抽象享元、具体享元类和主函数几部分组成。

 

           3.2:享元模式和对象池的最大不同在于?

享元模式和对象池的最大不同在于:享元对象是不可互相替代的,他们各自都有各自的含义和用途(多个工厂,工厂的大杂烩?),而对象池中的对象都是等价的,如数据库连接池中的数据库连接。

 

4、装饰者模式:装饰者模式拥有设计非常巧妙的结构,可以动态添加对象的功能。【委托机制和继承机制的区别】:在基本的设计原则中,有一条重要的设计准则叫做合成/聚合复用原则。根据该原则的思想,代码的复用的更多是要使用委托,而不是使用继承,因为继承是一种紧密耦合,任何父类的改动都会影响子类,不利于系统的维护。而委托是一种松散耦合,只要接口不变,委托类的改动并不会影响其上层对象。

         装饰者模式就充分利用了这种思想,通过委托机制,复用系统中的各个组件,在运行时,可以将这些功能组件进行叠加,从而构造一个“超级对象”,使其拥有所有这些组件的功能。而各个子功能模块,被很好地维护在各个组件的相关类中,拥有整洁的系统结构。

 

           4.1:装饰者模式的典型应用:

          1)装饰者模式的一个典型案例就是对输出结构进行增强。如对输出的结果增加HTML格式,增加HTTP头以进行网络传输等。一般来说,装饰者Decorator和被装饰者ConcreteComponent拥有相同的接口Component,被装饰者通常是系统的核心组件,完成特定的功能目标。而装饰者则可以在被装饰者的方法前后,加上特定的前置处理和后置处理,增强被装饰者的功能。

 

           2)JDK中的OutputStream和InputStream类族的实现是装饰者模式的典型应用,通过嵌套的方式不断地讲对象聚合起来,最终形成一个超级对象,并使之拥有相关子对象的功能。

 

          4.2:装饰者模式是如何去提高性能的?

装饰者模式更多是一种设计上的优化,有效地将性能组件和功能组件进行分离,从而提升模块的可维护性并增加模块的复用性。

【延展】:BufferedOutputStream的源码或者实现机制会是怎样的?

在FileOutputStream.write()的调用之前,会首先调用BufferedOutputStream.write(),从P33源码可以看到,BufferedOutputSteam.write()调用并不都是去磁盘写入数据,而是将数据写入缓存中,当缓存满时,才调用FileOuputSteam.write()方法实际写入数据。以此实现性能组件和功能组件的完美分离。

 

 

 5、观察者模式:在软件系统中,当一个对象的行为依赖于另一个对象的状态时,观察者模式就相当有用。

 

          5.1、观察者模式是如何提高性能的?

        和装饰者模式一样,更多也是设计上的优化,如不使用观察者模式提供的通用结构,而需要实现其类似的功能,则只能在另一个线程中不停监听对象所依赖的状态。在一个复杂的系统中,可能会因此开启很多线程来实现这一功能,这将使系统的性能产生额外的负担。观察者模式的意义也就在次,他可以在单线程中,使某一对象,及时得知自身所依赖的状态的变化。

 

         5.2、观察者模式的典型应用:

1)事件监听:Swing编程中JButton实现。

2)通知发布:

可以确保观察者在不使用轮询监控的情况下,及时收到相关消息和事件。如开户成功后的通知就可以不采用轮询,而是采用通知的方式。

 

         5.3、JDK内置的观察者模式:

JDK中直接为开发人员准备了一套观察者模式的实现,位于java.util包中,包括java.util.Obeserverable和java.util.Oberserver接口。

 

 

6、ValueObject模式:ValueObject模式提倡将一个对象的各个属性进行封装,将封装后的对象在网络中传递,从而是系统拥有更好的交互模型,并且减少网络通信数据,从而提高系统性能。

 

         6.1:ValueObject模式如何提高性能:

1)使用Value Object模式可以有效减少网络交互次数,减少网络数据的传输,提高远程调用方法的性能。

2)也能使系统接口具有更好的可维护性。

如客户端再向服务端请求获取订单信息的时候,如果一个订单信息包括有客户姓名,尚品名和订单数量等3个基本的属性,如果不进行Order类的封装,则会存在3次RMI的调用,经次调用后,将变为一次调用。

 

7、业务代理模式:

 

          7.1、VO模式和业务代理模式的区别:ValueObject模式是将远程调用的传递数据封装在一个串行化的对象中进行传输,而业务代理模式则是将一组由远程方法调用构成的业务流程,封装在一个位于展示层的代理类中。

 

          7.2、为什么需要业务代理模式的案例说明:比如用户需要修改一个订单,订单的修改操作可细分为3个子操作,其调用链路为RMI客户端(展示层)调用RMI服务端(业务逻辑层),再调用持久层。

1)校验用户

2)获取旧的订单信息

3)更新订单

以上结构存在两个问题:

1)当展示层存在大量的并发线程时,这些线程都会直接进行远程方法调用,进而会加重网络负担。

2)由于缺乏对订单修改操作流程的有效封装,如果将来修改流程发生变化,那么展示层组件需要修改。

 

         7.3:业务代理模式是如何提高系统性能的?

1)业务代理模式将一些业务流程封装在前台系统,为系统性能优化提供了基础平台。在业务代理中,不仅可以复用业务流程,还可以视情况为展示层组件提供缓存等功能,从而减少远程方法的调用次数,降低系统压力。

2)见P41业务代理模式架构图。

3)通过业务代理对象,可以更容易地在多个线程或者客户端请求之间共享数据,从而有效地利用缓存,减少远程调用次数,提供系统性能。

 

 

三、如何进行简单的压力测试?  -  实习生。

  大量的for循环、打印时间,显示gc等。

 

四、常用设计优化的组件和相关思想方法

 1、缓冲:缓冲可以协调上层组件和下层组件的性能差。当上层组件性能优于下层组件时,可以有效减少上层组件对下层组件的等待时间。

 

       1.1:缓冲区:缓冲区是一块特定的内存区域,开辟缓冲区的目的是通过缓解应用程序上下层之间的性能差异,提供系统的性能。

 

       1.2:典型应用:缓冲的一个典型应用就是漏斗。上层系统如茶壶,下层系统如水瓶,先需要将茶壶中的水导入水瓶中,这就有如将内存中的数据写入硬盘中一样。茶壶的出水速度可以很快,但是水瓶的瓶口很细,因此形成性能瓶颈。

 

        1.3:缓冲区如何提升系统性能的?

1)如上所说:缓冲可以协调上层组件和下层组件的性能差。当上层组件性能优于下层组件时,可以有效减少上层组件对下层组件的等待时间:如在一个复杂人多的大茶馆的人中倒茶时,如果瓶口都很细,如果使用漏斗,则可以避免茶壶的等待时间,而可以直接去下一个地方倒茶。

 

2)除性能上的优化外,缓冲区可以作为上层组件和下层组件的一种通信工具,从而将生层组件和下层组件进行解耦,优化设计结构,生产者消费者模式中,连接生产者和消费者的缓冲区正是起到这个作用。

 

        1.4:缓冲区的应用:

1)改善IO的性能。

2)缓解任何一种上下层组件存在性能差异的场合。

3)提升动画显示结果。

4)除性能上的优化外,缓冲区可以作为上层组件和下层组件的一种通信工具,从而将生层组件和下层组件进行解耦,优化设计结构,生产者消费者模式中,连接生产者和消费者的缓冲区正是起到这个作用。

 

2、缓存:缓存也是一块为提升系统性能而开辟的内存空间,其主要作用是暂存数据处理结果,并提供下次访问使用。

 

        2.1、缓存的应用场合:

1)目前流行的几种浏览器都会在本地缓存远程的页面,从而减少远程HTTP访问次数,加快网页的加载速度。

2)缓存可以保存一些来之不易的数据或者计算结果,当需要再次使用这些数据时,可以从缓存中低成本地获取,而不需要再占用宝贵的系统资源。

 

        2.2、HashMap作为缓存的简单实现的缺陷:

     最为简单的缓存可以直接使用HashMap实现。当然,这样做会遇到很多问题,比如何时应该清理无效的数据,如何防止缓存数据过多而导致内存溢出等。一个稍好的方案是直接使用weakhashmap,它使用弱引用来维护一张hash表,从而避免了潜在的内存溢出问题,但是作为专业的缓存,它的功能也略有不足。

 

        2.3、常见的Java缓存框架:

Hibernate的EHCache,Jboss的JBossCache,OpenSymphony的OSCache。

 

         2.4、基于动态代理实现的缓存方案的好处:

基于动态代理的缓存方案的最大好处是,在业务层无需关注对缓存的操作,缓存操作代码被完全独立并隔离,并且对一个新的函数方法加入缓存不会影响原有的方法实现,是一种非常灵活的软件结构。即使用动态代理无需修改一个逻辑方法的代码,就可以为他加上缓存的功能,提高其性能。

 

3、对象复用 - 池:对象池化,是目前非常常用的一种系统优化技术,它的核心思想是,如果一个类被频繁请求使用,那么不必每次都生成一个实例,可以将这个类的一些实例保存在一个“池”中,待需要使用的时候直接从池中获取。这个“池”就称为对象池。在实线的细节上,对象池可能是一个数组,一个链表或者是任何集合类。

 

      3.1、对象池的应用:

1)非常广泛,如线程池和数据库连接池。目前较为广泛的数据库连接池组件有C3P0和Proxool。

2)应用场景【什么对象适合用池化技术】:除了线程池和数据库连接池,对于普通的Java对象,在必要的时候,也可以进行池化管理,对于那些经常使用,并且创建很费时的大型对象来说,使用对象池维护,不仅可以节省获得对象实例的成本,还可以减轻GC频繁回收这些对象产生的系统压力。但对于生成对象开销很小的对象进行池化,反而可能得不偿失,维护对象池的成本可能会大于对象池带来的好处。

        在JDK中,new操作的效率是相当高的,不需要担心频繁的new操作对系统有性能影响。但是new操作时所调用的类构造函数可能是非常费时的,对于这些对象,可以考虑池化。即只有对重量级对象使用对象池技术才能提高系统性能,对轻量级的对象使用对象池,可能反而会降低系统性能。

 

        3.2: 对象池的实现:

1)Semaphore信号量中,使用了信号量同步机制来实现简单的对象池。

2)在Apache中,可以使用Jakarata Commons Pool对象池组件,有3个内置的对象池组件:StackObjectPool,GenericObjectPool,SoftReferenceObjectPool。

 

4、并行替代串行:

1)Thread,Runnable.

2)java.util.concurrent包

 

5、使用负载均衡:

      5.1、负载均衡的典型实现:

1)一个典型的实现便是Tomcat集群,配置Tomcat集群实现负载均衡,可以通过Apache服务器实现。即使用Apache服务器作为负载均衡分配器,将请求转向各个Tomcat服务器,从而实现负载均衡。

 

      5.2:Tomcat集群的两种Session共享模式:

1)黏性Session模式:所有Session信息被平均分配到各个Tomcat节点上,以实现负载均衡,但是一旦一个节点宕机,他所维护的Session信息将丢失,不具备高可用性,且同一用户只能与一台Tomcat交互,因为其他Tomcat节点上不保存这个用户信息。

2)复制Session模式:将使得所有Session在所有Tomcat节点上保持一致,当一个节点上的Session信息被修改,这个Session会被广播到其它Tomcat节点上,以保持Session同步。这样做的坏处是很容易引起网络繁忙,影响系统效率。

 

      5.3:Terracotta:

1)在Java开源软件中,有一款跨JVM虚拟机,专门用于分布式缓存的框架- Terracotta,使用Terracotta也可以实现Tomcat的Session共享。同时Terracotta也是一个成熟的高可用性系统解决方案。

2)由于Terracotta进行内存共享时,并不会进行全复制,而仅仅传输变化的部分,网络负载也相对较低。

3)Terracotta是一款企业级的、开源的、JVM层的集群解决方案,它可以实现诸如分布式对象共享、分布式缓存、分布式Session等功能。可以作为负载均衡,高可用性的解决方案。

 

6、时间换空间:时间换空间通常用于嵌入式设备、或者内存、硬盘空间不足的情况,通过使用牺牲CPU的方式,获得原本需要更多内存或者硬盘空间才能完成的工作。

 

      6.1、典型的例子:两个变量的值进行交换,可以使用a=a+b,b=a-b,a=a-b

 

      6.2、总结:

        性能的优化在于掌握各部分组件性能的平衡点,如果系统CPU资源有空闲,但是内存使用紧张,便可以考虑使用时间换空间的策略,达到整体性能的改良。反之,CPU资源紧张,内存资源有空闲,则可以使用空间换时间的策略,提升整体性能。

 

7、空间换时间:与时间换空间相反,空间换时间则是尝试使用更多的内存或者磁盘空间换取CPU资源或者网络资源,通过增加系统的内存消耗,来加快程序的运行速度。

 

     7.1:典型应用:

     1)这种方法的典型应用就是缓存。

     2)空间换时间是一种软件设计思路,除了缓存外,在一些算法中,也可以使用这样的技术,比如典型的空间换时间排序方法,不计空间成本,以数组的索引下标来表示数据大小,可以避免数字间的相互比较,这是一种典型的空间换时间的思路。

 

五、Java程序优化

 

1、String优化处理

      1.1、String优化处理的重要性:

        字符串是软件开发中最为重要的对象之一,通常,字符串对象或者其等价对象(如char数组:String对象可以看成是char数组的延伸和进一步封装),在内存中总是占据了最大的空间块。因此如何高效地处理字符串,必将是提高系统整体性能的关键。

 

      1.2、String对象的3个基本特点:

      1.2.1、不变性:

不变性是指String对象一旦生成、则不能再对它进行改变。String的这个特性可以泛化成不变模式,即一个对象的状态在对象被创建之后就不再发生变化。不变模式的主要作用在于当一个对象需要被多线程共享、并且需要频繁访问时,可以省略同步和锁等待的时间,从而大幅提高系统性能。不变模式是一个可以提高多线程程序的性能、降低多线程程序复杂度的设计模式。

 

      1.2.2、针对常量池的优化:当两个String对象拥有相同的值时,它们只引用常量池中的一个拷贝。当同一个字符串反复出现时,这个技术可以大幅度节省内存空间。

 

1)见P67 Sring内存分配方式。

2)String的intern()方法返回了String对象在常量池中的引用。

 

        1.2.3、类的final定义

作为final的String对象,在系统中不能有任何子类,这是对系统安全性的保护。

 

        1.2.4、String对象的内部结构:

       char数组 + offset偏移 + count长度

 

        1.2.5、subString()方法的内存泄露:

     subString()方法之所以引起了内存泄漏是因为调用了String(int offset, int count, char value[])构造函数,此构造函数采用了空间换时间的手段。但它是一个包内的私有的构造函数,也就是说,应用程序无法使用它。因为在实际使用时,不用担心他所带来的麻烦,但是我们仍然需要关注java.lang包内的对象对它的调用是否会引起内存泄漏。如Integer,Long等对象,String中的concat,replace,toLowerCase等方法。

     从FullGC轨迹可以看到,程序所占用的内存不断扩大,直到溢出。虽然Full GC不停地工作,每次Full GC效果并不显著,每次所释放的内存微乎其微。

 

        1.2.6、字符串分割的的几种方式对比:

使用indexOf()方法实现的分割方式优于StringTokenizer,StringTokenizer优于spit()方法。

 

       1.2.7、判断某个字符串是否以某个字符串开始和结尾,或者是否含有某个字符串时?

使用chartAt()的性能比starsWith()和endsWith()更好。

 

       1.2.8、String常量的累加操作:

        对于静态字符串的的连接操作,Java在编译时会进行彻底的优化、将多个连接操作的字符串在编译时合成一个单独的长字符串。

 

        1.2.9、String变量的累加操作:

      对于变量字符串的累加,Java也做了相应的优化操作,内部使用了StringBuilder对象来实现字符串的累加。

 

        1.2.10、构建超级大的String对象:

         String的加法操作虽然会被优化,但编译器是不够聪明的,因为对于String操作,类似于 “+” 和“+=”的运算符应该尽量少用。其次,String的concat()方法效率远远高于“+”和“+=”运算符,但是又远远低于StringBuilder类。

 

1.3、核心数据结构

1、List接口

     1.1、增加元素到列表的尾端: 

      ArrayList在尾部增加元素的性能比LinkedList的性能会更好。

   

     1.2、增加元素到列表的任意位置:

     LinkedList的性能比ArrayList的性能更好。因为每次插入操作,都会进行一次数组复制,而这个操作在增加元素到List尾端的时候是不存在的,大量的数组重组操作会导致系统性能低下。

   

     1.3、删除任意位置元素:

     ArrayList从尾部删除元素时效率很高,从头部删除元素时相当费时,而LinkedList从头尾删除元素时效率相差无几,但是从List总监删除元素时LinkedList性能非常糟糕。 

 

    1.4、遍历列表:

    对ArrayList这些基于数组的实现来说,随机访问的速度是很快的,在遍历这些List对象时,可以优先考虑随机访问。但对于LinkedList等基于链表的实现,随机访问性能是非常差的,应避免使用。

 

 2、Map接口

    2.1 Hashtable和Hashmap的区别

    1)Hashtable的大部分方法做了同步,而Hashmap没有,即Hashmap不是线程安全的。

    2)Hashtable不允许key或者value为null,而Hashmap可以使用null值。

    3)内部算法上,两者对key的hash算法和hash值到内存索引的映射算法不同。

 

   2.2 HashMap的实现原理:

      1)简单地说,HashMap就是将key做hash算法,然后将hash值映射到内存地址,直接取得key所对应的数据。在HashMap中,底层数据结构使用的是数组,所谓的内存地址即数组的下标索引。HashMap的高性能需要保证如下几点:

      1.1:hash算法必须是高效的。

      1.2:hash值到内存地址(数组索引)的算法是快速的。

      1.3:根据内存地址(数组索引)可以直接取得对应的值。

 

    2)Hash冲突

     虽然HashMap底层是使用数组来实现,但是数组内的元素并不是简单的值,而是一个Entry类的对象,每个Entry对象中有key,value,next和hash值。

     在进行put()操作有冲突时,新的Entry依然会被安放在对应的索引下标内,并替换原有的值。同时,为了保证原来的旧值不会丢,会将新的Entry的next指向旧值。这便实现了在一个数组索引空间内存放多个值项。因此HashMap实际上是一个链表数组。P88

 

  3)容量参数

     负载因子 = 元素个数 / 内部数组总大小

     在实际使用中,负载因子也可以设置为大于1的数,但如果这样做,HashMap将必然产生大量的冲突,因为这无疑是在尝试往只有10个口袋的包里放15件物品,必然有几只口袋要装有大于一个物件。因为,通常不会这么使用。

 

   2.3、LinkedHashMap

     1) LinkedHashMap继承自HashMap,因此,它具备了HashMap的优良特性-高性能,在HashMap的基础上,LinkedHashMap又在内部增加了一个链表,用以存放元素的顺序。因此,LinkedHashMap可以简单地理解为一个维护了元素次序表的HashMap。

     

     2) LinkedHashMap提供了两种类型的顺序:一是元素插入时的顺序,一是最近访问的顺序。可以通过构造函数的accessOrder来指定。

 

    3)LinkedHashMap中的ConcurrentModificationException异常:

         ConcurrentModificationException异常一般会在集合迭代过程中被修改时抛出,不仅仅是LinkedHashMap,所有的集合都不允许在迭代器模式中修改集合的结构。一般认为,put方法,remove方法会修改集合的结构,因此不能在迭代器中使用。但是在LinkedHashMap中,get()方法也会抛出同样的异常,这是因为如果当前的LinkedHashMap是工作在按照元素访问顺序排序的模式中, get()方法会修改LinkedHashMap中的的链表结构,以便将最近访问的元素放置到链表的末尾,因此这个操作便引起了这个错误。

 

    2.4:TreeMap

 

     1)TreeMap是基于元素的固有顺序(由Comparator或者Comparable指定)

     2)TreeMap的内部实现是基于红黑树的,红黑树是一种平衡查找树,它的统计性能要优于平衡二叉树,它具有良好的最坏情况运行时间,可以在O(logn)时间内做查找、插入和删除,n表示树中元素的数目。

     3)TreeMap中有几个筛选接口:成绩在两者之间的、成绩低于某个人的,成绩大于某个人的。

     4)如果确定需要将排序功能加入HashMap,笔者强烈建议使用TreeMap而不是在应用程序中实现排序。TreeMap的性能是相当不错的,而自行实现的排序算法,既增加了开发成本,又可能成为一个性能瓶颈。

 

 

3、Set接口

    1、HashSet是对HashMap封装,其内部维护一个HashMap对象。因为有关HashSet一切性能特性和实现细节与HashMap完全相同。

    2、linkedHashSet对应LinkedHashMap,TreeSet对应TreeMap。

 

 

 

 

4、容量参数相关

       Buffer的默认容量参数是8K,StringBuffer和StringBuilder默认是16个字节,ArrayList默认构造的容量为10,因为ArrayList的底层是由一个Object[]数组构成的,而这个Object[]数组,默认的长度是10,HashMap初始容量为16。当初始空间不够的时候,HashMap,ArrayList,StringBuffer,StringBuilder等都存在内存复制,带来性能问题。

 

5、减少方法调用

      方法调用是要消耗系统堆栈的,虽然面向对象的设计模式和模块化的软件设计方法鼓励程序员使用若干个小方法替代一个大方法。但这都是以牺牲部分性能为代价的,可喜的是,现代编程语言都在这方面做了足够的优化,来支持大量的方法嵌套调用。

 

6、RandomAccess接口的作用

       RandomAccess接口是一个标志接口,本身并没有提供任何方法,任何实现RandomAccess接口的对象都可以认为是支持快速随机访问的对象。此接口的主要目的是表示那些可支持快速随机访问的List实现。即通过RandomAccess可以知道List是否支持快速随机访问。

 

7、使用NIO提升性能 

   7.1:NIO 是New IO的简称,与传统的流式的IO不同,NIO是基于块(Block)的,它以块为基本单位处理数据。

 

   7.2:NIO的特性:

   1)为所有的原始类型提供Buffer缓存支持。

   2)使用Java.nio.cahrset.Charset作为字符集编码解码解决方案。

   3)增加通道Channel对象,作为新的原始IO抽象。

   4)支持锁和内存映射文件的文件访问接口。

   5)提供了基于Selector的异步网络IO。

 

   7.3:最重要的两个组件:缓冲Buffer和通道Channel

    缓冲是一块连续的内存块、是NIO中读写数据的中转地。通道表示缓冲数据的源头或者目的地,它用于向缓冲读取或者写入数据,是访问缓冲的接口。Channel是一个双向通道,既可读,也可写。有点类似Stream,但Stream是单向的。应用程序中不能直接对Channel进行读写操作,而必须通过Buffer来进行。比如在读一个Channel的时候,需要先将数据读入到相对应的Buffer,然后在Buffer中进行读取。

 

   7.4:Buffer的基本原理:

   Buffer中的3个重要参数:位置position,容量capacity和上限limit(当前的有效容量),其中position始终指向下一个即将输入的位置,limit代表可读取的总容量(和上次写入的数据量相等)

 

   7.5: Buffer的相关操作:

       1、Buffer的创建:使用静态方法allocate()从堆中分配缓冲区或者从一个既有数组中创建缓冲区。

       2、重置和清空缓冲区:

          2.1:rewind():将position置0,并清除标志mark,为提取Buffer的有效数据做准备。

          2.2:clear():将pisition置0,同时将limit设置为capacity的大小,并清除标志mark,由于清空了limit,因此便无法得知Buffer内哪些数据是真实是有效的,这个方法主要是为重新写Buffer做准备。

          2.3:flip():先将limit设置到position的位置,然后将position置零,并清除标志位mark,它通常在读写转换时使用。

这3个操作都重置了Buffer对象,这里所谓的重置,只是指重置了Buffer的各项标志,并不真正清空Buffer的内容。

       3、读/写缓冲区

         get(),get(byte[] dst),get(int index),put(byte b),put(int index, byte b),put(byte[] src)

 

       4、标志缓冲区:

      如书签一样随时记录当前位置。然后在任意时刻,回到这个位置,从而加快或简化数据处理流程。

 

       5、复制缓冲区:

      复制缓冲区是指以原缓冲区为基础,生成一个完全一样的新缓冲区。两个缓冲区共享相同的内存数据,并且任意一方的数据改动都是相互可见的,但两者又独立维护了各自的position,limit和mark。这就大大增加了程序的灵活性,为多方同时处理数据提供了可能。

 

      6、缓冲区分片:

      缓冲去分片使用slice()方法实现,它将在现有的缓冲区中,创建新的子缓冲区,子缓冲区和父缓冲区共享数据。缓冲区切片可以将一个大缓冲区进行分割处理、得到的子缓冲区都觉有完整的缓冲区模型结构。因此,这个操作有利于系统的模块化。

 

      7、只读缓冲区:

     1)可以使用缓冲区对象的asReadOnlyBuffer()方法得到一个域当前缓冲区一致的,并且共享内存数据的只读缓冲区。

    2)只读缓冲区对于数据的安全非常有用,也并不是原始缓冲区在某一时刻的快照,而是和原始缓冲区共享内存数据。

 

      8、文件映射到内存:

   1)NIO提供了一种将文件映射到内存的方法进行IO操作,它可以比常规的基于流的IO快很多。

   2)这个操作主要由FileChannel.map()方法实现。

 

      9、处理结构化数据:

       NIO中提供了处理结构化数据的方法,称之为散射(Scattering)和聚集(Gathering),散射是指将数据读入一组Buffer中,而不仅仅是一个,聚集与之相反,指将数据写入一组Buffer中。

 

     10、MappedByteBuffer性能评估:

       1)使用MappedByeBuffer(8、文件映射到内存)可以大大提高读取和写入文件的速度。

       2)虽然使用ByteBuffer读文件比Stream方式快了很多,但这不足以表明Stream方式与ByteBuffer有如此之大的差距。这其中,由于ByteBuffer是将文件一次性读入内存后再做后续处理,而Stream方式是边读文件边处理数据(虽然也使用了缓冲组件BufferedInputStream),这也是导致两者性能差异的原因之一。

      但即便如此,也不能掩盖使用NIO方法的优势,鉴于IO在很多场合都极可能成为系统瓶颈,因此使用NIO代替传统IO操作,对系统整体性能的优化,应该是有立竿见影的效果的。

 

      11、直接内存访问:

        1)NIO的Buffer还提供了一个可以直接访问系统物理内存的类 - DirectBuffer,DirectBuffer继承自ByteBuffer,但和普通的ByteBuffer不同。普通的ByteBuffer仍然在JVM堆上分配内存,其最大内存,受到最大堆的限制,而DirectBuffer直接分配在物理内存中,并不占用堆空间。

       2)   DirectBuffer的GC信息非常简单,因为GC只记录了堆空间的内存回收,由于DirectBuffer占用的内存空间并不在堆中,因此对堆空间的操作就相对较少(注意,DirectBuffer对象本身还是在堆上分配的)

    

 8、引用类型:

     在Java中提供了4个级别的引用:强引用、软引用、弱引用、虚引用。在这4个引用级别中,只有强引用FinalReference类是包内可见,其它3种类型均为public,可以在应用程序中直接使用。

     1、强引用特点:

     1)强引用可以直接访问目标对象。

     2)强引用所指向的对象在任何时候都不会被系统回收。JVM宁愿抛出OOM异常,也不回收强引用所指向的对象。

    3)强引用可能导致内存泄露。

   

    2、软引用:

     1)软引用是除了强引用外,最强的引用类型。

     2)一个持有软引用的对象,不会被JVM很快回收,JVM会根据当前堆的使用情况来判断何时回收。当堆使用率临近阈值时,才会去回收软引用的对象。

     3)软引用可以使用一个引用队列,当对象被回收时,就会被加入到这个队列中。

   

     3、弱引用

   1)弱引用是一种比软引用较弱的引用类型。

   2)熊GC时,只要发现弱引用,不管系统堆空间是否足够,都会将对象进行回收。但是由于垃圾回收器的线程通常优先级很低,因此,并不一定能很快地发现持有弱引用的对象。在这种情况下,弱引用对象可以存在较长的时间。

  3)一旦一个弱引用对象被垃圾回收期回收,便会加入到一个注册引用队列中。

 

       软引用、弱引用都非常适合来保存那些可有可无的缓存数据。如果这么做,当系统内存不足时,这些缓存数据会被回收,不会导致内存溢出,而当内存资源充足时,这些缓存数据又可以存在相当长的时间,从而起到加速系统的作用

 

      4、虚引用

  虚引用是所有引用类型中最弱的一个,一个持有虚引用的对象,和没有引用几乎是一样的,随时都可能被垃圾回收器回收。当试图通过虚引用的get()方法取得强引用时,总是会失败,因为方法都是返回null。    

     

 9、WeakHashMap类及其实现

    1)WeakHashMap是弱引用的一种典型引用,它可以作为简单的缓存表解决方案。

    2)因为WeakHashMap会在系统内存范围内,保存所有表项,而一旦内存不够,在GC时,没有被引用的表项又会很快被清除掉,从而避免系统内存溢出。

    3)要避免WeakHashMap退化为HashMap:主要是要避免WeakHashMap的key在系统中被强引用所引用,持有强引用。

 

10、有助于改善性能的技巧

 

      1、慎用异常:try catch 如果在大量的循环体内的耗时更大。

      2、使用局部变量:调用方法是传递的参数以及在调用中创建的临时变量都保存在栈中,速度较快。其它变量,如静态变量、实例变量等,都在堆中创建,速度较慢。

     3、位预算代替乘除法。位运算是最为高效的。

     4、替换Switch。

     5、一维数组代替二维数组

     6、提取表达式:如循环中提取表达式在循环体外。

     7、展开循环 : 一个循环体完成原来3个循环的工作。

     8、布尔运算代替位运算:虽然位运算的速度远远高于算术运算,但是在条件判断时,Java会对布尔运算做相当充分的优化。

    9、使用arrayCopy():native函数。

    10、使用Buffer进行IO操作。

    11、使用clone()代替new():clone做的是浅拷贝,不会拷贝值,而new操作中可能构造器有时会比较耗时。

   12、静态方法代替实例方法:在Java中,由于实例方法需要维护一张类似虚函数的表结构,以实现对多态的支持。对于一些工具类,应该使用static方法实现,这样不仅可以加快函数调用的速度,同时,调用static方法也不行呀哟生成类的实例,比调用实例实例方法更为方便,易用。

 

 六、集群相关:

 

    1、集群分类:缓存集群,数据库,Nosql,大数据处理集群

    

    2、集群管理中的领导者选举算法: Paxos算法与谦让算法。

 

 七、架构相关:

    1、架构经验,架构独到之处及对性能的提升

    2、应用架构的演进,各个时代的问题和主要要解决的问题

    3、作为一个架构师,如果你来设计支付宝的架构,你觉得它会怎样发展?

    4、如果有过支付的经验,可以从账务数据库和交易数据库数据容量性能瓶颈发生后,怎么做?数据垂直拆分后,最大的问题是啥?数据一致性怎么通过二阶段去保证,二阶段保证有哪些强制的要求。消息型的二阶段提交的场景,不是实时一致性,而是最终的一致性。反到大促。。。

    5、怎样形成无限扩容的数据库方式。

 

 

 八、ZK的缺点,怎么解决?

 

 九、缓存相关:

1、小型网站或应用的缓存实现,画图,大型分布式网站的缓存实现,画图。

2、基于大型分布式网站的缓存实现,怎么得出分布式session系统架构。

 

 十、 一致性哈希算法的原理和实现:

 

十一、数据库相关

1、悲观锁 乐观锁

 

十二、Java本身相关:

1、Java8的新特性:

2、Java源生实现一个RPC框架:需要哪些类?

 

X、Java中提及并行程序的开发及优化、一般都会涉及到什么知识?

1、并行程序的设计模式

1.1:Future模式

1.2:Master-Worker模式

1.3:Guarded Suspension模式

1.4:不变模式

1.5:生产者-消费者模式

 

2、JDK多任务执行框架

2.1:无限制线程的缺陷

2.2:怎样实现一个简单的线程池?

2.3:Executor框架

2.4:如何自定义线程池?

2.5:怎样优化线程池大小?

2.6:怎样扩展ThreadPoolExecutor?

 

3、JDK的并发数据结构有哪些?

3.1:并发List

3.2:并发Set

3.3:并发Map

3.4:并发Queue

3.5:并发Deque

 

4、并发控制方法有哪些?

4.1:Java的内存模型与volatile

4.2:同步关键字synchronized.

4.3:   ReentrantLock重入锁

4.4:   ReadWriteLock读写锁

4.5:   Conditon对象

4.6:   Seamphore信号量

4.7:   ThreadLocal线程局部变量

 

5、关于“锁”的性能以及优化

5.1:线程的开销

5.2:如何避免死锁

5.3:减小锁的持有时间

5.4:减少锁粒度

5.5:读写分离锁替换独占锁

5.6:   锁分离

5.7:重入锁(ReentrantLick)和内部锁(Synchrionized)

5.8:锁粗化(Lock Coarsening)

5.9:自旋锁(Spinning Lock)

5.10:锁消除(Lock Elimination)

5.11:锁偏向(Biased Lock)

 

技术风险评估关于锁的几个问题:

A.必须锁住以后再读取最新数据,经常有些错误是读取数据后再锁,锁住后没有重新读取数据,仍然基于脏数据做判断

B.对同一数据的锁,要保证读取和更新时使用同一把锁

C.在设计上要尽量减少锁的数量,最好能找到一个根对象,通过根对象锁保护一组数据,同时考虑锁的记录影响范围

<!--[if gte mso 9]><xml> <o:DocumentProperties> <o:Revision>0</o:Revision> <o:TotalTime>0</o:TotalTime> <o:Pages>1</o:Pages> <o:Words>31</o:Words> <o:Characters>181</o:Characters> <o:Company>Ant Financial</o:Company> <o:Lines>1</o:Lines> <o:Paragraphs>1</o:Paragraphs> <o:CharactersWithSpaces>211</o:CharactersWithSpaces> <o:Version>14.0</o:Version> </o:DocumentProperties> <o:OfficeDocumentSettings> <o:AllowPNG/> </o:OfficeDocumentSettings> </xml><![endif]--> <!--[if gte mso 9]><xml> <w:WordDocument> <w:View>Normal</w:View> <w:Zoom>0</w:Zoom> <w:TrackMoves/> <w:TrackFormatting/> <w:PunctuationKerning/> <w:DrawingGridVerticalSpacing>10 pt</w:DrawingGridVerticalSpacing> <w:DisplayHorizontalDrawingGridEvery>0</w:DisplayHorizontalDrawingGridEvery> <w:DisplayVerticalDrawingGridEvery>2</w:DisplayVerticalDrawingGridEvery> <w:ValidateAgainstSchemas/> <w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid> <w:IgnoreMixedContent>false</w:IgnoreMixedContent> <w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText> <w:DoNotPromoteQF/> <w:LidThemeOther>EN-US</w:LidThemeOther> <w:LidThemeAsian>ZH-CN</w:LidThemeAsian> <w:LidThemeComplexScript>X-NONE</w:LidThemeComplexScript> <w:Compatibility> <w:SpaceForUL/> <w:BalanceSingleByteDoubleByteWidth/> <w:DoNotLeaveBackslashAlone/> <w:ULTrailSpace/> <w:DoNotExpandShiftReturn/> <w:AdjustLineHeightInTable/> <w:BreakWrappedTables/> <w:SnapToGridInCell/> <w:WrapTextWithPunct/> <w:UseAsianBreakRules/> <w:DontGrowAutofit/> <w:SplitPgBreakAndParaMark/> <w:EnableOpenTypeKerning/> <w:DontFlipMirrorIndents/> <w:OverrideTableStyleHps/> <w:UseFELayout/> </w:Compatibility> <w:NoLineBreaksAfter Lang="JA">$([{£¥·‘“〈《「『【〔〖〝﹙﹛﹝$(.[{£¥</w:NoLineBreaksAfter> <w:NoLineBreaksBefore Lang="JA">!%),.:;&gt;?]}¢¨°·ˇˉ―‖’”…‰′″›℃∶、。〃〉》」』】〕〗〞︶︺︾﹀﹄﹚﹜﹞!"%'),.:;?]`|}~¢</w:NoLineBreaksBefore> <m:mathPr> <m:mathFont m:val="Cambria Math"/> <m:brkBin m:val="before"/> <m:brkBinSub m:val="&#45;-"/> <m:smallFrac m:val="off"/> <m:dispDef/> <m:lMargin m:val="0"/> <m:rMargin m:val="0"/> <m:defJc m:val="centerGroup"/> <m:wrapIndent m:val="1440"/> <m:intLim m:val="subSup"/> <m:naryLim m:val="undOvr"/> </m:mathPr></w:WordDocument> </xml><![endif]--><!--[if gte mso 9]><xml> <w:LatentStyles DefLockedState="false" DefUnhideWhenUsed="true" DefSemiHidden="true" DefQFormat="false" DefPriority="99" LatentStyleCount="276"> <w:LsdException Locked="false" Priority="0" SemiHidden="false" UnhideWhenUsed="false" QFormat="true" Name="Normal"/> <w:LsdException Locked="false" Priority="9" SemiHidden="false" UnhideWhenUsed="false" QFormat="true" Name="heading 1"/> <w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 2"/> <w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 3"/> <w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 4"/> <w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 5"/> <w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 6"/> <w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 7"/> <w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 8"/> <w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 9"/> <w:LsdException Locked="false" Priority="39" Name="toc 1"/> <w:LsdException Locked="false" Priority="39" Name="toc 2"/> <w:LsdException Locked="false" Priority="39" Name="toc 3"/> <w:LsdException Locked="false" Priority="39" Name="toc 4"/> <w:LsdException Locked="false" Priority="39" Name="toc 5"/> <w:LsdException Locked="false" Priority="39" Name="toc 6"/> <w:LsdException Locked="false" Priority="39" Name="toc 7"/> <w:LsdException Locked="false" Priority="39" Name="toc 8"/> <w:LsdException Locked="false" Priority="39" Name="toc 9"/> <w:LsdException Locked="false" Priority="35" QFormat="true" Name="caption"/> <w:LsdException Locked="false" Priority="10" SemiHidden="false" UnhideWhenUsed="false" QFormat="true" Name="Title"/> <w:LsdException Locked="false" Priority="1" Name="Default Paragraph Font"/> <w:LsdException Locked="false" Priority="11" SemiHidden="false" UnhideWhenUsed="false" QFormat="true" Name="Subtitle"/> <w:LsdException Locked="false" Priority="22" SemiHidden="false" UnhideWhenUsed="false" QFormat="true" Name="Strong"/> <w:LsdException Locked="false" Priority="20" SemiHidden="false" UnhideWhenUsed="false" QFormat="true" Name="Emphasis"/> <w:LsdException Locked="false" Priority="59" SemiHidden="false" UnhideWhenUsed="false" Name="Table Grid"/> <w:LsdException Locked="false" UnhideWhenUsed="false" Name="Placeholder Text"/> <w:LsdException Locked="false" Priority="1" SemiHidden="false" UnhideWhenUsed="false" QFormat="true" Name="No Spacing"/> <w:LsdException Locked="false" Priority="60" SemiHidden="false" UnhideWhenUsed="false" Name="Light Shading"/> <w:LsdException Locked="false" Priority="61" SemiHidden="false" UnhideWhenUsed="false" Name="Light List"/> <w:LsdException Locked="false" Priority="62" SemiHidden="false" UnhideWhenUsed="false" Name="Light Grid"/> <w:LsdException Locked="false" Priority="63" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Shading 1"/> <w:LsdException Locked="false" Priority="64" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Shading 2"/> <w:LsdException Locked="false" Priority="65" SemiHidden="false" UnhideWhenUsed="false" Name="Medium List 1"/> <w:LsdException Locked="false" Priority="66" SemiHidden="false" UnhideWhenUsed="false" Name="Medium List 2"/> <w:LsdException Locked="false" Priority="67" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Grid 1"/> <w:LsdException Locked="false" Priority="68" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Grid 2"/> <w:LsdException Locked="false" Priority="69" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Grid 3"/> <w:LsdException Locked="false" Priority="70" SemiHidden="false" UnhideWhenUsed="false" Name="Dark List"/> <w:LsdException Locked="false" Priority="71" SemiHidden="false" UnhideWhenUsed="false" Name="Colorful Shading"/> <w:LsdException Locked="false" Priority="72" SemiHidden="false" UnhideWhenUsed="false" Name="Colorful List"/> <w:LsdException Locked="false" Priority="73" SemiHidden="false" UnhideWhenUsed="false" Name="Colorful Grid"/> <w:LsdException Locked="false" Priority="60" SemiHidden="false" UnhideWhenUsed="false" Name="Light Shading Accent 1"/> <w:LsdException Locked="false" Priority="61" SemiHidden="false" UnhideWhenUsed="false" Name="Light List Accent 1"/> <w:LsdException Locked="false" Priority="62" SemiHidden="false" UnhideWhenUsed="false" Name="Light Grid Accent 1"/> <w:LsdException Locked="false" Priority="63" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Shading 1 Accent 1"/> <w:LsdException Locked="false" Priority="64" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Shading 2 Accent 1"/> <w:LsdException Locked="false" Priority="65" SemiHidden="false" UnhideWhenUsed="false" Name="Medium List 1 Accent 1"/> <w:LsdException Locked="false" UnhideWhenUsed="false" Name="Revision"/> <w:LsdException Locked="false" Priority="34" SemiHidden="false" UnhideWhenUsed="false" QFormat="true" Name="List Paragraph"/> <w:LsdException Locked="false" Priority="29" SemiHidden="false" UnhideWhenUsed="false" QFormat="true" Name="Quote"/> <w:LsdException Locked="false" Priority="30" SemiHidden="false" UnhideWhenUsed="false" QFormat="true" Name="Intense Quote"/> <w:LsdException Locked="false" Priority="66" SemiHidden="false" UnhideWhenUsed="false" Name="Medium List 2 Accent 1"/> <w:LsdException Locked="false" Priority="67" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Grid 1 Accent 1"/> <w:LsdException Locked="false" Priority="68" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Grid 2 Accent 1"/> <w:LsdException Locked="false" Priority="69" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Grid 3 Accent 1"/> <w:LsdException Locked="false" Priority="70" SemiHidden="false" UnhideWhenUsed="false" Name="Dark List Accent 1"/> <w:LsdException Locked="false" Priority="71" SemiHidden="false" UnhideWhenUsed="false" Name="Colorful Shading Accent 1"/> <w:LsdException Locked="false" Priority="72" SemiHidden="false" UnhideWhenUsed="false" Name="Colorful List Accent 1"/> <w:LsdException Locked="false" Priority="73" SemiHidden="false" UnhideWhenUsed="false" Name="Colorful Grid Accent 1"/> <w:LsdException Locked="false" Priority="60" SemiHidden="false" UnhideWhenUsed="false" Name="Light Shading Accent 2"/> <w:LsdException Locked="false" Priority="61" SemiHidden="false" UnhideWhenUsed="false" Name="Light List Accent 2"/> <w:LsdException Locked="false" Priority="62" SemiHidden="false" UnhideWhenUsed="false" Name="Light Grid Accent 2"/> <w:LsdException Locked="false" Priority="63" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Shading 1 Accent 2"/> <w:LsdException Locked="false" Priority="64" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Shading 2 Accent 2"/> <w:LsdException Locked="false" Priority="65" SemiHidden="false" UnhideWhenUsed="false" Name="Medium List 1 Accent 2"/> <w:LsdException Locked="false" Priority="66" SemiHidden="false" UnhideWhenUsed="false" Name="Medium List 2 Accent 2"/> <w:LsdException Locked="false" Priority="67" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Grid 1 Accent 2"/> <w:LsdException Locked="false" Priority="68" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Grid 2 Accent 2"/> <w:LsdException Locked="false" Priority="69" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Grid 3 Accent 2"/> <w:LsdException Locked="false" Priority="70" SemiHidden="false" UnhideWhenUsed="false" Name="Dark List Accent 2"/> <w:LsdException Locked="false" Priority="71" SemiHidden="false" UnhideWhenUsed="false" Name="Colorful Shading Accent 2"/> <w:LsdException Locked="false" Priority="72" SemiHidden="false" UnhideWhenUsed="false" Name="Colorful List Accent 2"/> <w:LsdException Locked="false" Priority="73" SemiHidden="false" UnhideWhenUsed="false" Name="Colorful Grid Accent 2"/> <w:LsdException Locked="false" Priority="60" SemiHidden="false" UnhideWhenUsed="false" Name="Light Shading Accent 3"/> <w:LsdException Locked="false" Priority="61" SemiHidden="false" UnhideWhenUsed="false" Name="Light List Accent 3"/> <w:LsdException Locked="false" Priority="62" SemiHidden="false" UnhideWhenUsed="false" Name="Light Grid Accent 3"/> <w:LsdException Locked="false" Priority="63" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Shading 1 Accent 3"/> <w:LsdException Locked="false" Priority="64" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Shading 2 Accent 3"/> <w:LsdException Locked="false" Priority="65" SemiHidden="false" UnhideWhenUsed="false" Name="Medium List 1 Accent 3"/> <w:LsdException Locked="false" Priority="66" SemiHidden="false" UnhideWhenUsed="false" Name="Medium List 2 Accent 3"/> <w:LsdException Locked="false" Priority="67" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Grid 1 Accent 3"/> <w:LsdException Locked="false" Priority="68" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Grid 2 Accent 3"/> <w:LsdException Locked="false" Priority="69" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Grid 3 Accent 3"/> <w:LsdException Locked="false" Priority="70" SemiHidden="false" UnhideWhenUsed="false" Name="Dark List Accent 3"/> <w:LsdException Locked="false" Priority="71" SemiHidden="false" UnhideWhenUsed="false" Name="Colorful Shading Accent 3"/> <w:LsdException Locked="false" Priority="72" SemiHidden="false" UnhideWhenUsed="false" Name="Colorful List Accent 3"/> <w:LsdException Locked="false" Priority="73" SemiHidden="false" UnhideWhenUsed="false" Name="Colorful Grid Accent 3"/> <w:LsdException Locked="false" Priority="60" SemiHidden="false" UnhideWhenUsed="false" Name="Light Shading Accent 4"/> <w:LsdException Locked="false" Priority="61" SemiHidden="false" UnhideWhenUsed="false" Name="Light List Accent 4"/> <w:LsdException Locked="false" Priority="62" SemiHidden="false" UnhideWhenUsed="false" Name="Light Grid Accent 4"/> <w:LsdException Locked="false" Priority="63" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Shading 1 Accent 4"/> <w:LsdException Locked="false" Priority="64" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Shading 2 Accent 4"/> <w:LsdException Locked="false" Priority="65" SemiHidden="false" UnhideWhenUsed="false" Name="Medium List 1 Accent 4"/> <w:LsdException Locked="false" Priority="66" SemiHidden="false" UnhideWhenUsed="false" Name="Medium List 2 Accent 4"/> <w:LsdException Locked="false" Priority="67" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Grid 1 Accent 4"/> <w:LsdException Locked="false" Priority="68" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Grid 2 Accent 4"/> <w:LsdException Locked="false" Priority="69" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Grid 3 Accent 4"/> <w:LsdException Locked="false" Priority="70" SemiHidden="false" UnhideWhenUsed="false" Name="Dark List Accent 4"/> <w:LsdException Locked="false" Priority="71" SemiHidden="false" UnhideWhenUsed="false" Name="Colorful Shading Accent 4"/> <w:LsdException Locked="false" Priority="72" SemiHidden="false" UnhideWhenUsed="false" Name="Colorful List Accent 4"/> <w:LsdException Locked="false" Priority="73" SemiHidden="false" UnhideWhenUsed="false" Name="Colorful Grid Accent 4"/> <w:LsdException Locked="false" Priority="60" SemiHidden="false" UnhideWhenUsed="false" Name="Light Shading Accent 5"/> <w:LsdException Locked="false" Priority="61" SemiHidden="false" UnhideWhenUsed="false" Name="Light List Accent 5"/> <w:LsdException Locked="false" Priority="62" SemiHidden="false" UnhideWhenUsed="false" Name="Light Grid Accent 5"/> <w:LsdException Locked="false" Priority="63" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Shading 1 Accent 5"/> <w:LsdException Locked="false" Priority="64" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Shading 2 Accent 5"/> <w:LsdException Locked="false" Priority="65" SemiHidden="false" UnhideWhenUsed="false" Name="Medium List 1 Accent 5"/> <w:LsdException Locked="false" Priority="66" SemiHidden="false" UnhideWhenUsed="false" Name="Medium List 2 Accent 5"/> <w:LsdException Locked="false" Priority="67" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Grid 1 Accent 5"/> <w:LsdException Locked="false" Priority="68" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Grid 2 Accent 5"/> <w:LsdException Locked="false" Priority="69" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Grid 3 Accent 5"/> <w:LsdException Locked="false" Priority="70" SemiHidden="false" UnhideWhenUsed="false" Name="Dark List Accent 5"/> <w:LsdException Locked="false" Priority="71" SemiHidden="false" UnhideWhenUsed="false" Name="Colorful Shading Accent 5"/> <w:LsdException Locked="false" Priority="72" SemiHidden="false" UnhideWhenUsed="false" Name="Colorful List Accent 5"/> <w:LsdException Locked="false" Priority="73" SemiHidden="false" UnhideWhenUsed="false" Name="Colorful Grid Accent 5"/> <w:LsdException Locked="false" Priority="60" SemiHidden="false" UnhideWhenUsed="false" Name="Light Shading Accent 6"/> <w:LsdException Locked="false" Priority="61" SemiHidden="false" UnhideWhenUsed="false" Name="Light List Accent 6"/> <w:LsdException Locked="false" Priority="62" SemiHidden="false" UnhideWhenUsed="false" Name="Light Grid Accent 6"/> <w:LsdException Locked="false" Priority="63" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Shading 1 Accent 6"/> <w:LsdException Locked="false" Priority="64" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Shading 2 Accent 6"/> <w:LsdException Locked="false" Priority="65" SemiHidden="false" UnhideWhenUsed="false" Name="Medium List 1 Accent 6"/> <w:LsdException Locked="false" Priority="66" SemiHidden="false" UnhideWhenUsed="false" Name="Medium List 2 Accent 6"/> <w:LsdException Locked="false" Priority="67" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Grid 1 Accent 6"/> <w:LsdException Locked="false" Priority="68" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Grid 2 Accent 6"/> <w:LsdException Locked="false" Priority="69" SemiHidden="false" UnhideWhenUsed="false" Name="Medium Grid 3 Accent 6"/> <w:LsdException Locked="false" Priority="70" SemiHidden="false" UnhideWhenUsed="false" Name="Dark List Accent 6"/> <w:LsdException Locked="false" Priority="71" SemiHidden="false" UnhideWhenUsed="false" Name="Colorful Shading Accent 6"/> <w:LsdException Locked="false" Priority="72" SemiHidden="false" UnhideWhenUsed="false" Name="Colorful List Accent 6"/> <w:LsdException Locked="false" Priority="73" SemiHidden="false" UnhideWhenUsed="false" Name="Colorful Grid Accent 6"/> <w:LsdException Locked="false" Priority="19" SemiHidden="false" UnhideWhenUsed="false" QFormat="true" Name="Subtle Emphasis"/> <w:LsdException Locked="false" Priority="21" SemiHidden="false" UnhideWhenUsed="false" QFormat="true" Name="Intense Emphasis"/> <w:LsdException Locked="false" Priority="31" SemiHidden="false" UnhideWhenUsed="false" QFormat="true" Name="Subtle Reference"/> <w:LsdException Locked="false" Priority="32" SemiHidden="false" UnhideWhenUsed="false" QFormat="true" Name="Intense Reference"/> <w:LsdException Locked="false" Priority="33" SemiHidden="false" UnhideWhenUsed="false" QFormat="true" Name="Book Title"/> <w:LsdException Locked="false" Priority="37" Name="Bibliography"/> <w:LsdException Locked="false" Priority="39" QFormat="true" Name="TOC Heading"/> </w:LatentStyles> </xml><![endif]--><!--[if gte mso 10]> <style> /* Style Definitions */ table.MsoNormalTable {mso-style-name:普通表格; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:0; mso-style-noshow:yes; mso-style-priority:99; mso-style-parent:""; mso-padding-alt:0cm 5.4pt 0cm 5.4pt; mso-para-margin:0cm; mso-para-margin-bottom:.0001pt; mso-pagination:widow-orphan; font-size:12.0pt; font-family:Cambria; mso-ascii-font-family:Cambria; mso-ascii-theme-font:minor-latin; mso-hansi-font-family:Cambria; mso-hansi-theme-font:minor-latin; mso-font-kerning:1.0pt;} </style> <![endif]--> <!--StartFragment--> <!--EndFragment-->

D.当设计上存在多把锁时,要考虑死锁的问题,所有的代码必须按同样的顺序去使用多把锁,这样可以避免死锁。例如:数据库锁要加上no wait,这样也能避免死锁

 

 

 

 

6、无锁的并行计算相关?

6.1:非阻塞的同步/无锁

6.2:原子操作

6.3:Amino框架相关介绍

6.4:Amino集合

6.5:Amino树

6.6:Amino图

6.7:Amino简单调度模式

 

7、协程

7.1:协程的概念

7.2:Kilim框架介绍

7.3:Task及其状态

7.4:Fiber及其状态。

7.5:开发环境配置

7.6:Kilim之Hello World、

7.7:多任务通信

7.8:Kilim相关实例以及性能评估。

 

并行服务调用的3种方式。【?书?】

 

 XI:提及JVM调优,具体主要包含哪些内容?

 1、Java虚拟机内存模型相关

1.1:程序计数器

1.2:Java虚拟机栈

1.3:本地方法栈

1.4:Java堆

1.5:方法区

 

2、JVM内存相关参数的分配

2.1:设置最大堆

2.2:设置最小堆内存

2.3:设置新生代

2.4:持久代

2.5:设置线程栈

2.6:堆的比例分配

2.7:堆分配参数总结

 

3、垃圾收集相关

3.1:垃圾收集的作用

3.2:垃圾收集的算法与思想

3.3:垃圾收集器的类型

3.4:评价GC策略的指标

3.5:新生代串行收集器

3.6:老年代串行收集器

3.7:并行收集器

3.8:新生代并行回收(Parallel Scavenge)收集器

3.9:老年代并行回收收集器

3.10:CMS收集器

3.11:G1收集器(Garbage First)

3.12:Stop the wold案例

3.13:收集器对系统性能的影响

3.14:GC相关参数总结

 

4、常用调优案例和方法:

4.1:将新对象预留在新生代

4.2:大对象进入老年代

4.3:设置对象进入老年代的年龄

4.4:稳定与震荡的堆大小

4.5:吞吐量优先案例

4.6:使用大页案例

4.7:降低停顿案例

 

5、实用JVM参数

5.1:JIT编译参数

5.2:堆快照(堆Dump)

5.3:错误处理

5.4:取得GC信息

5.5:类和对象跟踪

5.6:控制GC

5.7:选择类校验器

5.8:Solaris下线程控制

5.9:使用大页

5.10:压缩指针

 

6、实战JVM调优

6.1:Tomcat简介与启动加速

6.2:Web应用程序介绍

6.3:JMeter介绍与使用

6.4:调优前Web应用运行状况

6.5:调优过程

 

7、Java性能调优工具

1)Linux命令行工具

2)Windows命令行工具

3)JDK命令行工具:jps,jstat,jinfo,jmap,jhat,jstack,jstatd,hprof

4)JConsole

5)VisualVM

6)OQL

7)MAT

8)JProfile 

 

业务知识:

1.一笔充值交易耗时1秒,具体都花在哪些地方

2.现有的系统,做了哪些优化

3.架构一个系统,需要考虑的因素有哪些

4.当前系统压测可以扛多少并发

5.线上系统cpu维持在什么范围

6.hashmap原理

7.ReentrantLock底层是否适用cas?

 

8.什么情况下要要使用单例模式

 

额外:

分布式的缓存、本地缓存、数据库分库分表,数据库事务,数据库的锁、消息中间件的基本愿意及其高可用HA的机制、幂等的处理、放重发的处理、

资金的核对、对账、系统和业务的异常监控、报警和应急处理或者是自动决策的体系,分布式系统中的跟踪方案等等都有可能被问到,具体要看面试官。还有就是你自己未来的规划,对蚂蚁金服的技术栈的了解等,

 

google的经典面试题: 一颗21个节点10层的2叉树,第7层最多有多少个节点?还有怎么用java的API实现阻塞队列?写转账的伪代码和如何解决死锁和热点账户的问题。

 

 

 

猜你喜欢

转载自josh-persistence.iteye.com/blog/2411146