常见面试题

常见面试题,第1张

常见面试题 Java基础  1.Java中内存管理及各区域内存储数据的生命周期?

JVM会将申请到的内存从逻辑上划分为三个区域:堆、栈、方法区。这三个区域分别用于存储不同的数据。

堆:用于存储使用new关键字所创建的对象以及对象的属性成员变量。

栈:用于存储程序运行时在方法中声明的所有的局部变量。

方法区:用于存储静态资源,类的各种信息(包括方法)。

成员变量:

  1. 定义在类中,方法外;
  2. 由系统设定默认初始值,可以不显式初始化;
  3. 所在类被实例化后,存在堆中,对象被回收时,成员变量失效;
    局部变量:
  4. 定义在方法中;
  5. 没有默认值,必须自行设定初始值;
  6. 方法被调用时,存在栈中,方法调用结束时局部变量从栈中清除;
2.JVM堆内存的分代管理以及垃圾回收流程?

1.创建一个新对象,会把这个新对象的实例放在新生代的Eden区域,当Eden区空间不足,无法创建新的对象时会触发MinerGC进行清理

2.当经过一次MinorGC进行清理后Eden区还存活的一些对象会通过复制算法把它复制到Survivor区(存活区)的from 区(原to区).

3.Survivor区的两块区域是相同大小的两块区域,是可以互相交换的,交换以后form的叫to,to的叫from,交换的过程中会把其中一个的对象复制到另外一个,保证有一个是空的。

4.当原from区进行MinorGC清理后往原to区复制的时候,原to区复制一部分对象满了的情况下,会将原form区的剩余对象复制到老年代区域.

5.老年代区域没有可用空间时会触发Full GC,Full GC会扫描整个老年代区域将还存活的对象进行标记,然后把不存活的对象进行清除.

优点:空间内存活对象多的情况下,效率高.

缺点:直接回收不存活对象所

占用的内存空间,回收后造成整个空间不连贯,产生内存碎片.

3.面向对象三大特征及详细理解?

封装,继承,多态

封装:把描述一个对象的属性和行为封装成一个类,把具体的业务逻辑功能实现封装成一个方法,其次封装的意义还有效的保护属性通过访问修饰符私有化属性(成员变量),公有化方法.

继承:实现代码的复用,所有的子类所共有的行为和属性抽取为一个父类,所有的子类继承该类可具备父类的属性和行为,继承具有单一性和传递性.

多态:程序中定义的引用类型变量所指向的具体类型和调用具体的方法在编译期无法确定,而是在运行期才能确定该引用类型变量指向具体哪个对象而调用在哪个类中声明的方法.

多态的表现形式有强制类型转换,向上造型等,多态可分为行为多态和对象多态:

行为多态:同一个run(){}方法,不同的对象调用时会有不同的实现,猫调用时是跑,鱼调用时是游,鸟调用时是飞.

对象多态:同一个对象,可以被造型为不同的类型,比如同一个人对象,可以被造型为儿子,父亲,员工等.

4.重载(overload)与重写(override)的区别?  

Overload是重载的意思,Override是覆盖的意思,也就是重写。

重载Overload表示同一个类中可以有多个名称相同的方法,但这些方法的参数列表各不相同(即参数个数或类型不同)。

重写Override表示子类中的方法可以与父类中的某个方法的名称和参数完全相同,通过子类创建的实例对象调用这个方法时,将调用子类中的定义方法,这相当于把父类中定义的那个完全相同的方法给覆盖了,这也是面向对象编程的多态性的一种表现。

    4.1 重写的两同两小一大规则?

        重写要遵循"两同两小一大"原则:

        两同:1)方法名相同 2)参数列表相同

        两小: 1)子类方法的返回值类型小于或等于父类的

                 1.1)void时必须相等

                 1.2)基本类型时必须相等

        一大:子类访问权限大于父类

5.接口和抽象类区别?  

含有abstract修饰符的class即为抽象类,抽象类不能创建的实例对象。含有抽象方法的类必须定义为abstract class.

接口(interface)可以说成是一种特殊的抽象类,接口中的所有方法都必须是抽象的。接口中的方法定义默认为public abstract类型,接口中的成员变量类型默认为public static final。

