java面试常见问题

一、创建对象的4中方法:

1、new 关键字直接创建:

Student s=new Student();

2、class的反射调用(使用class的newInstanse方法可以调用无参构造器创建对象):

class.forName();

3、使用clone()来创建:

     try{
	            Student stu3 = (Student) stu1.clone();
	             System.out.println(stu3);
	}
	catch (CloneNotSupportedException e)
	{
	             e.printStackTrace();
	}

4、使用序列化(实现Serializable接口)

	public class Student implements Serializable{  }

二、线程不安全/安全的类

1、 不安全:

StringBuilder、HashMap、ArrayList、LinkedList

2、安全:

StringBuffer 、HashTable、Vector、stack(栈先进后出)

三、 HashTable和HashMap

Map 集合中不能包含重复的键 ,但可以包含重复的值
    
HashMap内部基于哈希表(数组)存储键值对(映射项)。
HashMap是线程不安全的。
HashMap根据键的哈希码值重新计算键值对(映射项)的在哈希表中的位置。
HashMap的key可以为null ,value 也可以为 null 。
HashMap的父类是 AbstractMap 。


Hashtable内部基于哈希表(数组)存储键值对(映射项)。
Hashtable是线程安全的 ( 所有的方法都被 synchronized 关键词所修饰 )。
Hashtable直接根据键的哈希码值确定键值对(映射项)的在哈希表中的位置。
Hashtable的key和value 都不能为null 。
Hashtable的父类是 Dictionary 类。
唯一不一样的是:HashTable为线程安全和key/value不可以为null值

四、ArrayList和LinkedList

ArrayList 内部借助于数组实现元素的存储。
ArrayList 是线程不安全的,相对于线程安全的Vector来说可能效率较高。
ArrayList 内部基于数组实现数据存储,因此随机访问效率较高。( 可以使用索引直接访问数组中的元素 )
ArrayList 内部基于数组实现数据存储,因此增删元素速度较慢。( 增删元素可能需要挪动数组中大量元素 )

LinkedList 内部基于链表实现元素的存储。
LinkedList是线程不安全的。
LinkedList内部基于链表实现数据存储,因此随机访问效率较低。( 需要逐个遍历链表中的结点 )
LinkedList内部基于链表实现数据存储,因此增删元素速度较快。( 增删元素只需要修改相邻两个节点的指针 )

五、Vector类和Stack类

 Vector 内部借助于数组实现元素的存储。
Vector是线程安全的,相对于线程不安全的ArrayList来说可能效率较低。
Vector内部基于数组实现数据存储,因此随机访问效率较高。( 可以使用索引直接访问数组中的元素 )
Vector内部基于数组实现数据存储,因此增删元素速度较慢。( 增删元素可能需要挪动数组中大量元素 )

Stack 类是 Vector 类的子类。

push 将元素压入栈顶
peek 检查栈顶元素(不弹出元素)
pop 弹出栈顶元素
search 从栈顶开始搜索元素( 基数从 1 开始 )
empty 判断当前栈是否为空

六、线程的五种状态:

1、	新建状态:new Thread();
2、	就绪状态:t.starts();等待获得CPU
3、	运行状态:获得CPU,实现run方法
4、	阻塞状态:执行了Thread.sleep方法、发生了IO操作、或者调用了同步锁的外套方法
5、	死亡状态:代码执行完毕。

sleep 和 yield 的区别:

1. sleep 不考虑线程优先级 ( 一个线程睡眠后其它线程都有机会获得CPU ),yield 要考虑线程优先级 ( 仅让位给 跟自己同等优先级或优先级比自己高的线程 )

2. sleep 可能抛出 InterruptedException ,而 yield 不会抛出异常

3. sleep 导致运行状态的线程进入到阻塞状态,而 yield 会导致运行状态的线程进入就绪状态

七、异常处理机制

    当程序发生异常时会产生一个代表该异常的对象
	                                                           
	同时当前程序会把这个异常对象交给运行时系统
	                                                           
	运行时系统根据接受到的异常对象寻找相应代码来处理该异常。

	处理异常的方式有两种,一种是 捕获异常 ,另外一种是 抛出异常。

