某咨询公司面试
1: 接口,抽象类,类三者之间的关系:
(1)接口是一种规范,告诉外界这个东西可以做什么。可以继承多个接口
(2)抽象类是一种模板,告诉外界这个东西的一部分公共功能。只能继承一个抽象类。
(3)类与上述的最大区别是可以维护状态信息。
2: java 8 新的接口特性:
首先看旧的接口的特性:
(1)无构造函数,不能实例化。
(2)接口只能继承接口,不能继承类。
(3)接口里没有普通方法,方法全是抽象的。
(4)接口中的字段全是全局常量,默认修饰是public static final
新的接口的特性:
旧的接口如果有方法,所有实现类都要实现方法。新的接口可以有static 和default方法,可以有实现。子类可以覆盖接口的default方法。static方法属于类,所以在调用静态方法时,
不需要实现接口,也不需要接口的实例。
3: 新接口因为有default实现,就会有多重继承的问题
多级继承问题:A类实现了B接口和C接口,而B和C都提供了一个叫test的default方法,那么A类将实现哪个方法里的test方法?
解决办法:
(1)类实现的优先级高于接口的默认实现。
(2)类同时实现2个接口,2个接口包含相同的默认方法,那么这个类必须重写这个方
法,不然代码报错。
(3)通过使用super, 可以显示的引用被继承接口的默认实现,语法: InterfaceName.super.methodName().
4: java 8以前,interface接口中所有的方法都是抽象方法和厂里那个。而1.8可以定义带有方法体的方法。这样:一些不需要重写的方法我们就直接在接口中定义好。定义接口的时候: 用default和 static关键字修饰好;
注意:一个类需要实现多个接口,而不同的接口中有相同参数和default修饰的方法,这个时候,这个时候需要重写这个相同参数和default修饰的方法。
被static修饰的则不需要。
5: Lambda表达式
List<String> list = Arrays.asList("1","2","3","4"); Collections.sort(list, new Comparator<String>() { public int compare(String o1, String o2) { // TODO Auto-generated method stub return 0; }}); // sort函数的第2个参数是一个接口,这里要用一个借口的具体实现作为实参, Collections.sort(list, (String a, String b)-> {return 1;}); Collections.sort(list, (a, b) - >a.compareTo(b)); list.forEach(i-> { System.out.println(i); });
6: 函数式接口与静态导入
如上,每一个lambda表达式都对应一个类型,通常是接口类型。
“函数式接口”是指仅仅只包含一个抽象方法的接口,每一个该类型的lambda表达式都会被匹配到这个抽象方法。
因为默认方法不算抽象方法,所以你也可以给你的函数式接口添加默认方法。
我们可以将lambda表达式当作任意只包含一个抽象方法的接口类型,确保你的接口一定达到这个要求,你只需要给你的接口添加 @FunctionalInterface 注解,编译器如果发现你标注了这个注解的接口有多于一个抽象方法的时候会报错的。
7: 三个线程顺序执行:
t.join()方法阻塞调用此方法的线程(calling thread),直到线程t完成,此线程再继续;通常用于在main()主线程内,等待其它线程完成再结束main()主线程。
8:三个线程交替执行:
t1 先执行, 然后t2执行,t2执行完,main再退出。
package com.deppon.test04.test; import java.util.concurrent.TimeUnit; public class ThreadTest2 { public static void main(String[] args) { final Thread t1 = new Thread(new Runnable(){ public void run() { System.out.print("t1 begin \r\n"); try { TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.print("t1 end \r\n"); } }); Thread t2 = new Thread(new Runnable(){ public void run() { System.out.print("t2 begin \r\n"); try { t1.join(); } catch (InterruptedException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } System.out.print("t2 aaaaaaaaaaaaaa \r\n"); try { TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.print("t2 end \r\n"); } }); t1.start(); t2.start(); try { t2.join(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.print("main end"); } }