下面比较一下两者的语法区别:

  1. 抽象类中可以有普通成员变量,接口中没有普通成员变量
  2. 抽象类中可以包含非抽象的普通方法,接口中的所有方法必须都是抽象的,不能有非抽象的普通方法。
  3. 抽象类中的抽象方法的访问类型可以是public,protected和(默认类型,虽然eclipse不报错,但也不行,默认类型子类不能继承),但接口中的抽象方法只能是public类型的,并且默认即为public abstract类型.
  4. 抽象类中可以包含静态方法,接口中JDK1.8之前不可以有不能包含静态方法和成员方法,JDK1.8之后可以包含.但成员方法必须使用default修饰
  5. 抽象类和接口中都可以包含静态成员变量,抽象类中的静态成员变量的访问类型可以任意,但接口中定义的变量只能是public static final类型,并且默认即为public static final类型。
  6. 一个类可以实现多个接口,用逗号隔开,但只能继承一个抽象类,接口不可以实现接口,但可以继承接口并且可以继承多个接口,用逗号隔开.
6.实例变量和静态变量的区别?

在语法定义上的区别:静态变量前要加static关键字,而实例变量前则不加。

在程序运行时的区别:实例变量属于某个对象的属性,必须创建了实例对象,其中的实例变量才会被分配空间,才能使用这个实例变量。

静态变量不属于某个实例对象,而是属于类,所以也称为类变量,只要程序加载了类的字节码,不用创建任何实例对象,静态变量就会被分配空间,静态变量就可以被使用了。

总之,实例变量必须创建对象后才可以通过这个对象来使用,静态变量则可以直接使用类名来引用。

7.八大基本类型及字节数和位数?

8.switch case是否支持byte,short和long,是否支持String?

在switch(expr1)中,expr1只能是一个整数表达式,整数表达式可以是int基本类型或Integer包装类型,由于byte,short,char都可以自动转换成int型,所以可以使用.

long类型由于不能自动转换成int类型,所以不能使用.

关于字符串类型,在JDK是1.7版本之前,swicth case中不可以使用字符串,但在JDK1.7之后是可以用字符串的,这是最新版本新加入的特性.

9.String中和Array中是否有length属性和length()方法?

数组没有length()这个方法,有length的属性.

String有length()这个方法.

集合没有length()方法,有size()方法.

10.==和equals的区别?

==比较基本数据类型时比较的时值是否相等,比较引用类型时比较的是对象的地址值是

否相同,也就是否是同一对象。

未重写的equals方法调用的是Object的方法,用法==一样,重写后的equals方法是用

于比较两个独立对象的内容是否相同,就好比去比较两个人的长相是否相同,它比较的

两个对象是独立的。

11.String str=new String("abc");创建了几个对象?
   再以上基础上又String str1=new String("abc");一共创建几个对象?

创建了两个对象,一个str引用指向堆内存中的String对象,另外一个则是String类有参构造方法中的直接量字符串对象,该字符串对象在字符串常量池中.

把创建的对象过程拆分成两部分就比较直观了:

String s="abc";

String str=new String(s);

延伸问题:

如果再执行一次String str1=new String("abc");此时共创建了几个对象?

上一次 *** 作创建了2个对象,这一次 *** 作创建了1个对象,一共3个.

因为在第一次常量池中已经有一个"abcdefg"字符串对象,第二个创建时并没有创建新的,而是拿过来直接用,只是创建了1个str1指向堆内存中的String对象,共3个.

12.String,StringBuffer,StringBulider的区别?

String类是final修饰的,该类所表示的字符串对象不可变,一旦发生改变即创建新对象, 当我们通过字面量,常量来初始化一个字符串时,JVM首先会从字符串的常量池(一个JVM内部维护的内存区域,用来保存已经创建过的字符串对象)中查询用来保存该字符串的对象是否存在,若存在则直接引用,若不存在则创建该字符串对象并存入常量池,然后引用它.

StringBuffer和StringBuilder是可变字符串对象,对字符串的修改 *** 作不会创建新对象,都是在原有对象基础上进行修改,内部有很多 *** 作字符串的方法,比如append()等.另外StringBuffer是线程安全的,同步处理的,性能稍慢;StringBuilder是非线程安全的,并发处理的,性能稍快。

13.怎么把ISO8859-1编码的字符串转换成GBK或者UTF-8的字符串?

