java面试题汇总–持续更新中

  • 1、什么是抽象?

抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面。抽象并不打算了解全部
问题,而只是选择其中的一部分,暂时不用部分细节。抽象包括两个方面,一是过程抽象,二是数据抽象。

  • 2、什么是继承?

继承是一种连接类的层次模型,并且允许和鼓励类的重用,它提供了一种明确表述共性的方法。对象的一个新类可以从现有的类中派生,这个过程称为类继承。新类继承了原始类的特性,新类称为原始类的派生类(子类),而原始类称为新类的基类(父类)。派生类可以从它的基类那里继承方法和实例变量,并且类可以修改或增加新的方法使之更适合特殊的需要。

  • 3、什么是封装?

封装是把过程和数据包装起来,对数据的访问只能通过已定义的界面。面向对象计算始于这个基本概念,即现实世界可以被描绘成一系列完全自治、封装的对象,这些对象通过一个受保护的接口访问其他对象。

  • 4、什么是多态性?

多态性是指允许不同类的对象对同一消息作出响应。多态性包括参数化多态性和包含多态性。多态性语言具有灵活、抽象、行为共享、代码共享的优势,很好的解决了应用程序函数同名问题。

  • 5、String是最基本的数据类型吗?是否可以被继承?

基本数据类型包括byte、int、char、long、float、double、boolean和short。
java.lang.String类是final类型的,因此不可以继承这个类、不能修改这个类。为了提高效率节省空间,我们应该用StringBuffer类。
string不可以被继承,因为String类有final修饰符,而final不能被继承的,实现细节不允许改变。平常我们定义的String str = " a ";其实和String str = new String(“a”);还是有差异的。
前者默认调用的String.valueof来返回String的实例对象,至于调用哪个则取决于你的赋值,比如String num = 1;调用的是public static String valueOf(int i){
return Integer.toString(i);
}
后者则是调用如下部分:
public String(String original) {
this.value = original.value;
this.hash = original.hash;
}
最后我们的变量都存储在一个char数组中。
private final char value[];

  • 6、int 和 Integer 有什么区别?

Java 提供两种不同的类型:引用类型和原始类型(或内置类型)。Int是java的原始数据类型,Integer是java为int提供的封装类。Java为每个原始类型提供了封装类。
原始类型 封装类
boolean Boolean
char Character
byte Byte
short Short
int Integer
long Long
float Float
double Double
引用类型和原始类型的行为完全不同,并且它们具有不同的语义。引用类型和原始类型具有不同的特征和用法,它们包括:大小和速度问题,这种类型以哪种类型的数据结构存储,当引用类型和原始类型用作某个类的实例数据时所指定的缺省值。对象引用实例变量的缺省值为 null,而原始类型实例变量的缺省值与它们的类型有关。

  • 7、String 和StringBuffer有什么区别?

JAVA平台提供了两个类:String和StringBuffer,它们可以储存和操作字符串,即包含多个字符的字符数据。这个String类提供了数值不可改变的字符串。而这个StringBuffer类提供的字符串进行修改。当你知道字符数据要改变的时候你就可以使用StringBuffer。典型地,你可以使用 StringBuffers来动态构造字符数据。

  • 8、运行时异常与一般异常有什么区别?

异常表示程序运行过程中可能出现的非正常状态,运行时异常表示虚拟机的通常操作中可能遇到的异常,是一种常见运行错误。java编译器要求方法必须声明抛出可能发生的非运行时异常,但是并不要求必须声明抛出未被捕获的运行时异常。

  • 9、error和exception有什么区别?

error 表示恢复不是不可能但很困难的情况下的一种严重问题。比如说内存溢出。不可能指望程序能处理这样的情况。
exception 表示一种设计或实现问题。也就是说,它表示如果程序运行正常,从不会发生的情况。

  • 10、说出Servlet的生命周期,并说出Servlet和CGI的区别?

Servlet被服务器实例化后,容器运行其init方法,请求到达时运行其service方法,service方法自动派遣运行与请求对应的doXXX方法(doGet,doPost)等,当服务器决定将实例销毁的时候调用其destroy方法。
与cgi的区别在于servlet处于服务器进程中,它通过多线程方式运行其service方法,一个实例可以服务于多个请求,并且其实例一般不会销毁,而CGI对每个请求都产生新的进程,服务完成后就销毁,所以效率上低于servlet。

  • 11、说出ArrayList,Vector, LinkedList的存储性能和特性?

ArrayList 和Vector都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢,Vector由于使用了synchronized方法(线程安全),通常性能上较ArrayList差,而LinkedList使用双向链表实现存储,按序号索引数据需要进行前向或后向遍历,但是插入数据时只需要记录本项的前后项即可,所以插入速度较快。

  • 12、Collection 和 Collections有什么区别?

Collection是集合类的上级接口,继承与他的接口主要有Set 和List.
  Collections是针对集合类的一个帮助类,他提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作。

  • 13、EJB是基于哪些技术实现的?并说出SessionBean和EntityBean的区别,StatefulBean和StatelessBean的区别

EJB包括Session Bean、Entity Bean、Message Driven Bean,基于JNDI、RMI、JAT等技术实现。
SessionBean在J2EE应用程序中被用来完成一些服务器端的业务操作,例如访问数据库、调用其他EJB组件。EntityBean被用来代表应用系统中用到的数据。
对于客户机,SessionBean是一种非持久性对象,它实现某些在服务器上运行的业务逻辑。
对于客户机,EntityBean是一种持久性对象,它代表一个存储在持久性存储器中的实体的对象视图,或是一个由现有企业应用程序实现的实体。
Session Bean 还可以再细分为 Stateful Session Bean 与 Stateless Session Bean ,这两种的 Session Bean都可以将系统逻辑放在 method之中执行,不同的是 Stateful Session Bean 可以记录呼叫者的状态,因此通常来说,一个使用者会有一个相对应的 Stateful Session Bean 的实体。Stateless Session Bean 虽然也是逻辑组件,但是他却不负责记录使用者状态,也就是说当使用者呼叫 Stateless Session Bean 的时候,EJB Container 并不会找寻特定的 Stateless Session Bean 的实体来执行这个 method。换言之,很可能数个使用者在执行某个 Stateless Session Bean 的 methods 时,会是同一个 Bean 的 Instance 在执行。从内存方面来看, Stateful Session Bean 与 Stateless Session Bean 比较, Stateful Session Bean 会消耗 J2EE Server 较多的内存,然而 Stateful Session Bean 的优势却在于他可以维持使用者的状态。

  • **14、HashMap和Hashtable有什么区别? **

HashMap是Hashtable的轻量级实现(非线程安全的实现),他们都完成了Map接口,主要区别在于HashMap允许空(null)键值(key),由于非线程安全,效率上可能高于Hashtable。
HashMap允许将null作为一个entry的key或者value,而Hashtable不允许。
HashMap把Hashtable的contains方法去掉了,改成containsvalue和containsKey。因为contains方法容易让人引起误解。
Hashtable继承自Dictionary类,而HashMap是Java1.2引进的Map interface的一个实现。
最大的不同是,Hashtable的方法是Synchronize的,而HashMap不是,在多个线程访问Hashtable时,不需要自己为它的方法实现同步,而HashMap 就必须为之提供外同步。
Hashtable和HashMap采用的hash/rehash算法都大概一样,所以性能不会有很大的差异。

  • 15、&和&&有什么区别?

&是位运算符,表示按位与运算,&&是逻辑运算符,表示逻辑与(and)。

  • **16、final, finally, finalize有什么区别? **

final 用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。
finally是异常处理语句结构的一部分,表示总是执行。
finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。

  • **17、sleep() 和 wait() 有什么区别? **