八、受检查异常( checked-exception ) 和 运行时异常 ( runtime-exception ) 的区别

   1、运行时异常是指 直接 或 间接 继承了 java.lang.RuntimeException 类的那些 异常类,  而 受检查异常 是指从来都没有继承过 java.lang.RuntimeException 类的那些 异常类 。
	     
	2、对于受检查异常来说,必须在编译之前就显式书写异常的处理代码,
	可以是通过 try ... catch ... finally 语句捕获并处理异常,
	 也可以通过为 相应的方法 添加 throws 声明 来 声明抛出的异常类型。
	     
	3、对于运行时异常来说,在编译阶段可以不显式书写任何跟异常处理有关的代码。

受检查异常( checked-exception ) 和 运行时异常 ( runtime-exception ) 的相同点

1、都是异常( 都是 Exception 的子类型,不是 Error 的子类型 )
2、都可以被 捕获 ( try ... catch ... finally ) 或 抛出 ( throw )

九、十种常见的异常

     IOException
     FileNotFoundException
     RunnTimeException
     ArithmeticException
     lllegalArgumentException
     ArrayIndexOutOfBoundsException
	 NullPointerException
	 ArrayStoreException
	 ClassCastException
	 NumberFormatException

十、Mysql和ORACLE的区别

1、	Oracle是大型数据库而Mysql是中小型数据库 Mysql是开源的而Oracle价格非常高
2、	Oracle支持大并发,大访问量
3、	Oracle也Mysql操作上的一些区别
主键 Mysql一般使用自动增长类型,在创建表时只要指定表的主键为auto increment,插入记录时,不需要再指定该记录的主键值,Mysql将自动增长;   
Oracle没有自动增长类型,主键一般使用的序列,插入记录时将序列号的下一个值付给该字段即可;只是ORM框架是只要是native主键生成策略即可。
4、	    单引号的处理 MYSQL里可以用双引号包起字符串,
 ORACLE里只可以用单引号包起字符串。在插入和修改字符串前必须做单引号的替换:把所有出现的一个单引号替换成两个单引号。

十一、C和Java的区别

   JAVA是从可以算是从C++发展而来的,因此Java与C语言的语法比较类似的。
   C在使用完一块内存时,要手动释放内存;而java有内存自动回收机制
   C有指针,而java没有
   C是多线继承,而java是单继承
   Java有package的概念,C没有

十二、String、StringBuffer、StringBuilder的区别

    String:字符串常量,字符串长度不变,是被声明程final的,一次赋值不可改变
    StringBuffer:字符串变量,线程安全,如果需要频繁的对字符串内容进行修改,处于效率考虑最好使用StringBuffer;
    StringBuilder:字符串变量,非线程安全,与StringBuffer的区别是StringBuilder它是在单线程环境下使用的,所以效率要比StringBuffer

十三、集合和数组的区别

     数组的长度是固定的,而集合长度是可变的
	 数组值可以存储对象,还可以存储基本数据类型;而集合只能够只能存储对象
	 数组存储的数据类型是固定的,而集合存储的数据类型不固定

十四、int和Integer的区别

    Integer是int提供的封装类。int是基本数据类型中的一种。
    Integer的默认值是null。int的默认值是0
    Integer是一个对象,需要一个引用来指向这个对象,int是基本数据类型, 直接存储在内存中。
     声明为Integer的变量需要实例化,声明为int的变量不需要实例化。

十五、抽象类与接口的区别

      抽象类和接口都不能直接实例化
      接口是设计的结果 ,抽象类是重构的结果
 	  抽象类里可以没有抽象方法
      如果一个类里有抽象方法,那么这个类只能是抽象类
抽象类可以有具体的方法 和属性,  接口只能有抽象方法和不可变常量