String类有一个重载的构造方法:

 String(byte bytes[], String charsetName)

 第一个参数为一个byte数组,第二个参数为指定的字符集类型

14.Integer i 127;Integer i2=127;i1==i2结果为true还是false?
   Integer i3=Integer.valueOf(127);Integer i4=Integer.valueOf(127);
   i3==i4结果为true还是false?

Integer i3=Integer.valueOf(127);Integer i4=Integer.valueOf(127);
i3==i4结果为true还是false?
是引用类型取的地址值从Integer缓存区拿出来的 第一个是true 第二个是是fasle记住缓存区范围是-127~-128之间

15.List和Set以及Map他们的实现类有哪些?

List是可重复集合,Set是不可重复集合,这两个接口都实现了Collection父接口.

Map未继承Collection,而是独立的接口, Map是一种把键对象和值对象进行映射的集合,它的每一个元素都包含了一对键对象和值对象, Map中存储的数据是没有顺序的,其key是不能重复的,它的值是可以有重复的。

List的实现类有ArrayList, Vector和linkedList.

ArrayList和Vector内部是线性动态数组结构,在查询效率上会高很多,Vector是线程安全的,相比ArrayList线程不安全的,性能会稍慢一些.

linkedList:是双向链表的数据结构存储数据,在做查询时会按照序号索引数据进行前向或后向遍历,查询效率偏低,但插入数据时只需要记录本项的前后项即可,所以插入速度较快。

Set的实现类有HashSet和TreeSet;

HashSet: 内部是由哈希表(实际上是一个 HashMap 实例)支持的。它不保证 set元素的迭代顺序.

TreeSet: TreeSet使用元素的自然顺序对元素进行排序,或者根据创建 set 时提供的 Comparator 进行排序.

Map接口有三个实现类:Hashtable,HashMap,TreeMap,linkedHashMap

Hashtable: 内部存储的键值对是无序的是按照哈希算法进行排序,与HashMap最大的区别就是线程安全.键或者值不能为null,为null就会抛出空指针异常

HashMap: 内部存储的键值对是无序的是按照哈希算法进行排序,与Hashtable最大的区别就是非线程安全的,键或值可以为null

TreeMap: 基于红黑树(red-black tree)数据结构实现, 按 key 排序,默认的排序方式是升序.

linkedHashMap:有序的Map集合实现类,相当于一个栈,先put进去的最后出来,先进后出.

16.ArrayList和linkedList的区别?

List的实现类有ArrayList, Vector和linkedList。
ArrayList和Vector内部是线性动态数组结构,在查询效率上会高很多,Vector是线程安全的,相比ArrayList线程不安全的,性能会稍慢一些.
linkedList:是双向链表的数据结构存储数据,在做查询时会按照序号索引数据进行前向或后向遍历,查询效率偏低,但插入数据时只需要记录本项的前后项即可,所以插入速度较快。

17.HashMap和HashTable的区别?

1.HashMap: 内部存储的键值对是{无序、散列存放的}的是按照哈希算法进行排序,与Hashtable最大的区别就是非线程安全的,键或值可以为null

2.Hashtable: 内部存储的键值对是无序的是按照哈希算法进行排序,与HashMap最大的区别就是线程安全.键或者值不能为null,为null就会抛出空指针异常

18.HashMap内部存储数据的原理?

使用put方法向HashMap存储数据,key会计算出一个hashcode值,然后再使用hash算法,计算出一个地址值,如果这个地址值的桶中没有数据,就直接将value值存储再这里,如果已经有值,会使用equals方法,对地址值进行比较,如果地址值相同,就会将原先的value值替换掉,不相等,则将这个值挂载到原先值的后面,形成链表。产生链表会影响查询效率,所以被存入的键值对对象都会重写equals和hashcode方法,但链表不能完全避免,原因是可能存在巧合key不相同但HashCode值相同.

当调用get方法时传入key,key会计算出一个hashcode值,然后再使用hash算法,计算出一个地址值,,通过该地址找到元素后在调用equals方法来比较key是否存在,若存在则返回其value值。

19.创建线程有几种方式?有何区别?

1.继承Thread类重写run方法

2.实现Runnable接口重写run方法 

实现Runnable接口的好处:

1).java仅支持单继承,实现接口可以把继承的机会留给其他类,实现接口更灵活一些

2). 可以将线程与线程要执行的任务分离开减少耦合度

