2018-01-03

Java面试之前复习总结(一)

时间在一分一秒的过去,面临求职面试也是越来越近了,在看面试题以及牛客网做题时,遇到了很多不理解或者之前没见过的,就把他总结下来了,发个博客,大家共勉,之后会持续更新。

1、String类都有那些常用的方法。

length(); split(); replace();

equals(); subString(); charAt();

concat(); 大小写转换; indexOf();

trim(); isEmpty(); contains();

startWith()

补充:Object类方法

clone、 equals finalize getClass

hashCode notify notifyAll toString

wait

补充:异常分类

算数异常 类型转换异常 非法参数异常

下标越界异常 空指针异常 安全性检查异常

need-to-insert-img


need-to-insert-img

2、StringBuilder和StringBuffer区别

根本区别就是StringBuilder是线程不安全的,而StringBuffer是线程安全的。

速度,StringBuilder > StringBuffer > String

String是不可变的,其他两个是可变的

按照性能排序 String(大姐,jdk1.0) < StringBuffer(二姐,jdk1.0)

StringBuffer很多方法都被synchronized修饰了,而StringBuilder没有,所以StringBuilder速度比StringBuffer快。建议用StringBuilder。

JVM运行程序主要时间都是浪费在创建对象和回收对象上。

eg:String s = “this is”+“only”“simple test”;等同于 String s = “this is only simple test”。


3、Map和List的遍历区别

List:增强的for循环(最差)、for(int i=0;i


List:对越arrayList、Vector遍历应该采用随机访问get

LinkedList:采用迭代器

关于Map能不能存储null情况

 keyvalue 

TreeMap不允许允许线程不安全

HashMap允许允许线程不安全

关于Map遍历的entrySet和keySet

推荐使用entrySet,说明,keySet其实是遍历了两次,一次转化为Iterator对象,另一次是从HashMap中取出key所对应的value,而entrySet只遍历了一次就把他key和value全部都存到entry中了,效率更高。

need-to-insert-img

Set代表无序,不重复,Map代表key-value组成的集合,Map的key要求是不能重复,没有顺序,把Map的所有key组合起来就是Set。


4、数组与List区别

ArrayList的底层实现还是数组,索引速度快。

LinkedList:是基于链表。

对于随机访问,get set ArrayList优秀。

对于新增和删除,LinkedList优秀

5、Set和List区别

根本:Set 无序,不重复。 List:有序,元素可重复


Java遍历List

第一种:   

for(Iterator it = list.iterator(); it.hasNext();) {     

    ......  

}  

这种方式在循环执行过程中会进行数据锁定,    性能稍差,    同时,如果你想在循环过程中去掉某个元素,只能调用it.remove方法, 不能使用list.remove方法,  否则一定出并发访问的错误.   


第二种:

for(A a : list) {  

    ......  

}  

它内部还是调用第一种,    换汤不换药,    这种循环方式还有其他限制,    不建议使用它   


第三种:   

for(int i = 0; i < list.size(); i++) {  

    A a = list.get(i);  

    ......  

}  

它内部不做锁定,    效率最高,    但是当写多线程时要考虑并发操作的问题!  


注:TreeMap和HashMap,Hash底层采用数组来保存key和value


6、垃圾回收

System.gc();

Runtime.gc() 也就是 Runtime.getRuntime().gc();

7、反射机制

在Java运行环境中获取类的属性和方法,调用对象的任意一个方法,这种动态获取类的信息,以及动态动态调用对象的方法的功能,就叫做Java的反射机制。

8、Java的数据类型

need-to-insert-img

补充:关于float与double精度丢失问题

float:有效位是7位。

double:有效位16位

9、Java类加载机制

10、栈和链表有什么区别

栈:先进后出。

链表:随便什么地方都可以插入删除

11、Map、HashMap、LinkedHashMap存储结构以及实现原理

HashMap底层是用数组实现的。

Map中包括一个内部类Entry,封装了一个key-value

LinkedHashMap采用双向链表来维护元素关系,因为要维护元素顺序,所以性能略低于HashMap。

12、short s1 =1, s1 = s1 + 1 有错吗,shrot s1 = 1 , s1 +=1有错吗。

对于第一种,由于1是int型,因此s1 + 1 运算是int型,需要强制类型转化,

而第二种相当于 s1 = (short)(s1 + 1)其中隐含了强制类型转化。

13、Integer 和int区别。

注意:就是涉及到自动装箱。

Integer a1 = new Integer(3);

Integer a2 = 3;

System.out.println(a1 == a2); //false 如果a2是int型,就是true


Integer a = 15;

Integer b = 15;

Integer c = 129;

Integer d = 128;

System.out.println(a == b); //true

System.out.println(c ==d ); //false

注:如果整形字面的量值在-128 ~128之间,那么不new对象,而是引用常量池中的Integer对象。

访问控制符

类成员:private、default、protected、public

修饰类:public、final、abstract

修饰方法:public、默认、protected、private、|static、find、abstract

修饰变量:public、默认、protected、private、|static、find

类型private无protectedpublic

同一类√√√√

同一包中子类 √√√

同一包非子类 √√√

不同包子类  √√

不同包非子类   √


14、HashMap采用拉链法解决冲突(链地址法)

HashMap有两个参数影响性能,初始容量和加载因子(装填因子)。

链表法就是将相同hash值的对象组织成一个链表放在hash值对应的槽位中。

开放地址法是通过一个探测算法,当某个槽位已经被占据的情况下继续寻找下一个可以使用的槽位,很显然,HashMap解决冲突的方法是拉链法,也叫链地址法。


15、关于Java默认导入的包。

Java.lang,包含如下

Object:是所有类的父类。

基础类型包装类

数学类

String和StringBuilder

系统和运行时类:System.in 和out 是标准的输入类和输出类,System所有成员变量和方法都是静态的。

16、关于==和equals

==可用于基本类型和引用类型的比较,采用Integer比较,只要new,就不同。Integer.valueOf()和Integer a = 53,等价。切记Intger.valueOf()的源码,大于127都要new。


17、Java语言中数组复制的方法.

System.arrayCopy() > clone > Arrays.copyOf -> for循环赋值。(按性能排序)。

need-to-insert-img


关于clone方法:Java.lang.Object类的clone()方法,为protected类型,不可直接调用,需要先对要克隆的对象进行下列操作,首先被克隆的类应该实现Cloneable接口,然后在该类中覆盖clone方法,并且在该类中调用super.clone()方法。

need-to-insert-img


复制引用和赋值对象的区别。

复制引用:是指将某个对象的地址复制,所以复制后的对象副本的地址和源对象相同,这样,当改变副本的某个值后,源对象值也被改变;

复制对象:是将源对象整个复制,对象副本和源对象的地址并不相同,当改变副本的某个值后,源对象值不会改变;

Cat cat1=new Cat("xiaohua",3);//源对象  

        System.out.println("源对象地址"+cat1);  

        //调用clone方法,复制对象  

        Cat cat2=(Cat)cat1.clone();  

        Cat cat3=(Cat)cat1;//复制引用  

        System.out.println("复制对象地址:"+cat2);  

        System.out.println("复制引用地址:"+cat3);

need-to-insert-img

可以看出,复制引用的对象和源对象地址相同,复制对象和源对象地址不同


18、关于静态代码块,代码块,构造方法的执行顺序.

父类静态代码块-》子类静态代码块-》父类构造代码块-》父类构造函数-》子类构造代码块-》子类构造函数。

注意:构造代码块和构造函数一起执行。

先执行静态初始化快,普通初始化快和午餐的构造函数一起i执行。

19、&& 和&

&&短路,如果&&左边位false,直接短路掉

&非短路。

20、return、break、和continue

return:直接退出循环

break:跳出本层循环

continue:跳过本次循环

补充:break只能用在循环语句中,while,do....while或者for 或者switch中

21、Math.round(11.5等于多少)

12.round其实就是四舍五入

注:关于四舍五入的方法



//第一种方法,使用DecimalFormat来格式化数字。

String ss = new DecimalFormat("#.000").format(s);

System.out.println("DecimalFormat四舍五入: "+ ss);


//第二种方式,使用String.format

System.out.println("使用String.format:" + String.format("%.3f", s));


//第三种方式,使用技巧round 这种方式存在问题

System.out.println("使用技巧round:" + Math.round(s*1000)*0.001d);

//错误System.out.println("使用技巧round:" + Math.round(s*1000*0.001d));


//第四种方式

BigDecimal big = new BigDecimal(s);

double d = big.setScale(3, BigDecimal.ROUND_HALF_EVEN).doubleValue();

System.out.println("第四种方式获取:" + d);

System.out.println(big.setScale(3, BigDecimal.ROUND_HALF_UP));


22、switch是否作用于byte上,是否作用long,是否String

Java5之前,switch(expr)。expr只能是byte,short,int,char

Java5之后,enum,

Java7,String

long,目前还不支持

23、数组有没有length()方法,String有没有length属性?

数组有length属性,String有length方法。

24、构造器不能被继承,所以不能被重写,但课重载,

25、为什么不能通过返回值类型区分重载

例如 int f(),void f(),在方法调用时可以省略类型f(),这时系统怎么处理?会找不到,会迷糊,所以,通过返回值区分重载行不通。

26、String s = new String("xyz"),创建了几个对象。

创建了两个对象,一个是静态区的。

27、Java中的final关键字有那些用法,

修饰类,表示该类不能被继承。

修饰方法

修饰变量

28、关于字符编码转换,就是利用String的构造方法和普通方法。

String a = "你好";

String b = new String(a.getBytes("gb2312"),"ISO-8859-1");

System.out.println(b);


String c = new String(a,"gbk").getBytes("utf-8");//第二种

29、TreeMap和TreeSet在排序时,如何比较元素,Collection中的sort()方法如何比较元素,

TreeSet要求所有存放对象必须实现Comparable接口,该接口提供compareTo()方法,

TreeMap要求存放的键值对映射的建必须实现Compareable接口,从而根据建进行排序。

Collection.sort()有两种排序方式:

传入的对象实现了Comparable

不强制要求传入元素必须课比较,但如要传入第二个参数,参数时实现Comparable接口的子类型,相关于临时定义了一个排序规则。

关于comparable(java.lang)和compartor(java.util)

list列表中所有元素必须实现Comparable接口,实现Comparable需要重写comparTo方法。

使用Comparable有很大局限性,实现此接口只能按compareTo(T t)定义的方法。

一个类的兑现更要实现多种排序方式,可以为该接口定义不同的比较器,实现comparator接口

附:compartor与comparable区别:comparator接口与Comparable接口的区别

补充:线程和进程的区别

进行是执行着的应用程序,而线程是进程内部的一个执行序列,一个进程可以又多个线程,

线程同步:

使用lock与使用同步方法有点类似,只是使用lock时显示使用lock对象作为同步锁,而使用同步方式时系统隐世使用当前对象作为同步监视器。而使用lock对象时,每个lock对象对应一个Account对象,一样可以保证对于同一个Account对象,同一时间只能又一个线程进入临界区。

30、关于Thread类的sleep方法和对象(Object)的wait方法。

Thread.sleep() Object.wait()

调用了sleep时线程类休眠的静态方法,调用此方法会让当前线程暂停执行指定事件,将执行机会(CPU)让给其他线程,但对象的锁依然保持,因此休眠结束后自动恢复。

wait是Object的方法,调用wait方法导致当前线程放弃对象所进入线程池,只有调用对象的notify()方法,才能被重新唤醒。

31、创建线程的三种方法。

继承Thread

实现Runnable

使用Callable和FUTURE(2、3实现方式相同,所以归结到一类)

推荐采用实现Runnable接口,Callable接口来创建线程,因为如果是继承,就浪费了一次继承的机会,导致无法再继承其他的类,而接口不一样。

32、状态

线程是进行内的并发,没有自己的内存空间,共享进程的。

线程的四种状态:就绪,执行,挂起。结束

need-to-insert-img

join:等待另一个线程完成

Sleep()之后线程进入阻塞状态,然后进入就绪状态,

wait()之后线程进入等待队列,等待唤醒进入就绪状态。

yield执行后线程进入就绪状态(直接进入就绪状态,不进入阻塞)

join执行后线程进入阻塞状态

need-to-insert-img

need-to-insert-img

sleep与yield

sleep()方法暂停后,会给其他线程机会,不会理会优先级,

sleep()方法会将线程转入阻塞状态,然后进入就绪状态,而yield()不会将线程转入阻塞,只是i强制当前进程进入就绪,因此完全有可能某个线程调用yield()方法暂停后,立即再次获得处理器资源执行

sleep()方法抛出一个InterruptedExecption异常。

sleep(0放比yield()方法具有更好的一致性,通常不建议使用yield()方法来控制并发线程执行。

线程相关:

1、关键字synchronized 、static、abstract、final

synchronized:用于方法或代码块前,使此方法或者代码块编程同步的。

static:用于声明静态变量,static关键字可以修饰变量,方法,静态代码块。

                          静态变量:

                                          由static修饰的变量称为静态变量

                                          静态变量属于类,而不属于某个对象

                                          静态变量它的副本只有一个(静态变量在类中只加载一)

                         静态方法:

                                          在静态方法中只能调用静态变量和静态方法

                                          在非静态方法中,可以调用静态方法或者变量。

                                          在静态方法中不能使用this和super关键字。

                        静态代码块

                                          作用:用来给静态成员变量初始化

abstract:用于定义抽象类或者方法

final:用于声明常量,即只能赋一次值

volatile:用来确保将变量的跟新操作通知到其他线程,当把变量声明为volatile类型后,编译器与运行时都会注意到这个变量是共享的,因此不会将该变量上的操作与其他内存操作一起重排序。然而,在访问volatile变量时不会执行加锁操作,因此也就不会使执行线程阻塞,因此volatile变量是一种比 synchronized关键字更轻量级的同步机制。

serialize:Java 对象序列化为二进制文件

33、Java中如何实现序列化以及实现序列化的意义。

实现Serializable接口

意义:可以将硫化后的对象进行读写操作,也可用于网络之间对象传输,序列化是为了解决对象流读写坐坐时引发的问题。

34、xml文档有几种形式?本质?解析。

两种:dtd schema

schema本身也是一个xml文件,可以被xml解析,约束能力大于dtd

解析xml有两种:

dom:使用dom要预先加载整个文件适合随机访问,(空间换时间)

SAX:是事件驱动型,适合对xml顺序访问。

35、简述JDBC

加载驱动,Class.forName("com.mysql.jdbc.");

创建链接,Connention conn = DriverManager.getConnection("")

创建语句:PrepareStatement ps = conn.prepareStatement("");

执行语句:ResultSet rs = ps.executeQuery()

处理结果

关闭资源

36、事务的ACID:原子性,一致性,隔离性,持久性

脏读:A事务读取B事务尚未提交的数据,并再次基础上操作,而B事务执行回滚,那么A事务读到的数据就是脏数据。

不可重复读:A事务重新读取前面读取过的数据,发现该数据已经被另一个已提交的事务B修改了。

幻读:

37、获取一个对象

A.class()

a.getClass()

Class.forName()

38、Arrays.toString(int[]),Arrays工具类的头String方法。

首先检查是否为空,如果为空就return "[]",否则,StringBuilder,先append一个"[",然后循环,append一个数,if 到结尾 return appent ”]“,否则append(",")

39、类变量是指用satic修饰的属性,

40、在子类构造方法中使用super(),显示调用父类的构造方法,super()必须卸载子类构造方法第一行,否则不通过。

41、Java是一次编写多出运行,c++是一次编写多处编译

42、新生代,老年代,持久代

43、LinkedList实现了List,而不是继承,AbstractSet实现了Set

44、StringBuilder通过调用toString()方法转换为String型。

45、override重写,overloadding重载。

重写是子类重新定义了父类的方法,重写必有相同的方法名,参数列表和返回值类型。

重载是发生在同一个类里面的两个或多个方法名相同,但参数不同的情况

46、什么是java虚拟机,为什么java被称为平台无关语言,

Java虚拟机是一个可执行Java字节码的虚拟机进程,Java源文件被编译成能被Java虚拟机执行的字节码文件。

47、关于抽象类和接口,区别和共同点。

接口中的方法都是抽象的,而抽象类则可以同时包含抽象和非抽象方法。

类可以实现多个接口,但只能继承一个抽象类。

类可以不实现抽象类和接口中声明的方法,当然在这种情况下类也必须是抽象的。

抽象类可以在比提供接口实现的情况下实现接口。

接口中声明的变量默认都是final的,抽象类可以包含非final的

接口中的成员函数默认都是public的,抽象类的成员函数可以是private、protected或者public

接口是绝对抽象的,不可以被实例化,抽象类也是不可以被实例化的

48、Iterator,ListIterator

Iterator可以遍历set和list集合,但是ListInterator只能用来遍历List

Itertator只能向前遍历,ListIterator既可以向前也可以向后,

ListIterator实现了Iterator接口。

49、快速失败和安全失败的区别是什么

Java.util都是快速失败,

Java.util.conncurrent包瞎所有类都是安全失败的。

快速失败会抛出ConncurrentModificationException异常,而安全失败永远不会抛出这样的异常。

50、Java中HashMap的工作原理。

Java中HashMap以键值对形式存储元素,HashMap需要一个hash函数,它使用hashCode()和equals()方法向集合添加元素,当调用put()方法时,HashMap会计算key的hash值。

HashMap的一些重要的特性是它的容量、负载因子和扩容极限。

你可能感兴趣的:(2018-01-03)