sleep是线程类(Thread)的方法,导致此线程暂停执行指定时间,给执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复。调用sleep不会释放对象锁。
wait是Object类的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify方法(或notifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态。

  • 18、Overload和Override有什么区别。Overloaded的方法是否可以改变返回值的类型?

方法的重写Overriding和重载Overloading是Java多态性的不同表现。重写Overriding是父类与子类之间多态性的一种表现,重载Overloading是一个类中多态性的一种表现。如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写 (Overriding)。子类的对象使用这个方法时,将调用子类中的定义,对它而言,父类中的定义如同被"屏蔽"了。如果在一个类中定义了多个同名的方法,它们或有不同的参数个数或有不同的参数类型,则称为方法的重载(Overloading)。Overloaded的方法是可以改变返回值的类型。

  • 19、同步和异步有什么不同,在什么情况下分别使用他们?

如果数据将在线程间共享。例如正在写的数据以后可能被另一个线程读到,或者正在读的数据可能已经被另一个线程写过了,那么这些数据就是共享数据,必须进行同步存取。
当应用程序在对象上调用了一个需要花费很长时间来执行的方法,并且不希望让程序等待方法的返回时,就应该使用异步编程,在很多情况下采用异步途径往往更有效率。

  • 20、abstract class和interface有什么区别?

声明方法的存在而不去实现它的类被叫做抽象类(abstract class),它用于要创建一个体现某些基本行为的类,并为该类声明方法,但不能在该类中实现该类的情况。不能创建abstract 类的实例。然而可以创建一个变量,其类型是一个抽象类,并让它指向具体子类的一个实例。不能有抽象构造函数或抽象静态方法。Abstract 类的子类为它们父类中的所有抽象方法提供实现,否则它们也是抽象类为。取而代之,在子类中实现该方法。知道其行为的其它类可以在类中实现这些方法。
接口(interface)是抽象类的变体。在接口中,所有方法都是抽象的。多继承性可通过实现这样的接口而获得。接口中的所有方法都是抽象的,没有一个有程序体。接口只可以定义static final成员变量。接口的实现与子类相似,除了该实现类不能从接口定义中继承行为。当类实现特殊接口时,它定义(即将程序体给予)所有这种接口的方法。然后,它可以在实现了该接口的类的任何对象上调用接口的方法。由于有抽象类,它允许使用接口名作为引用变量的类型。通常的动态联编将生效。引用可以转换到接口类型或从接口类型转换,instanceof 运算符可以用来决定某对象的类是否实现了接口。

  • 21、堆和栈有什么区别?

栈是一种线形集合,其添加和删除元素的操作应在同一段完成。栈按照后进先出的方式进行处理。
堆是栈的一个组成元素

  • **22、forward 和redirect有什么区别? **

forward是服务器请求资源,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,然后把这些内容再发给浏览器,浏览器根本不知道服务器发送的内容是从哪儿来的,所以它的地址栏中还是原来的地址。
redirect就是服务端根据逻辑,发送一个状态码,告诉浏览器重新去请求那个地址,一般来说浏览器会用刚才请求的所有参数重新请求,所以session,request参数都可以获取。

  • 23、EJB与JAVA BEAN有什么区别?

Java Bean 是可复用的组件,对Java Bean并没有严格的规范,理论上讲,任何一个Java类都可以是一个Bean。但通常情况下,由于Java Bean是被容器所创建(如Tomcat)的,所以Java Bean应具有一个无参的构造器,另外,通常Java Bean还要实现Serializable接口用于实现Bean的持久性。Java Bean实际上相当于微软COM模型中的本地进程内COM组件,它是不能被跨进程访问的。Enterprise Java Bean 相当于DCOM,即分布式组件。它是基于Java的远程方法调用(RMI)技术的,所以EJB可以被远程访问(跨进程、跨计算机)。但EJB必须被布署在诸如Webspere、WebLogic这样的容器中,EJB客户从不直接访问真正的EJB组件,而是通过其容器访问。EJB容器是EJB组件的代理, EJB组件由容器所创建和管理。客户通过容器来访问真正的EJB组件。

  • 24、Static Nested Class 和 Inner Class的区别?

Static Nested Class是被声明为静态(static)的内部类,它可以不依赖于外部类实例被实例化。而通常的内部类需要在外部类实例化后才能实例化。

  • 25、 JSP中动态INCLUDE与静态INCLUDE有什么区别?

动态INCLUDE用jsp:include动作实现 <jsp:include page=“included.jsp” flush=“true” />它总是会检查所含文件中的变化,适合用于包含动态页面,并且可以带参数。
静态INCLUDE用include伪码实现,定不会检查所含文件的变化,适用于包含静态页面<%@ include file=“included.htm” %>

  • **26、什么时候用assert? **

assertion(断言)在软件开发中是一种常用的调试方式,很多开发语言中都支持这种机制。在实现中,assertion就是在程序中的一条语句,它对一个boolean表达式进行检查,一个正确程序必须保证这个boolean表达式的值为true;如果该值为false,说明程序已经处于不正确的状态下,系统将给出警告或退出。一般来说,assertion用于保证程序最基本、关键的正确性。assertion检查通常在开发和测试时开启。为了提高性能,在软件发布后,assertion检查通常是关闭的。

  • 27、GC是什么? 为什么要有GC?

GC是垃圾收集的意思(Gabage Collection),内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,Java提供的GC功能可以自动监测对象是否超过作用域从而达到自动回收内存的目的,Java语言没有提供释放已分配内存的显示操作方法。

  • 28、short s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 += 1;有什么错?

short s1 = 1; s1 = s1 + 1; (s1+1运算结果是int型,需要强制转换类型)
  short s1 = 1; s1 += 1;(可以正确编译)

  • 29、Math.round(11.5)等於多少? Math.round(-11.5)等於多少?

Math.round(11.5)12
  Math.round(-11.5)-11
  round方法返回与参数最接近的长整数,参数加1/2后求其floor.

  • 30、简单描述一下Zookeeper?

Zookeeper是一种为分布式应用所设计的高可用性、高性能且一致的开源协调服务,它提供一项基本服务:分布式锁服务。由于Zookeeper的开元特性,后来我们的开发者在分布式锁的基础上,摸索了出了其他的使用方法:配置维护、组服务、分布式消息队列、分布式通知/协调等。
ZooKeeper性能上的特点决定了它能够用在大型的、分布式的系统当中。从可靠性方面来说,它并不会因为一个节点的错误而崩溃。除此之外,它严格的序列访问控制意味着复杂的控制原语可以应用在客户端上。ZooKeeper在一致性、可用性、容错性的保证,也是ZooKeeper的成功之处,它获得的一切成功都与它采用的协议——Zab协议是密不可分的。首先它设计一种新的数据结构——Znode,然后在该数据结构的基础上定义了一些关于该数据结构的一些操作。有了这些数据结构和原语还不够,因为我们的ZooKeeper是工作在一个分布式的环境下,我们的服务是通过消息以网络的形式发送给我们的分布式应用程序,所以还需要一个通知机制——Watcher机制。那么总结一下,ZooKeeper所提供的服务主要是通过:数据结构+原语+watcher机制,三个部分来实现的。
ZooKeeper的数据模型,在结构上和标准文件系统的非常相似,都是采用树形层次结构,ZooKeeper树中的每个节点被称为—Znode。每个Znode由3部分组成:
① stat:此为状态信息, 描述该Znode的版本, 权限等信息
② data:与该Znode关联的数据
③ children:该Znode下的子节点
ZooKeeper虽然可以关联一些数据,但并没有被设计为常规的数据库或者大数据存储,相反的是,它用来管理调度数据,比如分布式应用中的配置文件信息、状态信息、汇集位置等等。这些数据的共同特性就是它们都是很小的数据,通常以KB为大小单位。ZooKeeper的服务器和客户端都被设计为严格检查并限制每个Znode的数据大小至多1M,但常规使用中应该远小于此值。
ZooKeeper中的节点有两种,分别为临时节点和永久节点。节点的类型在创建时即被确定,并且不能改变。
① 临时节点:该节点的生命周期依赖于创建它们的会话。一旦会话(Session)结束,临时节点将被自动删除,当然可以也可以手动删除。虽然每个临时的Znode都会绑定到一个客户端会话,但他们对所有的客户端还是可见的。另外,ZooKeeper的临时节点不允许拥有子节点。
② 永久节点:该节点的生命周期不依赖于会话,并且只有在客户端显示执行删除操作的时候,他们才能被删除。
Watch触发器概述
ZooKeeper可以为所有的读操作设置watch,这些读操作包括:exists()、getChildren()及getData()。watch事件是一次性的触发器,当watch的对象状态发生改变时,将会触发此对象上watch所对应的事件。watch事件将被异步地发送给客户端,并且ZooKeeper为watch机制提供了有序的一致性保证。理论上,客户端接收watch事件的时间要快于其看到watch对象状态变化的时间。

  • 31、线程五状态:新建、就绪、执行、阻塞、死亡

其中,阻塞状态(Blocked)
线程运行过程中,可能由于各种原因进入阻塞状态:
1>线程通过调用sleep方法进入睡眠状态;
2>线程调用一个在I/O上被阻塞的操作,即该操作在输入输出操作完成之前不会返回到它的调用者;
3>线程试图得到一个锁,而该锁正被其他线程持有;
4>线程在等待某个触发条件;
所谓阻塞状态是正在运行的线程没有运行结束,暂时让出CPU,这时其他处于就绪状态的线程就可以获得CPU时间,进入运行状态。
死亡状态(Dead)
有两个原因会导致线程死亡:
1) run方法正常退出而自然死亡,
2) 一个未捕获的异常终止了run方法而使线程猝死。

  • 32、线程安全性的五种类别

①. 不可变 – 不可变的对象一定是线程安全的,并且永远也不需要额外的同步。Java 类库中大多数基本数值类如 Integer 、 String 和 BigInteger 都是不可变的。
②. 线程安全 – 线程安全的对象,由类的规格说明所规定的约束在对象被多个线程访问时仍然有效,不管运行时环境如何排列,线程都不需要任何额外的同步。这种线程安全性保证是很严格的 – 许多类,如 Hashtable 或者 Vector都不能满足这种严格的定义。
③. 有条件的线程安全 – 有条件的线程安全类对于单独的操作可以是线程安全的,但是某些操作序列可能需要外部同步。条件线程安全的最常见的例子是遍历由 Hashtable 或者 Vector 或者返回的迭代器。
④. 线程兼容 – 线程兼容类不是线程安全的,但是可以通过正确使用同步而在并发环境中安全地使用。这可能意味着用一个 synchronized 块包围每一个方法调用,或者创建一个包装器对象,其中每一个方法都是同步的(就像 Collections.synchronizedList() 一样)。许多常见的类是线程兼容的,如集合类 ArrayList 和 HashMap 、 java.text.SimpleDateFormat 、或者 JDBC 类 Connection 和 ResultSet。
⑤. 线程对立 – 线程对立类是那些不管是否调用了外部同步都不能在并发使用时安全地呈现的类。线程对立很少见,当类修改静态数据,而静态数据会影响在其他线程中执行的其他类的行为,这时通常会出现线程对立。线程对立类的一个例子是调用 System.setOut() 的类。

  • 33、简单理解线程池技术?

多线程技术主要解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力。
假设一个服务器完成一项任务所需时间为:T1 创建线程时间,T2 在线程中执行任务的时间,T3 销毁线程时间。
如果:T1 + T3 远大于 T2,则可以采用线程池,以提高服务器性能。
一个线程池包括以下四个基本组成部分:
1、线程池管理器(ThreadPool):用于创建并管理线程池,包括 创建线程池,销毁线程池,添加新任务;
2、工作线程(PoolWorker):线程池中线程,在没有任务时处于等待状态,可以循环的执行任务;
3、任务接口(Task):每个任务必须实现的接口,以供工作线程调度任务的执行,它主要规定了任务的入口,任务执行完后的收尾工作,任务的执行状态等;
4、任务队列(taskQueue):用于存放没有处理的任务。提供一种缓冲机制。
线程池技术正是关注如何缩短或调整T1,T3时间的技术,从而提高服务器程序性能的。它把T1,T3分别安排在服务器程序的启动和结束的时间段或者一些空闲的时间段,这样在服务器程序处理客户请求时,不会有T1,T3的开销了。
线程池不仅调整T1,T3产生的时间段,而且它还显著减少了创建线程的数目,看一个例子:
假设一个服务器一天要处理50000个请求,并且每个请求需要一个单独的线程完成。在线程池中,线程数一般是固定的,所以产生线程总数不会超过线程池中线程的数目,而如果服务器不利用线程池来处理这些请求则线程总数为50000。一般线程池大小是远小于50000。所以利用线程池的服务器程序不会为了创建50000而在处理请求时浪费时间,从而提高效率。
代码实现中并没有实现任务接口,而是把Runnable对象加入到线程池管理器(ThreadPool),然后剩下的事情就由线程池管理器(ThreadPool)来完成了。
Java通过Executors提供四种线程池,分别为:
newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。
newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
// 执行任务,其实只是把任务加入任务队列,什么时候执行有线程池管理器觉定
public void execute(Runnable task) {
synchronized (taskQueue) {
taskQueue.add(task);
taskQueue.notify();
}
}
// 批量执行任务,其实只是把任务加入任务队列,什么时候执行有线程池管理器觉定
public void execute(Runnable[] task) {
synchronized (taskQueue) {
for (Runnable t : task)
taskQueue.add(t);
taskQueue.notify();
}
}
// 批量执行任务,其实只是把任务加入任务队列,什么时候执行有线程池管理器觉定
public void execute(List task) {
synchronized (taskQueue) {
for (Runnable t : task)
taskQueue.add(t);
taskQueue.notify();
}
}

  • 34、介绍几个MySQL存储引擎?

MySQL将数据用各种不同的技术存储在文件中,这些技术中的每一种技术都使用不同的存储机制、索引技巧、锁定水平并且最终提供广泛的不同的功能和能力。这些不同的技术以及配套的相关功能在 mysql中被称作存储引擎(也称作表类型)。

  1. MyISAM引擎:MyISAM引擎是MySQL默认的存储引擎,MyISAM不支持事务和行级锁,所以MyISAM引擎速度很快,性能优秀。MyISAM可以对整张表加锁,支持并发插入,支持全文索引。
    缺点:不支持事务和行级锁,也不支持外键
    优点:访问速度快,对事务的完整性没有要求或者以select、insert为主的应用基本上都可以使用这个引擎来创建
      MyISAM再磁盘上存储成三个文件,其文件名都和表名相同,但扩展名分别是:.frm(存储表定义),.MYD(存储数据),.MYI(存储索引)
  2. InnoDB引擎:InnoDB是专为事务设计的存储引擎,支持事务,支持外键,拥有高并发处理能力。但是,InnoDB在创建索引和加载数据时,比MyISAM慢。–>InnoDB有两种模式的行锁:(面试就问的这里,GG了,如何对表中的一条记录加锁?)
    1)共享锁:允许一个事务去读一行,阻止其他事务获得相同数据集的排他锁。
    ( Select * from table_name where …lock in share mode)
    2)排他锁:允许获得排他锁的事务更新数据,阻止其他事务取得相同数据集的共享读锁和 排他写锁。(select * from table_name where…for update)
  3. Memory引擎(采用哈希索引):内存表,Memory引擎将数据存储在内存中,表结构不是存储在内存中的,查询时不需要执行磁盘I/O操作,所以要比MyISAM和InnoDB快很多倍,但是数据库断电或是重启后,表中的数据将会丢失,表结构不会丢失.
  • 35、简单的介绍索引

索引是存储引擎用于快速找到记录的一种数据结构。索引本身很大,不可能全部存储在内存中,因此索引以索引表的形式存储在磁盘中。
索引是在存储引擎中实现的,而不是在服务器层中实现的。所以,每种存储引擎的索引都不一定完全相同,并不是所有的存储引擎都支持所有的索引类型。
(滴滴、宜信、广联达面试GG了,B+、B-区别?)
{★ B-树索引:每一个叶子节点都包含指向下一个叶子节点的指针,从而方便叶子节点的范围遍历。B-Tree通常意味着所有的值都是按顺序存储的,并且每一个叶子页到根的距离相同,很适合查找范围数据。
★ B+树索引:并不能找到一个给定健值的具体行,B+树索引只能找到被查找数据行所在的页,然后从数据库将页读入内存,在内存中查找。B+树索引可以分为聚集索引和辅助索引。聚簇索引是按照数据存放的逻辑地址为顺序的,而非聚簇索引就不一样了;聚簇索引能提高多行检索的速度,而非聚簇索引对于单行的检索很快。}
○ 聚集索引 :聚集索引是一种索引组织形式,索引的键值逻辑顺序决定了表数据行的物理存储顺序。 聚集索引对于那些经常要搜索范围值的列特别有效。使用聚集索引找到包含第一个值的行后,便可以确保包含后续索引值的行在物理相邻。
InnoDB的数据文件本身要按主键聚集,所以InnoDB要求表必须有主键(MyISAM可以没有主键),如果没有显式指定,则MySQL系统会自动选择一个可以唯一标识数据记录的列作为主键,如果不存在这种列,则MySQL自动为InnoDB表生成一个隐含字段作为主键,这个字段长度为6个字节,类型为长整形。
○ 辅助索引:叶结点的data域存放的是对应记录的主键的key。 对于建立辅助索引的表需要先根据辅助索引找到相应的主键,再根据主键在聚集索引中找到相应的记录集。
○ 非聚集索引
非聚集索引则就是普通索引了,仅仅只是对数据列创建相应的索引,不影响整个表的物理存储顺序。主键索引中,叶节点的data域存放的是数据记录的地址,如果指定的Key存在,则取出其data域的值,然后以data域的值为地址,读取相应数据记录。(MYISAM采用此种索引方式)。
区别:
聚集索引表里数据物理存储顺序和主键索引的顺序一致,所以如果新增数据是离散的,会导致数据块趋于离散,而不是趋于顺序。而非聚集索引表数据写入的顺序是按写入时间顺序存储的。聚簇索引索引的叶节点就是数据节点;而非聚簇索引的叶节点仍然是索引节点,只不过有一个指针指向对应的数据块。
适用情景
★ Hash索引:哈希索引基于哈希表实现,只有精确索引所有列的查询才有效。对于每一行数据,存储引擎都会对所有的索引列计算一个哈希码,哈希码是一个较小的值,并且不同键值的行计算出来的哈希码也不一样。哈希索引将所有的哈希存储在索引中,同时在哈希表中保存指向每个数据的指针。
哈希索引中存储的是:哈希值+数据行指针
MySQL中,只有Memory存储引擎显示支持hash索引,是Memory表的默认索引类型,尽管Memory表也可以使用B-Tree索引。Memory存储引擎支持非唯一hash索引,这在数据库领域是罕见的,如果多个值有相同的hash code,索引把它们的行指针用链表保存到同一个hash表项中。
索引有如下优点与缺点:
★ 优点
1.可以通过建立唯一索引或者主键索引,保证数据库表中每一行数据的唯一性
2.建立索引可以大大提高检索的数据,以及减少表的检索行数
3.在表连接的连接条件,可以加速表与表直接的相连
4.在分组和排序字句进行数据检索,可以减少查询时间中分组和 排序时所消耗的时间(数据库的记录会重新排序)
5.建立索引,在查询中使用索引,可以提高性能
–索引大大减小了服务器需要扫描的数据量
–索引可以帮助服务器避免排序和临时表
–索引可以将随机IO变成顺序IO
△ 缺点
1.创建索引和维护索引会耗费时间,随着数据量的增加而增加
2.索引文件会占用物理空间,除了数据表需要占用物理空间之外,每一个索引还会占用一定的物理空间
3.当对表的数据进行 INSERT,UPDATE,DELETE 的时候,索引也要动态的维护,这样就会降低数据的维护速度,(建立索引会占用磁盘空间的索引文件。一般情况这个问题不太严重,但如果你在一个大表上创建了多种组合索引,索引文件的会膨胀很快)。
索引的使用:最好的做法是创建表的时候创建索引,如果创建表之后再修改新建索引的话,对于聚集索引,会根据原来的表,创建一个新的表带有索引数据结构,再把原来的表删去,新创建的表改成原来的表的名字。而非聚集索引则是通过修改索引文件来完成。所以都是需要占用额外的资源来修改或新建索引的。

  • 36、说一下synchronized原理?

①.synchronized的字节码表示:
在java语言中存在两种内建的synchronized语法:1、synchronized语句;2、synchronized方法。对于synchronized语句当Java源代码被javac编译成bytecode的时候,会在同步块的入口位置和退出位置分别插入monitorenter和monitorexit字节码指令。而synchronized方法则会被翻译成普通的方法调用和返回指令如:invokevirtual、areturn指令,在VM字节码层面并没有任何特别的指令来实现被synchronized修饰的方法,而是在Class文件的方法表中将该方法的access_flags字段中的synchronized标志位置1,表示该方法是同步方法并使用调用该方法的对象或该方法所属的Class在JVM的内部对象表示Class做为锁对象。
②.JVM中锁的优化:
简单来说在JVM中monitorenter和monitorexit字节码依赖于底层的操作系统的Mutex Lock来实现的,但是由于使用Mutex Lock需要将当前线程挂起并从用户态切换到内核态来执行,这种切换的代价是非常昂贵的;然而在现实中的大部分情况下,同步方法是运行在单线程环境(无锁竞争环境)如果每次都调用Mutex Lock那么将严重的影响程序的性能。不过在jdk1.6中对锁的实现引入了大量的优化,如锁粗化(Lock Coarsening)、锁消除(Lock Elimination)、轻量级锁(Lightweight Locking)、偏向锁(Biased Locking)、适应性自旋(Adaptive Spinning)等技术来减少锁操作的开销。
③.在JVM中创建对象时会在对象前面加上两个字大小的对象头(Object header),在32位机器上一个字为32bit,根据不同的状态位Mark World中存放不同的内容,在轻量级锁中,Mark Word被分成两部分,刚开始时LockWord为被设置为HashCode、最低三位表示LockWord所处的状态,初始状态为001表示无锁状态。
④.Monitor Record是线程私有的数据结构,每一个线程都有一个可用monitor record列表,同时还有一个全局的可用列表;那么这些monitor record有什么用呢?每一个被锁住的对象都会和一个monitor record关联(对象头中的LockWord指向monitor record的起始地址,由于这个地址是8byte对齐的所以LockWord的最低三位可以用来作为状态),同时monitor record中有一个Owner字段存放拥有该锁的线程的唯一标识,表示该锁被这个线程占用。
⑤.获取锁(monitorenter)的大概过程如下:
当对象处于无锁状态时(RecordWord值为HashCode,状态位为001),线程首先从自己的可用moniter record列表中取得一个空闲的moniter record,初始Nest和Owner值分别被预先设置为1和该线程自己的标识,一旦monitor record准备好然后我们通过CAS原子指令安装该monitor record的起始地址到对象头的LockWord字段来膨胀.
对象已经被膨胀同时Owner中保存的线程标识为获取锁的线程自己,这就是重入(reentrant)锁的情况,只需要简单的将Nest加1即可。不需要任何原子操作,效率非常高
对象已膨胀但Owner的值为NULL,当一个锁上存在阻塞或等待的线程同时锁的前一个拥有者刚释放锁时会出现这种状态,此时多个线程通过CAS原子指令在多线程竞争状态下试图将Owner设置为自己的标识来获得锁,竞争失败的线程在则会进入到第四种情况的执行路径。
对象处于膨胀状态同时Owner不为NULL(被锁住),在调用操作系统的重量级的互斥锁之前先自旋一定的次数,当达到一定的次数时如果仍然没有成功获得锁,则开始准备进入阻塞状态,首先将rfThis的值原子性的加1,由于在加1的过程中可能会被其他线程破坏Object和monitor record之间的关联,所以在原子性加1后需要再进行一次比较以确保LockWord的值没有被改变,当发现被改变后则要重新进行monitorenter过程。同时再一次观察Owner是否为NULL,如果是则调用CAS参与竞争锁,锁竞争失败则进入到阻塞状态。
⑥.释放锁(monitorexit)的大概过程如下:
首先检查该对象是否处于膨胀状态并且该线程是这个锁的拥有者,如果发现不对则抛出异常;
检查Nest字段是否大于1,如果大于1则简单的将Nest减1并继续拥有锁,如果等于1,则进入到下一步;
检查rfThis是否大于0,设置Owner为NULL然后唤醒一个正在阻塞或等待的线程再一次试图获取锁,如果等于0则进入到下一步;
缩小(deflate)一个对象,通过将对象的LockWord置换回原来的HashCode值来解除和monitor record之间的关联来释放锁,同时将monitor record放回到线程是有的可用monitor record列表。

  • 37、二叉排序树的性质?

按中序遍历二叉排序树,所得到的中序遍历序列是一个递增有序序列。

  • 38、什么是事务?有哪些属性?以及属性的意义。

事务是并发操作的单位,是用户定义的一个操作序列。
事务的四个特性:原子性(事务必须是一个不可分割的整体)、一致性(执行完数据库操作后,数据不会被破坏,A给B充Q币,A充了之后B能看见自己的Q币多了)、隔离性(写写之间隔离)、持久性(数据库必须要保证有一条数据永久地存放在磁盘)。

  • 39、 SQL语句常用优化技巧

要提高SQL语句的执行效率,最常见的方法就是建立索引,以及尽量避免全表扫描。一个简单的优化,也许能让你的SQL执行效率提高几倍,甚至几十倍。
①.避免在where子句中使用 is null 或 is not null 对字段进行判断。
如:select id from table where name is null
在这个查询中,就算我们为 name 字段设置了索引,查询分析器也不会使用,因此查询效率底下。为了避免这样的查询,在数据库设计的时候,尽量将可能会出现 null 值的字段设置默认值,这里如果我们将 name 字段的默认值设置为0,那么我们就可以这样查询:
select id from table where name = 0
②.避免在 where 子句中使用 != 或 <> 操作符。
如:select name from table where id <> 0
数据库在查询时,对 != 或 <> 操作符不会使用索引,而对于 < 、 <= 、 = 、 > 、 >= 、 BETWEEN AND,数据库才会使用索引。因此对于上面的查询,正确写法应该是:
select name from table where id < 0
union all
select name from table where id > 0
这里我们为什么没有使用 or 来链接 where 后的两个条件呢?这就是我们下面要说的第3个优化技巧。
③.避免在 where 子句中使用 or来链接条件。
如:select id from tabel where name = ‘UncleToo’ or name = ‘PHP’
这种情况,我们可以这样写:
select id from tabel where name = ‘UncleToo’
union all
select id from tabel where name = ‘PHP’
④.少用 in 或 not in。
虽然对于 in 的条件会使用索引,不会全表扫描,但是在某些特定的情况,使用其他方法也许效果更好。如:
select name from tabel where id in(1,2,3,4,5)
像这种连续的数值,我们可以使用 BETWEEN AND,如:
select name from tabel where id between 1 and 5
⑤.注意 like 中通配符的使用
下面的语句会导致全表扫描,尽量少用。如:
select id from tabel where name like’%UncleToo%’
或者
select id from tabel where name like’%UncleToo’
而下面的语句执行效率要快的多,因为它使用了索引:
select id from tabel where name like’UncleToo%’
⑥.避免在 where 子句中对字段进行表达式操作。
如:select name from table where id/2 = 100
正确的写法应该是:
select name from table where id = 100*2
⑦.避免在 where 子句中对字段进行函数操作。
如:select id from table where substring(name,1,8) = ‘UncleToo’
或 select id from table where datediff(day,datefield,‘2014-07-17’) >= 0
这两条语句中都对字段进行了函数处理,这样就是的查询分析器放弃了索引的使用。正确的写法是这样的:
select id from table where name like’UncleToo%’
或 select id from table where datefield <= ‘2014-07-17’
也就是说,不要在 where 子句中的 = 左边进行函数、算术运算或其他表达式运算。
⑧.在子查询中,用 exists 代替 in 是一个好的选择。
如:select name from a where id in(select id from b)
如果我们将这条语句换成下面的写法:select name from a where id exists(select 1 from b where id = a.id)
这样,查询出来的结果一样,但是下面这条语句查询的速度要快的多。
⑨.对查询进行优化,要尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。
⑩.不要在 where 子句中的“=”左边进行函数、算术运算或其他表达式运算,否则系统将可能无法正确使用索引。
如果使用到了临时表,在存储过程的最后务必将所有的临时表显式删除,先 truncate table ,然后 drop table ,这样可以避免系统表的较长时间锁定。
尽量避免大事务操作,提高系统并发能力。

  • 40、简要说NoSQL 数据库的分布式模型

分片 – 特点:数据的各个部分存放在集群的不同服务器中;比如按字母来划分:以a-g 开头的键值都存放到第一台,服务器上,以h-n 开头的存放到第二台…
需要考虑的问题 – 如何存放数据,让用户基本上只需从一台服务器上获取数据?如果经常需要与多个结点交互才能取到需要数据,可能分片策略不合适,或者该场景中分片不是一个理想的方案;
数据节点的分布 – 地理位置与访问用户的关系 数据结点分布在全球各地,让北京的用户只需要访问北京的结点就能取到所需数据;
保持负载均衡 – 优点:同时提升读取和写入性能、由于分片是将数据分散到多个结点存储,这样在写入时,压力同样分散;横向扩展写入能力 缺点:降低数据库的错误恢复能力,分片后,集群中结点的故障将导致部分数据丢失;
解决方案 – 每个分片数据不只存放在一个结点上,冗余存放,增加数据安全性(通过后面讲到的与主从复制的结合使用,是常用的手段)
主从复制 – 特点:主节点存放权威数据,负责数据更新操作;主节点将更新的数据复制到从节点;优点:有助于提升数据读取性能,从结点只负责查询,增加从结点提升数据读取性能,增强“读取操作的故障恢复能力”,主节点损坏,依然可处理读取请求;从结点升级为主结点后可以处理更新请求;
“一拖一” 即时备份的单存储方案 – 即使不需要分布式部署,主从复制也可以用来做为单机服务器备份的部署方案;缺点:数据的不一致性(未及时更新),主节点更新后,同步到各个从结点的数据不能保证及时,可能导致各个结点上查询的数据不一致(只具有最终一致性)、对提升写入操作性能帮助不大、所有的更新操作都通过主结点处理,对于更新频繁的业务,使用主从复制模型优势不大;
主节点是系统的瓶颈和弱点
对等复制 – 特点:所有节点地位相同,都可接收查询和写入请求;各节点将自己的更新的数据复制到其他节点;优点:从容处理出错节点,不必担心数据请求的丢失增加节点,轻易提升查询和写入性能;缺点:数据不一致性、写入和读取都有可能发生冲突;
结合使用 – 分片和主从复制中的一拖一方案结合使用、分片的作用在于数据的分布式存储;主从复制的作用在于为各个分片结点提供备份,增加数据安全;

  • 41、Java 集合部分都有哪些接口,主要体现了哪些设计模式?

Java 集合部分主要有Collection、List、Set、Map、Comparator、Iterator 等,主要体现的设计模式是策略模式和迭代模式
策略模式主要体现在每个接口有不同的实现,可以完成互换,如List 接口下有ArrayList 和LinkedList,在不同的场景下可以互换。
迭代模式主要体现在Iterator 的实现,为不同的数据存储方式(数组、链表、散列表等)提供了统一的访问方式。
Comparator 体现的设计模式是什么? – 策略模式,即不改变对象自身,而使用一个策略对象去改变它的行为。
注:策略模式的优缺点是什么:
优点:(1)将具体算法逻辑与客户类分离,(2)避免了大量的if else 判断
缺点:(1)每个算法一个类,产生了太多的类,(2)客户端要知道所有的策略类,以便决定使用哪一个。

  • 42、垃圾回收的优点和原理。并考虑2种回收机制

Java语言中一个显着的特点就是引入了垃圾回收机制,使c++程序员最头疼的内存管理的问题迎刃而解,它使得Java程序员在编写程序的时候不再需要考虑内存管理。由于有个垃圾回收机制, Java中的对象不再有"作用域"的概念,只有对象的引用才有"作用域"。垃圾回收可以有效的防止内存泄露,有效的使用可以使用的内存。垃圾回收器通常是作为一个单独的低级别的线程运行,不可预知的情况下对内存堆中已经死亡的或者长时间没有使用的对象进行清楚和回收,程序员不能实时的调用垃圾回收器对某个对象或所有对象进行垃圾回收。回收机制有分代复制垃圾回收和标记垃圾回收,增量垃圾回收。

  • 43、请说出你所知道的线程同步的方法?

wait():使一个线程处于等待状态,并且释放所持有的对象的lock。
sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要捕捉InterruptedException异常。
notify():唤醒一个处于等待状态的线程,注意的是在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由JVM确定唤醒哪个线程,而且不是按优先级。
Allnotity():唤醒所有处入等待状态的线程,注意并不是给所有唤醒线程一个对象的锁,而是让它们竞争。

  • 44、你所知道的集合类都有哪些?主要方法?

最常用的集合类是 List 和 Map。 List 的具体实现包括 ArrayList 和 Vector,它们是可变大小的列表,比较适合构建、存储和操作任何类型对象的元素列表。 List 适用于按数值索引访问元素的情形。
Map 提供了一个更通用的元素存储方法。 Map 集合类用于存储元素对(称作"键"和"值"),其中每个键映射到一个值。

  • 45、描述一下JVM加载class文件的原理机制?

JVM中类的装载是由ClassLoader和它的子类来实现的,Java ClassLoader 是一个重要的Java运行时系统组件。它负责在运行时查找和装入类文件的类。

  • 46、char型变量中能不能存贮一个中文汉字?为什么?

能够定义成为一个中文的,因为java中以unicode编码,一个char占16个字节,所以放一个中文是没问题的

  • 47、多线程有几种实现方法,都是什么?同步有几种实现方法,都是什么?

多线程有两种实现方法,分别是继承Thread类与实现Runnable接口
同步的实现方面有两种,分别是synchronized,wait与notify

  • **48、JSP的内置对象及方法。 **

request表示HttpServletRequest对象。它包含了有关浏览器请求的信息,并且提供了几个用于获取cookie, header, 和session数据的有用的方法。
response表示HttpServletResponse对象,并提供了几个用于设置送回浏览器的响应的方法(如cookies,头信息等)
out对象是javax.jsp.JspWriter的一个实例,并提供了几个方法使你能用于向浏览器回送输出结果。
pageContext表示一个javax.servlet.jsp.PageContext对象。它是用于方便存取各种范围的名字空间、servlet相关的对象的API,并且包装了通用的servlet相关功能的方法。
session表示一个请求的javax.servlet.http.HttpSession对象。Session可以存贮用户的状态信息
applicaton 表示一个javax.servle.ServletContext对象。这有助于查找有关servlet引擎和servlet环境的信息
config表示一个javax.servlet.ServletConfig对象。该对象用于存取servlet实例的初始化参数。
page表示从该页面产生的一个servlet实例。

  • 49、线程的基本概念、线程的基本状态以及状态之间的关系

线程指在程序执行过程中,能够执行程序代码的一个执行单位,每个程序至少都有一个线程,也就是程序本身。
Java中的线程有四种状态分别是:运行、就绪、挂起、结束。

  • 50、JSP的常用指令?

<%@page language=“java” contenType=“text/html;charset=gb2312” session=“true” buffer=“64kb” autoFlush=“true” isThreadSafe=“true” info=“text” errorPage=“error.jsp” isErrorPage=“true” isELIgnored=“true” pageEncoding=“gb2312” import=“java.sql.*”%>
isErrorPage(是否能使用Exception对象),isELIgnored(是否忽略表达式)
<%@include file=“filename”%>
<%@taglib prefix="c"uri=“http://…”%>

  • 51、什么情况下调用doGet()和doPost()?

Jsp页面中的form标签里的method属性为get时调用doGet(),为post时调用doPost()。

  • 52、简述servlet的生命周期

web容器加载servlet,生命周期开始。通过调用servlet的init()方法进行servlet的初始化。通过调用service()方法实现,根据请求的不同调用不同的do***()方法。结束服务,web容器调用servlet的destroy()方法。

  • 53、如何现实servlet的单线程模式

<%@ page isThreadSafe=“false”%>

  • 54、页面间对象传递的方法

request,session,application,cookie等

  • 55、JSP和Servlet有哪些相同点和不同点,他们之间的联系是什么?

JSP 是Servlet技术的扩展,本质上是Servlet的简易方式,更强调应用的外表表达。JSP编译后是"类servlet"。Servlet和JSP最主要的不同点在于,Servlet的应用逻辑是在Java文件中,并且完全从表示层中的HTML里分离开来。而JSP的情况是Java和HTML可以组合成一个扩展名为.jsp的文件。JSP侧重于视图,Servlet主要用于控制逻辑。

  • **56、四种会话跟踪技术 **

会话作用域ServletsJSP 页面描述
page否是代表与一个页面相关的对象和属性。一个页面由一个编译好的 Java servlet 类(可以带有任何的 include 指令,但是没有 include 动作)表示。这既包括 servlet 又包括被编译成 servlet 的 JSP 页面
request是是代表与 Web 客户机发出的一个请求相关的对象和属性。一个请求可能跨越多个页面,涉及多个 Web 组件(由于 forward 指令和 include 动作的关系)
session是是代表与用于某个 Web 客户机的一个用户体验相关的对象和属性。一个 Web 会话可以也经常会跨越多个客户机请求
application是是代表与整个 Web 应用程序相关的对象和属性。这实质上是跨越整个 Web 应用程序,包括多个页面、请求和会话的一个全局作用域

  • 57、Request对象的主要方法:

setAttribute(String name,Object):设置名字为name的request的参数值
getAttribute(String name):返回由name指定的属性值
getAttributeNames():返回request对象所有属性的名字集合,结果是一个枚举的实例
getCookies():返回客户端的所有Cookie对象,结果是一个Cookie数组
getCharacterEncoding():返回请求中的字符编码方式
getContentLength():返回请求的Body的长度
getHeader(String name):获得HTTP协议定义的文件头信息
getHeaders(String name):返回指定名字的request Header的所有值,结果是一个枚举的实例
getHeaderNames():返回所以request Header的名字,结果是一个枚举的实例
getInputStream():返回请求的输入流,用于获得请求中的数据
getMethod():获得客户端向服务器端传送数据的方法
getParameter(String name):获得客户端传送给服务器端的有name指定的参数值
getParameterNames():获得客户端传送给服务器端的所有参数的名字,结果是一个枚举的实例
getParameterValues(String name):获得有name指定的参数的所有值
getProtocol():获取客户端向服务器端传送数据所依据的协议名称
getQueryString():获得查询字符串
getRequestURI():获取发出请求字符串的客户端地址
getRemoteAddr():获取客户端的IP地址
getRemoteHost():获取客户端的名字
getSession([Boolean create]):返回和请求相关Session
getServerName():获取服务器的名字
getServletPath():获取客户端所请求的
脚本文件的路径
getServerPort():获取服务器的端口号
removeAttribute(String name):删除请求中的一个属性

  • 58、J2EE是技术还是平台还是框架?

J2EE本身是一个标准,一个为企业分布式应用的开发提供的标准平台。
J2EE也是一个框架,包括JDBC、JNDI、RMI、JMS、EJB、JTA等技术。

  • 59、我们在web应用开发过程中经常遇到输出某种编码的字符,如iso8859-1等,如何输出一个某种编码的字符串?

Public String translate (String str) {
String tempStr = “”;
try {
tempStr = new String(str.getBytes(“ISO-8859-1”), “GBK”);
tempStr = tempStr.trim();
}
catch (Exception e) {
System.err.println(e.getMessage());
}
return tempStr;
}

  • 60、简述逻辑操作(&,|,^)与条件操作(&&,||)的区别。

区别主要答两点:
a.条件操作只能操作布尔型的,而逻辑操作不仅可以操作布尔型,而且可以操作数值型
b.逻辑操作不会产生短路

  • 61、XML文档定义有几种形式?它们之间有何本质区别?解析XML文档有哪几种方式?

a: 两种形式 dtd schema,b: 本质区别:schema本身是xml的,可以被XML解析器解析(这也是从DTD上发展schema的根本目的),c:有DOM,SAX,STAX等
DOM:处理大型文件时其性能下降的非常厉害。这个问题是由DOM的树结构所造成的,这种结构占用的内存较多,而且DOM必须在解析文件之前把整个文档装入内存,适合对XML的随机访问
SAX:不现于DOM,SAX是事件驱动型的XML解析方式。它顺序读取XML文件,不需要一次全部装载整个文件。当遇到像文件开头,文档结束,或者标签开头与标签结束时,它会触发一个事件,用户通过在其回调事件中写入处理代码来处理XML文件,适合对XML的顺序访问
STAX:Streaming API for XML (StAX)

  • 62、简述synchronized和java.util.concurrent.locks.Lock的异同?

主要相同点:Lock能完成synchronized所实现的所有功能
主要不同点:Lock有比synchronized更精确的线程语义和更好的性能。synchronized会自动释放锁,而Lock一定要求程序员手工释放,并且必须在finally从句中释放。

  • 63、EJB的角色和三个对象

一个完整的基于EJB的分布式计算结构由六个角色组成,这六个角色可以由不同的开发商提供,每个角色所作的工作必须遵循Sun公司提供的EJB规范,以保证彼此之间的兼容性。这六个角色分别是EJB组件开发者(Enterprise Bean Provider) 、应用组合者(Application Assembler)、部署者(Deployer)、EJB 服务器提供者(EJB Server Provider)、EJB 容器提供者(EJB Container Provider)、系统管理员(System Administrator)
三个对象是Remote(Local)接口、Home(LocalHome)接口,Bean类。

  • 64、EJB容器提供的服务

主要提供声明周期管理、代码产生、持续性管理、安全、事务管理、锁和并发行管理等服务。

  • 65、EJB规范规定EJB中禁止的操作有哪些?

1.不能操作线程和线程API(线程API指非线程对象的方法如notify,wait等),
2.不能操作awt,
3.不能实现服务器功能,
4.不能对静态属生存取,
5.不能使用IO操作直接存取文件系统,
6.不能加载本地库.,
7.不能将this作为变量和返回,
8.不能循环调用。

  • 66、remote接口和home接口主要作用

remote接口定义了业务方法,用于EJB客户端调用业务方法。
home接口是EJB工厂用于创建和移除查找EJB实例

  • 67、24种设计模式(gof23+1):

创建型模式:
1.简单工厂模式(不包含在gof23中)
2.工厂模式
3.抽象工厂模式
4.单例模式
5.原型模式
创建者模式
6.结构型模式:
7.组合模式
8.装饰者模式
9.外观模式
10.适配器模式
11.代理模式
12.享元模式
13.桥接模式
行为型模式:
14.观察者模式
15.策略模式
16.状态模式
17.中介模式
18.模板方法
19.命令模式
20.备忘录模式
21.访问者模式
22.解释器模式
23.迭代器模式
24.职责链模式
这里只是简单描述了定义和特征以及设计模式的关系,具体细节不讨论。

  • 68、简述你所知道的Linux:

Linux起源于1991年,1995年流行起来的免费操作系统,目前, Linux是主流的服务器操作系统, 广泛应用于互联网、云计算、智能手机(Android)等领域。由于Java主要用于服务器端的开发,因此Java应用的部署环境有很多为Linux。
Windows操作系统的目录结构,是以盘符为单位,C盘、D盘、E盘等等,数据存储在各个盘符之下,而Linux操作系统最顶层只有一个根目录root,所有文件都存储在这一个根目录之下。
Linux不像Windows的图形操作界面,是通过命令的方式进行操作,常用命令有:
a . pwd:用于显示当前工作目录;
b . ls:用于查看当前工作目录内容;
c . cd:用于改变当前工作目录。

  • 69、什么是Java虚拟机?为什么Java被称作是“平台无关的编程语言”?

Java虚拟机是一个可以执行Java字节码的虚拟机进程。Java源文件被编译成能被Java虚拟机执行的字节码文件。
Java被设计成允许应用程序可以运行在任意的平台,而不需要程序员为每一个平台单独重写或者是重新编译。Java虚拟机让这个变为可能,因为它知道底层硬件平台的指令长度和其他特性。

  • 70、JDK、JRE、JVM关系是什么?

JDK(Java Development Kit)即为Java开发工具包,包含编写Java程序所必须的编译、运行等开发工具以及JRE。开发工具如:用于编译java程序的javac命令、用于启动JVM运行java程序的java命令、用于生成文档的javadoc命令以及用于打包的jar命令等等。
JRE(Java Runtime Environment)即为Java运行环境,提供了运行Java应用程序所必须的软件环境,包含有Java虚拟机(JVM)和丰富的系统类库。系统类库即为java提前封装好的功能类,只需拿来直接使用即可,可以大大的提高开发效率。
JVM(Java Virtual Machines)即为Java虚拟机,提供了字节码文件(.class)的运行环境支持。
简单说,就是JDK包含JRE包含JVM。

  • 71、Java支持的数据类型有哪些?什么是自动拆装箱?

基本数据类型:
整数值型:byte,short,int,long,
字符型:char
浮点类型:float,double
布尔型:boolean
整数默认int型,小数默认是double型。Float和long类型的必须加后缀。
首先知道String是引用类型不是基本类型,引用类型声明的变量是指该变量在内存中实际存储的是一个引用地址,实体在堆中。引用类型包括类、接口、数组等。String类还是final修饰的。
而包装类就属于引用类型,自动装箱和拆箱就是基本类型和引用类型之间的转换,至于为什么要转换,因为基本类型转换为引用类型后,就可以new对象,从而调用包装类中封装好的方法进行基本类型之间的转换或者toString(当然用类名直接调用也可以,便于一眼看出该方法是静态的),还有就是如果集合中想存放基本类型,泛型的限定类型只能是对应的包装类型。

  • 72、面向对象是什么?

面向对象是一种思想,世间万物都可以看做一个对象,这里只讨论面向对象编程(OOP),Java是一个支持并发、基于类和面向对象的计算机编程语言,面向对象软件开发的优点:
代码开发模块化,更易维护和修改;
代码复用性强;
增强代码的可靠性和灵活性;
增加代码的可读性。

  • 73、面向对象的四大基本特性:

抽象:提取现实世界中某事物的关键特性,为该事物构建模型的过程。对同一事物在不同的需求下,需要提取的特性可能不一样。得到的抽象模型中一般包含:属性(数据)和操作(行为)。这个抽象模型我们称之为类。对类进行实例化得到对象。
封装:封装可以使类具有独立性和隔离性;保证类的高内聚。只暴露给类外部或者子类必须的属性和操作。类封装的实现依赖类的修饰符(public、protected和private等)
继承:对现有类的一种复用机制。一个类如果继承现有的类,则这个类将拥有被继承类的所有非私有特性(属性和操作)。这里指的继承包含:类的继承和接口的实现。
多态:多态是在继承的基础上实现的。多态的三个要素:继承、重写和父类引用指向子类对象。父类引用指向不同的子类对象时,调用相同的方法,呈现出不同的行为;就是类多态特性。多态可以分成编译时多态和运行时多态。
抽象、封装、继承和多态是面向对象的基础。在面向对象四大基础特性之上,我们在做面向对象编程设计时还需要遵循有一些基本的设计原则。

  • 74、面向对象的七大设计原则:

SOLID原则(单一职责原则、开放关闭原则、里氏替换原则、接口隔离原则和依赖倒置原则)
迪米特法则
组合优于继承原则(合成复用原则)。
在遵循这些面向对象设计原则基础上,前辈们总结出一些解决不同问题场景的设计模式,以四人帮的gof23最为知名。

  • 75、什么是值传递和引用传递?

值传递是对基本型变量而言的,传递的是该变量的一个副本,改变副本不影响原变量.
引用传递一般是对于对象型变量而言的,传递的是该对象地址的一个副本, 并不是原对象本身 。
一般认为,java内的传递都是值传递. java中实例对象的传递是引用传递 。

  • 76、是否可以在static环境中访问非static变量?

static变量在Java中是属于类的,它在所有的实例中的值是一样的。当类被Java虚拟机载入的时候,会对static变量进行初始化。如果你的代码尝试不用实例来访问非static的变量,编译器会报错,因为这些变量还没有被创建出来,还没有跟任何实例关联上。

  • 77、Java中,什么是构造方法?什么是构造方法重载?什么是复制构造方法?

当新对象被创建的时候,构造方法会被调用。每一个类都有构造方法。在程序员没有给类提供构造方法的情况下,Java编译器会为这个类创建一个默认的构造方法。
Java中构造方法重载和方法重载很相似。可以为一个类创建多个构造方法。每一个构造方法必须有它自己唯一的参数列表。
Java不支持像C++中那样的复制构造方法,这个不同点是因为如果你不自己写构造方法的情况下,Java不会创建默认的复制构造方法。

  • 78、Java支持多继承么?

Java中类不支持多继承,只支持单继承(即一个类只有一个父类)。 但是java中的接口支持多继承,,即一个子接口可以有多个父接口。(接口的作用是用来扩展对象的功能,一个子接口继承多个父接口,说明子接口扩展了多个功能,当类实现接口时,类就扩展了相应的功能)。

  • **79、解释内存中的栈(stack)、堆(heap)和方法区(method area)的用法。 **

通常我们定义一个基本数据类型的变量,一个对象的引用,还有就是函数调用的现场保存都使用JVM中的栈空间;而通过new关键字和构造器创建的对象则放在堆空间,堆是垃圾收集器管理的主要区域,由于现在的垃圾收集器都采用分代收集算法,所以堆空间还可以细分为新生代和老生代,再具体一点可以分为Eden、Survivor(又可分为From Survivor和To Survivor)、Tenured;方法区和堆都是各个线程共享的内存区域,用于存储已经被JVM加载的类信息、常量、静态变量、JIT编译器编译后的代码等数据;程序中的字面量(literal)如直接书写的100、”hello”和常量都是放在常量池中,常量池是方法区的一部分,。栈空间操作起来最快但是栈很小,通常大量的对象都是放在堆空间,栈和堆的大小都可以通过JVM的启动参数来进行调整,栈空间用光了会引发StackOverflowError,而堆和常量池空间不足则会引发OutOfMemoryError。

  • **80、接口和抽象类的区别是什么? **

从设计层面来说,抽象是对类的抽象,是一种模板设计,接口是行为的抽象,是一种行为的规范。
Java提供和支持创建抽象类和接口。它们的实现有共同点,不同点在于:
接口中所有的方法隐含的都是抽象的。而抽象类则可以同时包含抽象和非抽象的方法。
类可以实现很多个接口,但是只能继承一个抽象类
类可以不实现抽象类和接口声明的所有方法,当然,在这种情况下,类也必须得声明成是抽象的。
抽象类可以在不提供接口方法实现的情况下实现接口。
Java接口中声明的变量默认都是final的。抽象类可以包含非final的变量。
Java接口中的成员函数默认是public的。抽象类的成员函数可以是private,protected或者是public。
接口是绝对抽象的,不可以被实例化。抽象类也不可以被实例化,但是,如果它包含main方法的话是可以被调用的。
也可以参考JDK8中抽象类和接口的区别。

  • **81、用最有效率的方法计算2乘以8? **

2 << 3(左移3位相当于乘以2的3次方,右移3位相当于除以2的3次方)。

  • **82、手写单例模式(饿汉和饱汉模式)和工厂模式? **

(1)单例饿汉模式://饿汉式单例类.在类初始化时,已经自行实例化
2 public class Singleton1 {
3 //私有的默认构造子
4 private Singleton1() {}
5 //已经自行实例化
6 private static final Singleton1 single = new Singleton1();
7 //静态工厂方法
8 public static Singleton1 getInstance() {
9 return single;
10 }
11 }
(2)懒汉模式://懒汉式单例类.在第一次调用的时候实例化
2 public class Singleton2 {
3 //私有的默认构造子
4 private Singleton2() {}
5 //注意,这里没有final
6 private static Singleton2 single=null;
7 //静态工厂方法
8 public synchronized static Singleton2 getInstance() {
9 if (single == null) {
10 single = new Singleton2();
11 }
12 return single;
13 }
14 }
(3)工厂模式:
interface IFactory{
public IProduct createProduct();}
Class Factory implements IFactory{
public IProduct createProduct(){return new Product();}}
Public class client{
Public Static void main (String [] args){IFactory factory=new Factory();
IProduct product=factory.createProduct();
product.ProductMethod();}}

  • **83、Java集合框架是什么?说出一些集合框架的优点? **

每种编程语言中都有集合,最初的Java版本包含几种集合类:Vector、Stack、HashTable和Array。随着集合的广泛使用,Java1.2提出了囊括所有集合接口、实现和算法的集合框架。在保证线程安全的情况下使用泛型和并发集合类,Java已经经历了很久。它还包括在Java并发包中,阻塞接口以及它们的实现。集合框架的部分优点如下:
(1)使用核心集合类降低开发成本,而非实现我们自己的集合类。
(2)随着使用经过严格测试的集合框架类,代码质量会得到提高。
(3)通过使用JDK附带的集合类,可以降低代码维护成本。
(4)复用性和可操作性。

  • **84、集合框架中的泛型有什么优点? **

Java1.5引入了泛型,所有的集合接口和实现都大量地使用它。泛型允许我们为集合提供一个可以容纳的对象类型,因此,如果你添加其它类型的任何元素,它会在编译时报错。这避免了在运行时出现ClassCastException,因为你将会在编译时得到报错信息。泛型也使得代码整洁,我们不需要使用显式转换和instanceOf操作符。它也给运行时带来好处,因为不会产生类型检查的字节码指令。

  • **85、Java集合框架的基础接口有哪些? **

Collection为集合层级的根接口。一个集合代表一组对象,这些对象即为它的元素。Java平台不提供这个接口任何直接的实现。## 标题 ##
Set是一个不能包含重复元素的集合。这个接口对数学集合抽象进行建模,被用来代表集合,就如一副牌。
List是一个有序集合,可以包含重复元素。你可以通过它的索引来访问任何元素。List更像长度动态变换的数组。
Map是一个将key映射到value的对象.一个Map不能包含重复的key:每个key最多只能映射一个value。
一些其它的接口有Queue、Dequeue、SortedSet、SortedMap和ListIterator。

  • **86、为何Collection不从Cloneable和Serializable接口继承? **

Collection接口指定一组对象,对象即为它的元素。如何维护这些元素由Collection的具体实现决定。例如,一些如List的Collection实现允许重复的元素,而其它的如Set就不允许。很多Collection实现有一个公有的clone方法。然而,把它放到集合的所有实现中也是没有意义的。这是因为Collection是一个抽象表现。重要的是实现。
当与具体实现打交道的时候,克隆或序列化的语义和含义才发挥作用。所以,具体实现应该决定如何对它进行克隆或序列化,或它是否可以被克隆或序列化。
在所有的实现中授权克隆和序列化,最终导致更少的灵活性和更多的限制。特定的实现应该决定它是否可以被克隆和序列化。

  • **87、为何Map接口不继承Collection接口? **

尽管Map接口和它的实现也是集合框架的一部分,但Map不是集合,集合也不是Map。因此,Map继承Collection毫无意义,反之亦然。
如果Map继承Collection接口,那么元素去哪儿?Map包含key-value对,它提供抽取key或value列表集合的方法,但是它不适合“一组对象”规范。

  • **88、什么是迭代器(Iterator)? **

Iterator接口提供了很多对集合元素进行迭代的方法。每一个集合类都包含了可以返回迭代器实例的迭代方法。迭代器可以在迭代的过程中删除底层集合的元素,但是不可以直接调用集合的remove(Object Obj)删除,可以通过迭代器的remove()方法删除。

  • **89、Iterator和ListIterator的区别是什么? **

下面列出了他们的区别:
Iterator可用来遍历Set和List集合,但是ListIterator只能用来遍历List。
Iterator对集合只能是前向遍历,ListIterator既可以前向也可以后向。
ListIterator实现了Iterator接口,并包含其他的功能,比如:增加元素,替换元素,获取前一个和后一个元素的索引,等等。

  • **90、快速失败(fail-fast)和安全失败(fail-safe)的区别是什么? **

快速失败:当你在迭代一个集合的时候,如果有另一个线程正在修改你正在访问的那个集合时,就会抛出一个ConcurrentModification异常。
在java.util包下的都是快速失败。
安全失败:你在迭代的时候会去底层集合做一个拷贝,所以你在修改上层集合的时候是不会受影响的,不会抛出ConcurrentModification异常。
在java.util.concurrent包下的全是安全失败的。

  • **91、Java中的HashMap的工作原理是什么? **

我们知道在Java中最常用的两种结构是数组和模拟指针(引用),几乎所有的数据结构都可以利用这两种来组合实现,HashMap也是如此。实际上HashMap是一个“链表散列”,如下是它数据结构:最左侧是一个数组,数组中的每一个元素都是一个链表,链表的每一个元素都是entry。
HashMap是基于hashing的原理,我们使用put(key, value)存储对象到HashMap中,使用get(key)从HashMap中获取对象。当我们给put()方法传递键和值时,我们先对键调用hashCode()方法,返回的hashCode用于找到bucket位置来储存Entry对象。

  • **92、当两个对象的hashcode相同会发生什么? **

因为hashcode相同,所以它们的bucket位置相同,‘碰撞’会发生。因为HashMap使用链表存储对象,这个Entry(包含有键值对的Map.Entry对象)会存储在链表中。

  • **93、如果两个键的hashcode相同,你如何获取值对象? **

当我们调用get()方法,HashMap会使用键对象的hashcode找到bucket位置,然后会调用keys.equals()方法去找到链表中正确的节点,最终找到要找的值对象。

  • **94、hashCode()和equals()方法有何重要性? **

HashMap使用Key对象的hashCode()和equals()方法去决定key-value对的索引。当我们试着从HashMap中获取值的时候,这些方法也会被用到。如果这些方法没有被正确地实现,在这种情况下,两个不同Key也许会产生相同的hashCode()和equals()输出,HashMap将会认为它们是相同的,然后覆盖它们,而非把它们存储到不同的地方。同样的,所有不允许存储重复数据的集合类都使用hashCode()和equals()去查找重复,所以正确实现它们非常重要。equals()和hashCode()的实现应该遵循以下规则:
(1)如果o1.equals(o2),那么o1.hashCode() == o2.hashCode()总是为true的。
(2)如果o1.hashCode() == o2.hashCode(),并不意味着o1.equals(o2)会为true。
具体可以参考 http://blog.csdn.net/javazejian/article/details/51348320

  • **95、如何决定选用HashMap还是TreeMap? **

对于在Map中插入、删除和定位元素这类操作,HashMap是最好的选择。然而,假如你需要对一个有序的key集合进行遍历,TreeMap是更好的选择。基于你的collection的大小,也许向HashMap中添加元素会更快,将map换为TreeMap进行有序key的遍历。

  • **96、ArrayList和Vector有何异同点? **
    ArrayList和Vector在很多时候都很类似。
    (1)两者都是基于索引的,内部由一个数组支持。
    (2)两者维护插入的顺序,我们可以根据插入顺序来获取元素。
    (3)ArrayList和Vector的迭代器实现都是fail-fast的。
    (4)ArrayList和Vector两者允许null值,也可以使用索引值对元素进行随机访问。
    以下是ArrayList和Vector的不同点。
    (1)Vector是同步的,而ArrayList不是。然而,如果你寻求在迭代的时候对列表进行改变,你应该使用CopyOnWriteArrayList。
    (2)ArrayList比Vector快,它因为有同步,不会过载。
    (3)ArrayList更加通用,因为我们可以使用Collections工具类轻易地获取同步列表和只读列表。
  • **97、Array和ArrayList有何区别?什么时候更适合用Array? **

Array可以容纳基本类型和对象,而ArrayList只能容纳对象。
Array是指定大小的,而ArrayList大小是固定的。
Array没有提供ArrayList那么多功能,比如addAll、removeAll和iterator等。尽管 ArrayList明显是更好的选择,但也有些时候Array比较好用。
(1)如果列表的大小已经指定,大部分情况下是存储和遍历它们。
(2)对于遍历基本数据类型,尽管Collections使用自动装箱来减轻编码任务,在指定大小的基本类型的列表上工作也会变得很慢。
(3)如果你要使用多维数组,使用[][]比List

  • **98、Switch能否用string做参数? **

在 Java 7 之前, switch 只能支持byte,short,char,int 或者其对应的封装类以及 Enum 类型。在JAVA 7中,String 支持被加上了。

  • **99、equals与==的区别: **

a.==是判断两个变量或实例是不是指向同一个内存空间 equals是判断两个变量或实例所指向的内存空间的值是不是相同;

  • **100、Object有哪些公用方法? **

a.方法equals测试的是两个对象是否相等
b.方法clone进行对象拷贝
c.方法getClass返回和当前对象相关的Class对象
d.方法notify,notifyall,wait都是用来对给定对象进行线程同步的

  • **101、Java的四种引用,强弱软虚,用到的场景 **

a.利用软引用和弱引用解决OOM问题:用一个HashMap来保存图片的路径和相应图片对象关联的软引用之间的映射关系,在内存不足时,JVM会自动回收这些缓存图片对象所占用的空间,从而有效地避免了OOM的问题
b.通过软可及对象重获方法实现Java对象的高速缓存:比如我们创建了一Employee的类,如果每次需要查询一个雇员的信息。哪怕是几秒中之前刚刚查询过的,都要重新构建一个实例,这是需要消耗很多时间的。我们可以通过软引用和 HashMap 的结合,先是保存引用方面:以软引用的方式对一个Employee对象的实例进行引用并保存该引用到HashMap 上,key 为此雇员的 id,value为这个对象的软引用,另一方面是取出引用,缓存中是否有该Employee实例的软引用,如果有,从软引用中取得。如果没有软引用,或者从软引用中得到的实例是null,重新构建一个实例,并保存对这个新建实例的软引用
c.强引用:如果一个对象具有强引用,它就不会被垃圾回收器回收。即使当前内存空间不足,JVM也不会回收它,而是抛出 OutOfMemoryError 错误,使程序异常终止。如果想中断强引用和某个对象之间的关联,可以显式地将引用赋值为null,这样一来的话,JVM在合适的时间就会回收该对象
d.软引用:在使用软引用时,如果内存的空间足够,软引用就能继续被使用,而不会被垃圾回收器回收,只有在内存不足时,软引用才会被垃圾回收器回收。
e.弱引用:具有弱引用的对象拥有的生命周期更短暂。因为当 JVM 进行垃圾回收,一旦发现弱引用对象,无论当前内存空间是否充足,都会将弱引用回收。不过由于垃圾回收器是一个优先级较低的线程,所以并不一定能迅速发现弱引用对象
f.虚引用:顾名思义,就是形同虚设,如果一个对象仅持有虚引用,那么它相当于没有引用,在任何时候都可能被垃圾回收器回收。
g.使用场景:

  • **102、Hashcode的作用,与 equal 有什么区别 **

a.同样用于鉴定2个对象是否相等的,java集合中有 list 和 set 两类,其中 set不允许元素重复实现,那个这个不允许重复实现的方法,如果用 equal 去比较的话,如果存在1000个元素,你 new 一个新的元素出来,需要去调用1000次 equal 去逐个和他们比较是否是同一个对象,这样会大大降低效率。hashcode实际上是返回对象的存储地址,如果这个位置上没有元素,就把元素直接存储在上面,如果这个位置上已经存在元素,这个时候才去调用equal方法与新元素进行比较,相同的话就不存了,散列到其他地址上

  • **103、抽象类和接口的区别 **

a.一个类只能继承单个类,但是可以实现多个接口
b.接口强调特定功能的实现,而抽象类强调所属关系
c.抽象类中的所有方法并不一定要是抽象的,你可以选择在抽象类中实现一些基本的方法。而接口要求所有的方法都必须是抽象的

  • **104、解析XML的几种方式的原理与特点:DOM、SAX、PULL **

a.DOM:消耗内存:先把xml文档都读到内存中,然后再用DOM API来访问树形结构,并获取数据。这个写起来很简单,但是很消耗内存。要是数据过大,手机不够牛逼,可能手机直接死机
b.SAX:解析效率高,占用内存少,基于事件驱动的:更加简单地说就是对文档进行顺序扫描,当扫描到文档(document)开始与结束、元素(element)开始与结束、文档(document)结束等地方时通知事件处理函数,由事件处理函数做相应动作,然后继续同样的扫描,直至文档结束。
c.SAX:与 SAX 类似,也是基于事件驱动,我们可以调用它的next()方法,来获取下一个解析事件(就是开始文档,结束文档,开始标签,结束标签),当处于某个元素时可以调用XmlPullParser的getAttributte()方法来获取属性的值,也可调用它的nextText()获取本节点的值。

  • **105、JAVA多态的实现原理 **

a.抽象的来讲,多态的意思就是同一消息可以根据发送对象的不同而采用多种不同的行为方式。(发送消息就是函数调用)
b.实现的原理是动态绑定,程序调用的方法在运行期才动态绑定,追溯源码可以发现,JVM 通过参数的自动转型来找到合适的办法。

  • **106、JAVA 垃圾回收机制 **

a.标记回收法:遍历对象图并且记录可到达的对象,以便删除不可到达的对象,一般使用单线程工作并且可能产生内存碎片
b.标记-压缩回收法:前期与第一种方法相同,只是多了一步,将所有的存活对象压缩到内存的一端,这样内存碎片就可以合成一大块可再利用的内存区域,提高了内存利用率
c.复制回收法:把现有内存空间分成两部分,gc运行时,它把可到达对象复制到另一半空间,再清空正在使用的空间的全部对象。这种方法适用于短生存期的对象,持续复制长生存期的对象则导致效率降低。
d.分代回收发:把内存空间分为两个或者多个域,如年轻代和老年代,年轻代的特点是对象会很快被回收,因此在年轻代使用效率比较高的算法。当一个对象经过几次回收后依然存活,对象就会被放入称为老年的内存空间,老年代则采取标记-压缩算法
e.引用计数(最简单古老的方法):指将资源(可以是对象、内存或磁盘空间等等)的被引用次数保存起来,当被引用次数变为零时就将其释放的过程
f.对象引用遍历(现在大多数 jvm 使用的方法):对象引用遍历从一组对象开始,沿着整个对象图上的每条链接,递归确定可到达(reachable)的对象。如果某对象不能从这些根对象的一个(至少一个)到达,则将它作为垃圾收集
g.什么是垃圾回收机:释放那些不再持有引用的对象的内存
h.怎么判断一个对象是否需要收集?
i.几种垃圾回收机制

  • **107、讲讲 Java 中的集合有多少种,区别是什么? **

a.HashTable比较老,是基于Dictionary 类实现的,HashTable 则是基于 Map接口实现的
b.HashTable 是线程安全的, HashMap 则是线程不安全的
c.HashMap可以让你将空值作为一个表的条目的key或value
d.ArrayList、LinkedList、Vector的区别:ArrayList 和Vector底层是采用数组方式存储数据,Vector由于使用了synchronized方法(线程安全)所以性能上比ArrayList要差,LinkedList使用双向链表实现存储,随机存取比较慢
e.HashMap的底层源码实现:当我们往HashMap中put元素的时候,先根据key的hashCode重新计算hash值,根据hash值得到这个元素在数组中的位置(即下标),如果数组该位置上已经存放有其他元素了,那么在这个位置上的元素将以链表的形式存放,新加入的放在链头,最先加入的放在链尾。如果数组该位置上没有元素,就直接将该元素放到此数组中的该位置上。
f.Fail-Fast机制:在使用迭代器的过程中有其他线程修改了map,那么将抛出ConcurrentModificationException,这就是所谓fail-fast机制。这一机制在源码中的实现是通过modCount域,modCount顾名思义就是修改次数,对HashMap内容的修改都将增加这个值,那么在迭代器初始化过程中会将这个值赋给迭代器的expectedModCount。在迭代过程中,判断modCount跟expectedModCount是否相等,如果不相等就表示已经有其他线程修改了Map.
g.HashMap和 HashTable 的区别。

  • **108、讲讲类的实例化顺序,比如父类静态数据,构造函数,字段,子类静态数据,构造函数,字段,当 new 的时候, 他们的执行顺序。 **

父类静态代变量、
父类静态代码块、
子类静态变量、
子类静态代码块、
父类非静态变量(父类实例成员变量)、
父类构造函数、
子类非静态变量(子类实例成员变量)、
子类构造函数。

  • **109、继承和聚合的区别在哪。 **

继承指的是一个类(称为子类、子类接口)继承另外一个类(称为父类、父接口)的功能,并可以增加它自己的新功能,继承是类与类或者接口之间最常见的关系。在java中此类关系通过关键字exetents明确标识,在设计时候一般没有争议性。

  • **110、什么是初始化数据块? **

初始化数据块——当创建对象或加载类时运行的代码。
有两种类型的初始化数据块:
静态初始化器:加载类时运行的的代码
实例初始化器:创建新对象时运行的代码

  • **111、什么是静态初始化器? **

请看下面的例子: static{ 和 } 之间的代码被称为静态初始化器。它只有在第一次加载类时运行。只有静态变量才可以在静态初始化器中进行访问。虽然创建了三个实例,但静态初始化器只运行一次。
public class InitializerExamples { static int count; int i; static{ //This is a static initializers. Run only when Class is first loaded. //Only static variables can be accessed System.out.println(“Static Initializer”); //i = 6;//COMPILER ERROR System.out.println("Count when Static Initializer is run is " + count); } public static void main(String[] args) { InitializerExamples example = new InitializerExamples(); InitializerExamples example2 = new InitializerExamples(); InitializerExamples example3 = new InitializerExamples(); }}
示例输出
Static InitializerCount when Static Initializer is run is 0.

  • **112、什么是正则表达式? **

正则表达式能让解析、扫描和分割字符串变得非常容易。Java中常用的正则表达式Patter,Matcher和Scanner类。

  • **113、什么是令牌化? **

令牌化是指在分隔符的基础上将一个字符串分割为若干个子字符串。例如,分隔符;分割字符串ac;bd;def;e为四个子字符串 ac , bd , def 和 e 。
分隔符自身也可以是一个常见正则表达式。
String.split(regex)函数将regex作为参数。
给出令牌化的例子?
private static void tokenize(String string,String regex) { String[] tokens = string.split(regex); System.out.println(Arrays.toString(tokens));}tokenize(“ac;bd;def;e”,";");//[ac, bd, def, e]
如何使用扫描器类(Scanner Class)令牌化?
private static void tokenizeUsingScanner(String string,String regex) { Scanner scanner = new Scanner(string); scanner.useDelimiter(regex); List matches = new ArrayList(); while(scanner.hasNext()){ matches.add(scanner.next()); } System.out.println(matches);}tokenizeUsingScanner(“ac;bd;def;e”,";");//[ac, bd, def, e]


java面试题想涨薪时使用相关推荐

  1. Java程序员跳槽涨薪面试心得

    面试候选人的时候,有个比较常见的问题:对于一份工作,你最关注哪些因素?回答往往是薪资待遇,公司氛围,公司发展前景,工作强度等.个人比较欣赏的答案是:个人能力的成长.想收获一个薪资好,公司发展前景好的工 ...

  2. 最近找工作,搜刮了一些Java面试题,涨涨知识

    Java 面试随着时间的改变而改变.在过去的日子里,当你知道 String 和 StringBuilder 的区别(String 类型和 StringBuffer 类型的主要性能区别其实在于 Stri ...

  3. 在职场想要涨薪升职,需要打造个人品牌

    凡是在职场打拼生存,都想涨薪升职,以获取更多更大的利益.每一个员工在老板眼中,都有各自的价值标签.   在每一张标签背后,是这个员工的业务能力.统筹能力.社会关系.个人影响.等,以及老板对他的评定. ...

  4. “花式提涨薪,结果被套路”,不懂怎么跟老板提加薪?这个方法真的很好用

    加薪想必是所有职场人的共同愿望,但大部分人想要向领导提出加薪时,都会遇到这些问题. 第一种人:想要加薪,但是却提都不敢提: 第二种人:想要加薪,但是却不知道怎么提: 第三种人:想要加薪,但是提了之后不 ...

  5. 2021年软件测试高薪就业秘诀:高薪工作地点+必修技能+涨薪技能

    随着"互联网+"的风靡,各行各业在数字化转型道路上,都增加了互联网技术人才的市场需求.对于求职者来说,这既是一种对个人实力的挑战,也是一次让职场人找到新出路的机遇. 作为IT行业中 ...

  6. java 多态判断非空_跳槽涨薪季面试题之java基础(一)

    点击上方[全栈开发者社区]→右上角[...]→[设为星标⭐] 为迎接金九银十跳槽涨薪季,小编汇总了java精编版面试题,大概从java基础.java8特性.多线程.spring.springboot. ...

  7. 看完涨薪2K+_____2019 JAVA 必刷面试题

    欢迎大家加入我的github项目,一起学习,一起发展 ---> 全栈工程师进阶学习站 ---> 我的前端学习笔记 --->行业内最新最群的报告,工作日每日更新 ->原生 js ...

  8. Java程序员千千万,想要涨薪的占一半,这篇读完,跳槽涨薪有希望了!

    前言: 虽然面试套路众多,但对于技术面试来说,主要还是考察一个人的技术能力和沟通能力.不同类型的面试官根据自身的理解问的问题也不尽相同,没有规律可循.有些面试官喜欢问自己擅长的问题,比如在实际编程中遇 ...

  9. 想跳槽涨薪的必看!2021年百度Java面试真题,跳槽大厂必看!

    前言 MyBatis是一个支持普通SQL查询.存储过程和高级映射的优秀持久层框架.MyBatis 去掉了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装.MyBatis可以使用简单的XML ...

最新文章

  1. 在做移动端开发的时候,一些应该知道的知识
  2. 托管exe文件的加载和执行
  3. 【原创】大叔案例分享(3)用户行为分析--见证scala的强大
  4. 如何用JavaScript判断dom是否有存在某class的值?
  5. JPA EntityManagers,事务及其周围的一切
  6. VOC数据集将XML转为对应的train.txt,trainval.txt,val.txt,test.txt
  7. Java多线程系列--“JUC锁”03之 公平锁(一)
  8. 云原生的本质_云原生2.0的逻辑之辩,如何让每个企业都成为新云原生企业
  9. 加速深度学习在线部署,TensorRT安装及使用教程
  10. DisplayMetircs 类
  11. 【ASP.NET 基础】ASP.NET 目录操作
  12. js获取本月第一天和最后一天
  13. c语言保龄球计分程序,保龄球规则-保龄球比赛计分方法是怎样的? 爱问知识人...
  14. 小米笔记本 wifi linux,被小米笔记本的WiFi坑了一道
  15. windows计算器(calc)按键功能详解
  16. 高级移动位置(AML)与紧急位置服务(ELS)
  17. 原型图 线框图_16个原型设计和线框图设计工具
  18. VHDL智力竞赛抢答器设计
  19. 内存整理工具 Memory Booster
  20. jitsi-meet 主持人退出会议后结束会议室(网页访问)

热门文章

  1. [转]nginx和php-fpm调用方式
  2. 商城系统架构以及流程
  3. 科威特国家银行将支持Ripple汇款服务
  4. 微信小程序行业生态白皮书
  5. 电脑连不上WIFI 显示地球图标
  6. [ACL22] SummaReranker (Ravaut et al, 2022) 阅读笔记
  7. 如何全面认知创客教育机器人
  8. python修改桌面壁纸_Python设置每日更新windows壁纸
  9. 送给所有程序员的浪漫
  10. Blender-镜像复制物体