另外:一个线程仅需要一个实例时可以使用匿名内部类创建,这种方式有助于简化代码

 继承Thread类:

实现Runnable接口:

20.线程运行中的五种状态?

New(新建):当我们创建一个线程时该线程并没有纳入线程调度处于一个new状态。

Runnable(就绪):当调用线程的start方法后,该线程纳入线程调度的控制,其处于一个可运行状态,等待分配时间片段以并发运行。

Running(运行):当该线程被分配到时间片段后被CPU运行,该线程处于running状态。

Blocked(阻塞):当线程在运行过程中可能会出现阻塞现象,比如等待用户输入信息等。但阻塞状态不是百分百出现的,具体要看代码中是否有相关需求。

Dead(结束):当线程的任务全部运行完毕,或在运行过程中抛出了一个未捕获的异常,那么线程结束,等待GC回收.

当使用new线程创建完毕后调用start方法后线程进入就绪状态,线程调度系统将就绪状态的线程转为运行状态,遇到synchronized语句时,由运行状态转为阻塞,当该线程获得synchronized对象锁后,由阻塞状态转为运行,在这种情况下可以调用wait 方法转为挂起状态,当线程关联的代码执行完毕后,线程变为结束状态.

21.线程中synchronized的用法?

java中有一个关键字名为:synchronized,该关键字是同步锁,用于将某段代码变为同步 *** 作,从而解决线程并发安全问题.
用于将某段代码变为同步 *** 作,解决线程并发的问题
锁普通方法:是同步方法,上锁对象是this,同一对象访问时,需要等待顺序执行,如果创建两个对象,可以执行各自的同步方法,互不影响
锁静态方法:因为静态方法只有一份,所以上锁对象是类对象,必须等待顺序执行
锁代码块:为了缩小同步范围,提高多线程并发效率,上锁对象是this

优化?
就是从偏向级锁升级为轻量级锁在升级为重量级锁,不可回退;
咋区分轻量级锁和重量级锁?
会根据一个个对象头(英文:马克我的)进行判断,对象头的话他会去进行一个二进制进行一个判断他尾部的一个数字状态;

22.synchronized什么情况下是同步锁,什么情况下是互斥锁?
    多个线程     同一对象    同一个加锁的方法时,看到的上锁对象是同一个
    多个线程     同一对象    不同加锁方法时,       看到的上锁对象时同一个

23.什么是死锁?怎么解决死锁?

理解多线程死锁前先理解这个小故事:

假设有A、B、C、D四个人在一起吃饭,每个人左右各有一只筷子。所以,这其中要是有一个人想吃饭,他必须首先拿起左边的筷子,再拿起右边的筷子。现在,我们让所有的人同时开始吃饭。那么就很有可能出现这种情况。每个人都拿起了左边的筷子,或者每个人都拿起了右边的筷子,为了吃饭,他们现在都在等另外一只筷子。此时每个人都想吃饭,同时每个人都不想放弃自己已经得到的一那只筷子。所以,事实上大家都吃不了饭。

死锁: 就是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。

线程死锁可能发生在以下的情况:

        1)当两个线程相互调用Thread.join();

        2)当两个线程使用嵌套的同步块时,一个线程占用了另一个线程的必需的锁,互相等待时被阻塞,就有可能出现死锁。

死锁一般都是由于对共享资源的竞争所引起的。但对共享资源的竞争又不一定就会发生死锁,死锁的发生必需满足4个必要条件:

互斥: 所谓互斥就是进程在某一时间内独占资源。

等待/持有: 一个进程因请求资源而阻塞时,对已获得的资源保持不放。

非抢占: 进程已获得资源,在末使用完之前,不能强行剥夺。

形成等待环: 若干进程之间形成一种头尾相接的循环等待资源关系。

如何解决死锁:可以从死锁的四个条件去解决,只要破坏了一个必要条件,那么死锁问题就解决了,在java中使用多线程的时候一定要考虑是否有死锁的问题.

24.Exception和RuntimeException区别?
   throw和throws的区别?

1.继承Exception时自定义异常属于检查型异常,编译器会做检查,会主动提示抛出…
2.继承RuntimeException时自定义异常属于运行时异常,编译期不会检查,运行时会抛出相关异常.

throw和throws的区别?