十六、单列的特点和作用
特点:

      单例类确保自己只有一个实例。
      单例类必须自己创建自己的实例。
      单例类必须为其他对象提供唯一的实例
     作用:
       控制资源的使用,通过线程同步来控制资源的并发访问;
	   控制实例产生的数量,达到节约资源的目的。
       作为通信媒介使用,也就是数据共享,它可以在不建立直接关联的条件下,让多个不相关的两个线程或者进程之间实现通信

十七、数据结构中的栈和队列的区别

栈:后进先出
队列:先进先出
Queue:先进先出

十八、this、super、static、final、instanceOf关键字

This:

是当前类的实例,经常出现在方法和构造方法中,具体使用有以下三种情况:
       
	1、	返回调用当前方法的对象的引用;
	2、	在构造方法中调用当前类中的其他构造方法;
	3、	在方法参数名和成员变量名相同时,用于区分参数名和成员变量名。

Super:

this用于调用当前类的方法、属性和构造方法 ,而super调用父类的实例,super用于调用父类的方法、属性和构造方法,具体使用方法有以下两种:
	
	1、	调用父类的构造方法;
	2、	调用父类的实行和方法

Static:

 static关键字可以修饰方法、属性、自由块和静态块,使用static修饰这些成员时,可以理解为成员与类相关,通过 类名.成员 的形式调用;
 没有使用static修饰可以理解为成员与对象相关,通过  对象名.成员 的形式调用 

注意:

1static不能用于修饰构造方法;
2、	在static修饰的方法中,不能调用没有static修饰的方法和属性,也不能使用superthis关键字;
3、	被static 修饰的属性被多个类对象共享,一个对象修改静态属性值后,会影响其他对象;
4、	静态块无论对象创建几次,静态块只执行一次;

Final:用于修饰类、成员变量、成员方法

1final修饰的类:
该类不能被继承;
2final修饰的成员变量:
不能改变变量的值,即final修饰的类为常量;
3final修饰的成员方法:
该方法不能被子类重写

InstanceOf:属于Java的二元操作符,作用是判断某个对象是否某个类或接口类型。

十九、数据结构

char采用Unicode编码,因此可以直接和基本数据类型加减乘除

二十、double和float精度不准的问题:

 通过java.math.BigDecimal可以解决

 float s=2.12;语法错误

二十一、成员变量和局部变量有什么区别

  局部变量是定义在方法体内部的变量,其作用域在方法块内部有效。
  局部变量在使用时,必须先初始化才能使用,否则不能顺理通过编译;
  成员变量是定义的变了里那个,即属性,其作用域整个类中有效;
  成员变量可以不指定初始值,系统有默认值:除了八种基本数据类型,
  其他的引用类型都是null;
  Byte、Short、int的初始值为0long的初始值为0L;booleanfalsefloat的为0.0F;double的为0.0d;char为‘/u0000’;final修饰且没有被static修饰的成员变量必须显式赋初始值;

成员变量和局部变量的区别:

1public、protect、privatestatic可以修饰成员变量,但不能修饰局
部变量;两者都可以用final修饰;
2、	成员变量存储在堆内存中,局部变量存储在栈内存中
3、	作用域不同,局部变量作用域在方法块内部,成员变量作用域整个类
4、	成员变量可以不设置默认值,局部变量必须设置默认值。

二十二、==和equals的区别

   ==用于判断两个变量的值是否相等,或者两个变量的引用地址是否相等
   equals用于判断变量的引用地址 指向的存储内容是否相等    

二十三、类、对象、属性和方法

类是对一类相同事物的抽象描述;
对象是类的一个具体体现;
属性是对一类相同特征的抽象;
方法是对一类相同行为的抽象。

二十四、抽象类、接口

抽象类:

abstract修饰,允许包含未实现方法的类叫抽象类;

抽象类的特征:

1、	抽象类中可以包含抽象方法也可以不包含抽象方法;
2、	抽象类不能实例化,既不能创建对象,只能作为父类被子类继承;
3、	子类继承一个抽象类后,必须实现父类中所有的抽象方法,
不然子类也要定义成抽象类;
4、	如果类中包含抽象类,那么此类必须定义成抽象类;
5、	类只能单继承。

接口:

接口是方法声明和常量定义的集合;

接口特征

1、	接口只包含方法的声明和常量的定义;即使定义普通属性,该属性也
会编译成常量来实现;
2、	当其他方法实现该接口时,必须实现该接口定义的所有方法,否则应
该将该类定义为抽象类;
3、	一个类可以实现多个接口;(implement);
4、	定义接口时允许使用继承,接口允许多继承。

类和借口的区别:

相同点:

1、	都可以有抽象方法;
2、	都不能被实例化;
3、	都可以包含static方法( 从 JDK 1.8 开始,允许在接口中声明 static 方法 )

不同点:

1、	抽象类有构造方法,接口没有;
2、	抽象类可以有代码块、普通字段(不是常量的字段),而接口中不允许有代码
块 和 普通字段 ( 接口中所有的字段都是 public static final 修饰 )
3、	抽象类只能继承一个直接父类 (单继承 x ) ,接口可以继承多个父
接口 ( 多继承 x )  
4、	抽象类的子类通过 extends 关键字继承抽象类后可以实现抽象类中的抽象
方法,接口的实现类通过 implements 关键字实现接口并实现其中的抽象方法  
5、	JDK 1.8 开始允许在接口中声明 default 修饰的方法,而 抽象类中的方法 不能
用 default 修饰。

二十五、多态、继承、封装
多态:

1、Java中主要指对象变量的多态;	
	2、在Java语言中有两种形式的多态: 编译时多态、运行时多态;
3、编译时多态通过方法重载(overload)来实现,即同一个类中存在多个方法名称相
同但参数列表(参数个数、类型、顺序)不相同的方法;
4、运行时多态通过方法重写(override)来实现,当子类继承父类后重写父类中的可见
(visible)方法,在运行阶段由父类类型的引用指向了子类类型的对象,此时 父类引用
指向哪个子类类型的对象,就调用哪个子类重写后的方法(就是表现谁的形态)

继承:

1、	是指一个对象直接使用另一对象的属性和方法;
2、	Java语言中通过 extends 实现类与类、接口与接口之间的继承,从而实现代码
复用,也是实现多态的基础。

封装:

1、通常将字段私有化(被隐藏起来)、某些不需要在类外部调用的方法也可以隐藏
起来,尽可能隐藏类的实现细节,
  
3、	将外部可能调用的方法公开。

二十六、内部类

定义在一个类内部的类叫做内部类;

内部类的优点:
1、内部类的对象能访问所处类的私有属性和方法;
2、内部类可以隐藏起起来,不被同一个包的其他类访问;
3、内部类可以声明为抽象类,被其他内部类继承,也可以声明为final4、内部类可以声明为private、protect;
5、内部类可以用static修饰;

二十七、overload和override的区别:

Overload(重载):
1、是同一个类中含有多个方法名称相同但参数列表(参数个数、类型、顺序)不相同的方法,
2、这些方法可能是当前类直接声明的,也可能是从父类中继承过来的可见方法。

Override(重写)
1、重写必须是子类继承父类后,子类重新声明了从父类中继承的可见(visible)方法,
2、此时,如果子类中重新声明的方法与父类中的方法 名称相同、参数列表完全相同、返回类型也一致,就说子类重写了父类中的同名方法。

相同点:都要求方法名称相同;

不同点:
1、	重载要求本类中有同名不同那个参的方法;重写必须发生在子类和父类之间;
2、	重载 要求同名方法的参数列表一定不相同;重写要求子类和父类的同名方法
的参数列表完全相同;
3、	重载对返回类型么有要求;而 重写 ( override ) 要求 被重写后的方法的返回
类型 必须跟 父类中相应方法保持一致 ( 如果是返回基本类型,则要求完全相同 )
4、	重载( overload ) 对方法的  权限修饰符 没有要求,而 重写 ( override ) 要求 
被重写后的方法的 权限修饰符 的范围不能缩小

注意:  

子类不能重写父类的 静态方法,如果子类重新声明了父类中同名的静态方法,
则说 子类 隐藏 了 父类中的同名静态方法。

你可能感兴趣的:(java,java)