throws:是用来声明一个方法可能抛出的所有异常信息,多个异常之间逗号隔开,写在方 法上, 通常不用显示的捕获异常,可由系统自动将所有捕获的异常信息抛给上级调用者.

throw:是指抛出的一个具体的异常类型,写在方法的内部, 需要用户自己捕获相关的异 常,而后在对其进行相关包装,最后在将包装后的异常信息抛出.

25.请说出五种以上常见运行时异常的名字以及产生的原因和解决方案?

ArrayIndexOutOfBoundsException:  数组下标越界异常。当对数组的下标为负数或大于等于数组大小时抛出。

ArithmeticException: 算术条件异常。如:整数除以零。

NullPointerException:空指针异常, 调用null对象的实例方法、访问null对象的属性、计算null对象的长度、使用throw语句抛出null等等.

ClassNotFoundException:  找不到类异常。根据字符串形式的类名在遍CLASSPAH之后找不到对应名称的class文件时,抛出该异常。

NegativeArraySizeException  数组长度为负异常

ArrayStoreException 数组中包含不兼容的值抛出的异常

SecurityException 安全性异常

IllegalArgumentException 非法参数异常

ClassCastException    类型转换异常类

ArrayStoreException  数组中包含不兼容的值抛出的异常

SQLException    *** 作数据库异常类

NoSuchFieldException   字段未找到异常

NoSuchMethodException   方法未找到抛出的异常

NumberFormatException    字符串转换为数字抛出的异常

StringIndexOutOfBoundsException 字符串索引超出范围抛出的异常

IllegalAccessException  不允许访问某类异常

  • IOException的子类:

IOException: *** 作输入流和输出流时可能出现的异常。

EOFException   文件已结束异常

FileNotFoundException   文件未找到异常

26.final,finalize,finally的区别?

使用final关键字修饰一个变量时,是指引用变量不能变,引用变量所指向的对象中的内容还是可以改变的,另外final修饰的方法不能被重写,修饰的类不可被继承,修饰的成员变量不可改变.

finalize:方法名
在垃圾回收器将内存中的没有引用指向的对象清空之前,调用finalize() 进行清理工作.

finally:异常处理中的程序块
在异常处理时,使用finally块来进行必要的清理工作,不论是否有异常发生,finally语句块中的语句都会被执行,如果发生了异常,则执行catch语句,再执行finally块.

27.什么是反射,怎么通过反射获取类对象,并且实例化该类对象,怎么获取类对象中属性和方法并执行方法?

反射是Java 动态执行机制,可以实现动态执行功能:

  1. 反射提供了在运行时判断任意一个对象所属的类型并可以检查解析类型的内部结构。
  2. 反射可以动态加载类型,并能够动态创建对象反射可以动态访问对象的属性。
  3. 反射可以动态执行对象的方法。
  4. 利用反射API还可以动态的访问,不可见的属性和方法,打破面向对象的封装性.

优点:可以动态执行!在运行期间根据业务功能动态执行方法、访问属性,最大限度发挥了java的灵活性。

缺点:对性能有影响,这类 *** 作总是慢于直接执行java代码。

JDBC中,利用反射动态加载了数据库驱动程序。

Web服务器中利用反射调用了Sevlet的服务方法。

很多框架用到反射机制,注入属性,调用方法,如Hibernate、Struts2、Spring等

CSS/JS 28.表单控件有哪些? 

表单是浏览器向服务器传送数据的手段,使用标签将表单元素及书写包裹在内.

有三个主要属性:

        action:表单提交的URL地址路径

        method: 表单的提交方式,默认为get请求方式,可设置为post请求方式.

        enctype:表单数据的编码方式

表单控件分为input元素和其他元素:

input元素:

        文本框:

        密码框:

        主要属性:value:用户输入的文本数据  maxlength:最大输入字符数  readonly:只读

        单选框:男性

                    女性

        复选框:篮球

                    足球

        主要属性:value:单/复选框文本    name:分组,一组单/复选框name属性必须相同checked:设置选中

按钮元素:

        提交按钮::自带表单提交效果

        重置按钮::重置表单内容

        普通按钮::普通按钮

        主要属性:value:按钮名字

隐藏框,文件选择框元素:

        隐藏框::一个用户看不到的框体

        文件框::选择要上传的文件

其他元素:

        文本域: