面向对象1. 讲讲你所理解的Java面向对象
字节跳动秋招
面向对象有三大特点:封装,继承和多态。五大基本原则是:单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则和接口隔离原则
所谓面向过程,就是在解决问题的时候,针对于某个过程,逐步分解成小问题,每个小问题我们使用函数实现即可
面向对象则是自底向上逐步抽象,抽象出相应的对象_(自然界的实体对象如桌子和非实体对象如课表),在对象中封装响应的数据结构(属性和行为),然后面向对象的设计方法(设计模式)_,遵循响应的设计原则,进而逐步向上完成一个大问题
2. 面向对象的特性讲下
腾讯19年秋招
面向对象的三大特性是封装,继承和多态
所谓封装就是按照面向对象的思路将问题进行建模抽象出数据结构然后封装成对象,同时封装也隐藏了数据。每层对象再不断向上封装,最终解决所求问题
所谓继承就是子类可以拥有父类的方法和属性。继承是多态的基础
多态是指同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果。多态需要有三个条件:派生类继承基类,派生类Override基类方法,基类引用指向派生类对象
项目中哪里用到了
这个题主要是说项目中用到了哪些面向对象的特性。譬如我们在写JavaEE的时候会在service包中有UserService和UserServiceImpl,这个即是继承。在我们的Spring项目中,我们往IOC中注入多个实现同一个接口的实例,最终通过接口来获取,这就用到了多态。同时设计模式中会有大量多态的例子,设计模式则是利用面向对象的特性来完成一系列任务的经验方法。所以这个问题我们可以转到设计模式上,后面会有细说
3. 简单说说面向对象的特征以及七大原则
华为19社招
面向对象特征:抽象,封装和多态。具体参考前两个题
常说的五种设计原则有:开闭原则_(对修改关闭,扩展开发,是总纲领),单一职责原则(类的设计,每个类负责单一的职责),接口隔离原则(接口的设计,接口要缩小不要混杂),里式替换原则(子类尽量不override父类方法),依赖倒置原则(面向抽象编程)_
有时候还会有其他两种原则:迪米特原则(实体之间尽量通过中间件达到少交互目的)和合成复用原则(少用继承,多用组合)
4. 编译时多态和运行时多态
七牛云19年秋招本科
维基百科上说多态分为静态多态和动态多态。子类override父类的方法则是动态多态,是在运行期确定,称为运行时多态;子类overload父类的方法则是静态多态,是在编译时确定,称为编译时多态,即在编译期通过参数就能确定调用哪个方法了
??override要求方法名,返回值,参数列表_(参数顺序,参数类型,参数个数)_必须相同,static,private,final不能被override。子类方法的异常签名不能多于父类,子类的访问权限不能低于父类??overload要求方法名相同,参数列表不同,返回值无要求,一个类也能overload
个人认为overload不属于多态,这个问题在StackOverflow等网站上有很多人讨论,但是并没有什么定论。不过概念只是一种工具,是不是多态其实无所谓
PS在一个类中,子类中的成员变量如果和父类中的成员变量同名,那么即使他们类型不一样,只要名字一样。父类中的成员变量都会被隐藏
5. 说一下多态的底层的原理
pdd19年秋招本科
??编译时多态和运行时多态??Jvm通过invokestatic和invokespecial调用实方法_(private, static,和父类方法)_,invokevirtual和invokeinterface来调用虚方法和final方法??对于运行时多态来说,会通过invokevirtual去到虚方法表根据槽号找到相应方法的实现(子类override时会使用和父类一样的槽号),如果找不到(即调用的是子类自己的方法),则再在子类中寻找
基础6. C# 和 Java 语言的区别和优劣
京东19年秋招
??C#和Java的泛型机制不一样??Java的跨平台比C#好??C#没有完全摆脱指针,通过unsafe操作
PS 没用过C#,别的不清楚
C 和Java
??C和Java的泛型在实现上不一样,C是真正实现了泛型,而Java只是一个语法糖??C 是编译型语言;Java是编译 解释(解释器 JIT)??C 是平台相关的;Java是平台无关的??C 对所有的数字类型有标准的范围限制,但字节长度是跟具体实现相关的,不同操作系统可能不同;Java在所有平台上对所有的基本类型都有标准的范围限制和字节长度??C除了一些比较少见的情况之外和C语言兼容;Java没有对任何之前的语言向前兼容。但在语法上受 C/C 的影响很大??C 允许直接调用本地的系统库;Java要通过JNI调用, 或者JNA??C 允许过程式程序设计和面向对象程序设计;Java必须使用面向对象的程序设计方式??C 支持指针,引用,传值调用 ;Java只有值传递??C 需要显式的内存管理,但有第三方的框架可以提供垃圾搜集的支持。支持析构函数;Java 是自动垃圾收集的。没有析构函数的概念??C 支持多重继承,包括虚拟继承 ;Java只允许单继承,需要多继承的情况要使用接口。
7. 抽象类和接口的区别
贝壳找房19年秋招本科,七牛云19年秋招本科
能不能用一个设计模式来说明
模板方法模式:通过抽象类封装不变的部分如模板方法和具体方法,易变的部分由子类实现如更改钩子,填充方法等等
8. int和Integer区别
贝壳找房19年秋招本科,联行科技19年秋招本科
int是Java的基本类型,但是为了更好的利用面向对象的特性,所以Java就为基本类型都延伸出了一种包装类,int的包装类就是Integer。
其中,int的默认值是0,Integer的默认值是null;
int不需要类加载器,Integer的类加载其实BootstrapClassLoader;
int类型的值存储在栈上,Integer的引用值在堆中;
int初始化不需要new但是Integer需要
下面代码有几次装拆箱
Integera=1000;//Integer.valueOf(1000);a ;//Integer.valueOf(a.intValue() )
所以在该程序中有两次装箱,一次拆箱
9. 讲一下Java的数据结构
字节跳动秋招,pdd19年实习
对于任何一种语言来说,底层的数据结构都是数组和链表;在这之上会抽象出map,栈和队列,树这些基础的数据结构
这个题基本问的是Collection和Map包下的整个集合框架,按照集合回答就没问题。可以参考我之前写的集合面试题
10. Java基本类型有多少种
阿里19年秋招,网易19年秋招本科
byte(1B,-128~127),short(2B),int(4B),long(8B),float(4B),double(8B),boolean,char(2B)
PS:定点数是指小数点位数不变,浮点数是指小数点位数会改变。
PPS:常见的字符集有ASCII和Unicode,编码方式有GBK,UTF-8/16等
11. 基本类型的比较用什么进行比较
网易19年秋招本科
基本类型一般使用==来比较
对象如何比较
对象比较一般通过hashCode和equals,参见第13题
12. final,finally,finalize的区别
华为19社招
??被final修饰的类不可以被继承;被final修饰的方法不可以被override;被final修饰的变量不可以被改变,且会被存放在常量池中??finally用于try catch后的最终执行,常用来关闭流_(在JDK7之后通过try-with-resource)_来关闭流。注意不要在finally中使用return。会覆盖的??finalize()是Object的一个方法,类似于析构函数,对象在即将GC的时候执行。这个方法建议不用
String为什么是final的
String是final主要是为了安全性,fianl类不能被继承,/JAVA_HOME/lib下的基础API好多参数都使用的String,倘若String可以继承,那么用户自己写的String类可能造成意想不到的安全问题,甚至成为漏洞;同时String因为不可变,在做HashMap的查询时效率会更高
13. Java中==、equals与hashCode的区别和联系
华为19社招
hashCode()主要是为了使用散列表时通过生成hash来定位。equals主要是用来重写来比较相同类的不同实例相同
在常见的hash容器中_(hashset,hashmap,hashtable)_,一般都是通过hashCode()进行定位比较,如果不同,则返回false,如果相同且equals相同的话,这两个对象才相同。比较两次的原因是因为第一次hashCode的效率比较高,第二次的equals比hashCode更准确
??hashcode相同,equals不一定为true,两个对象不一定相等??hashcode不同,equals一定为false,两个对象一定不相等??equals为true,hashcode一定相同,两个对象一定相等_(这里要求重写equals必须重写hashCode)_??equals为false,hashcode可能相同,两个对象不相等
14. Java 是引用传递还是值传递
pdd19年秋招本科,七牛云19年秋招本科
15. static关键字,final关键字
OPPO19年秋招本科
static修饰内部类时,只能访问父类中的静态字段;修饰普通字段或者方法时,类加载的时候已经初始化;静态代码块在类初始化时执行且只执行一次
fianl关键在参考第12题
16. 构造函数能不能继承
网易19年秋招本科
构造函数是不能继承的。譬如,我们知道Object类中一个控制构造方法,我们在子类中新建一个非空值的构造方法,同时new Sub();编译器是会报错的。但是我们可以通过super()来获得父类的构造方法
我们能在子类的构造方法中调用父类的构造方法(自动调用父类默认构造方法,或调用父类指定的构造方法,如果父类中只定义了有参数的构造方法,而在子类的构造方法中又没有用super()来调用父类中特定的构造方法,则编译时将发生错误),保证父类对象也进行初始化(子类继承父类对象数据得到初始化)
构造方法虽然不能override但是可以overload
16. 深克隆和浅克隆
七牛云19年秋招本科
17. 说下内部类
百度19年秋招
??内部类在JDK源码中经常看到,譬如说ConcurrentHashMap1.7的Segment,HashMap的Node等等均是使用内部类,使用内部类可以帮助更好的理解和编写健壮性的程序??静态内部类可以访问外部类的所有static成员; 非静态内部类则可以访问外部类的所有成员(方法,属性) ,不能有static成员??内部类在被编译后会变成两个类,Exb$Inner的形式,匿名内部类可以用lambda替换??内部类的static在类加载三部曲_(加载,链接,初始化)只是被加载,并没有初始化,因为没有真正使用,所以内部类也是现实单例模式的好方法(clint保证线程安全,懒汉式)_
19. 说下序列化
阿里19年秋招
序列化是将对象转换为可传输格式的过程。是一种数据的持久化手段。一般广泛应用于网络传输,RMI和RPC等场景中
??序列化和反序列可能会破坏单例模式。需要定义一个方法Object readResolve() {return singleton}。底层会查看如果有readResolve()方法,则把该方法的返回值作为反序列化完成的对象
1.在Java中,只要一个类实现了java.io.Serializable接口,那么它就可以被序列化。除此之外,Enum、Array和Serializable的子类都可以被序列化2.通过ObjectOutputStream和ObjectInputStream对对象进行序列化及反序列化3.虚拟机是否允许反序列化,不仅取决于类路径和功能代码是否一致,一个非常重要的一点是两个类的序列化 ID 是否一致(就是private static final long serialVersionUID)4.要想将父类对象也序列化,就需要让父类也实现Serializable接口5.Transient 关键字的作用是控制变量的序列化,在变量声明前加上该关键字,可以阻止该变量被序列化到文件中,在被反序列化后,transient 变量的值被设为初始值,如 int 型的是 0,对象型的是 null6.常用的集合会自定义writeObject和readObject方法_(在使用ObjectOutputStream的writeObject方法和ObjectInputStream的readObject方法时,会通过反射的方式调用 )_用来自定义序列化是为了使集合中的元素也被序列化起来,同时有transient关键字来修饰譬如Object[] elements是为了在序列化的时候节省空间7.两个接口??Serializable:序列化所有非 transient 属性??Externalizable:Serializable 子接口,有 writeExternal() 和 readExternal() 方法,用来指定需要序列化属性,如果为空,则没有要序列化的对象8.常用的序列化框架有java、kryo、hessian、protostuff、gson、fastjson
如果你已经将某个类的实例序列化到磁盘,这时候再往这个类添加新的属性,那么反序列化该对象的时候会发生什么
只要在类中定义了serialVersionUID,在类中新增属性不会导致序列化失败,新增的字段在反序列化后会为默认值,如null
如何保证序列化安全
??序列化可能会导致数据篡改,拒绝服务,命令执行等漏洞??对序列化对象通过TLS加密,对敏感数据使用transient,对序列化对象进行验证
20. 常用编码方式
ASCII(2B 48:0 65:A 97:a)
Unicode是一种编码标准,UTF-8/16/32是符合该标准的编码存储规则
UTF-8使用可变长度字节来储存 Unicode字符,例如ASCII字母继续使用1字节储存,重音文字、希腊字母或西里尔字母等使用2字节来储存,而常用的汉字就要使用3字节。辅助平面字符则使用4字节
GBK的文字编码是双字节来表示的,即不论中、英文字符均使用双字节来表示,只不过为区分中文,将其最高位都定成1,英文最高位为0
泛型21. 泛型作用和原理
用友19年秋招
注解和泛型都是在JDK1.5出现的新特性,泛型最主要的应用是在JDK 5中的新集合类框架中,最大的作用是提高代码的复用性。泛型中有类型擦除的概念,就是说java泛型只用于编译期间,编译完成擦除类型信息,在运行期间JVM只知道泛型所代表的类型。将多种泛型类形实例映射到唯一的字节码表示是通过类型擦除(type erasue)实现的
在Java语言中引入泛型是为了在编译时提供更严格的类型检查并支持泛型编程。为了实现泛型,Java编译器将类型擦除应用于:
1.如果类型参数是无界的,则将泛型类型中的所有类型参数替换为它们的界限或对象。因此,生成的字节码只包含普通类、接口和方法2.如果需要,插入类型强制类型转换以保护类型安全。生成桥接方法以保留扩展泛型类型中的多态性。类型擦除确保不会为参数化创建新类
Java的泛型属于Code sharing,而相对于C#和C 的泛型Code specialization来说,Java不同的泛型在运行期只有一份代码,而C#等有多个(会导致类型膨胀)
??泛型不可overload??泛型类的静态变量是共享的??尽量不要在新代码中使用原生态类型,使用泛型可以在编译期做出警告防止潜在的ClassCastException
泛型和数组协变有什么关系
所谓协变就是指A<B,则f(A) < f(B)
Java的泛型具有不变性,需要<? extend Sup>和<? super Sub>来支持协变,使用通配符时,需要注意PECS规则copy(List<? super T> dest,List<? extends T> src);其中,<? extends T>,取的话,一定能赋值给一个T类型,存的话,编译器并不知道具体会存哪种子类型,不安全,所以不让存,但是可以存null;<? super T>是T的某个超类型,所以往里面存任何一个T的子类型都是安全的,取的话,编译器不知道取出来的是具体哪个超类型,所以取出来只能赋值给一个Object类型
数组支持协变性是为了满足诸如Arrays.sort(Object[])这些方法的使用,在运行期才会产生异常
异常22. 异常和错误的区别,OOM是Error还是Exception
猪场19年实习
Exception和Error都继承了Throwable,实现了Serializable接口
??Error指出了一个合理的应用程序不应该试图捕捉的严重问题。大多数这样的错误都是不正常的情况。方法不需要在其抛出子句中声明在方法执行期间可能抛出但未捕获的任何错误子类,因为这些错误是不应该发生的异常情况。也就是说,错误及其子类被视为未检查异常??Exception表示一个合理的应用程序可能希望捕获的条件。Exception和任何不属于RuntimeException子类的子类都是受控异常。如果检查过的异常可以在方法或构造函数执行时抛出并传播到方法或构造函数边界之外,则需要在方法或构造函数的抛出子句中声明??换句话说,Error和RuntimeException_(如NPE)_是非受查异常。其他的叫受查异常,受查异常一定要经过catch后者throw处理;而非受查异常则没有这个要求,健壮的程序可以避免,同时不用在方法签名后显式throws
23. 如何处理异常
七牛云19年秋招本科
异常的处理方式有两种
1.自己处理。千万不能捕获了之后什么也不做。或者只是使用e.printStacktrace()。可以 记录日志、封装异常重新throw抛出、或者正常返回如return true2.向上抛,交给调用者处理
具体的处理方式的选择其实原则比较简明:自己明确的知道如何处理的,就要处理掉。不知道如何处理的,就交给调用者处理。
24. 说一下常见的异常
受查异常:IOExpection
非受查异常:
??StackOverFlowError, OutOfMemoryError??NullPointerException – 空指针引用异常??IndexOutOfBoundsException – 下标越界异常??ClassCastException – 类型强制转换异常??IllegalArgumentException – 传递非法参数异常??NumberFormatException – 数字格式异常??ArithmeticException – 算术运算异常??ArrayStoreException – 向数组中存放与声明类型不兼容对象异常??NegativeArraySizeException – 创建一个大小为负数的数组错误异常??SecurityException – 安全异常??UnsupportedOperationException – 不支持的操作异常??ConcurrentModificationException – 并发操作异常,常见数组中
反射25. 写一个反射的例子
滴滴19年秋招
项目中使用自定义注解的时候经常会通过反射来拿到注解
Class<?>clazz=bean.getClass();Method[]methods=clazz.getDeclaredMethods();for(Methodm:methods){if(m.isAnnotationPresent(MyAnno.class)){Stringvalue=m.getAnnotation(MyAnno.class).value();}}
反射在许多地方都能用到,如
1.JDK中的动态代理_(代理模式):静态代理是编译期完成,动态代理是运行期。但是JDK要求必须实现一个接口,增加了代码的植入性。动态代理还有cglib(通过asm实现)_,这个下一篇有说2.JDBC的class.forName通过反射来注册3.BeanUtils中属性值的拷贝4.RPC框架5.ORM框架6.Spring的IOC/DI
26. 说一下Java的反射
小米19年秋招本科, 滴滴19年秋招
??反射机制指的是程序在运行时能够获取自身的信息。在java中,只要给定类的名字,那么就可以通过反射机制来获得类的所有属性和方法,是Java成为一种动态语言。其中尤其是invokedynamic指令,使得Jvm能处理其他动态语言??反射提高了程序的灵活性和扩展性但是反射降低了代码的可读性低及可维护性,破坏了封装性,降低了执行性能??反射可以:1. 在运行时判断任意一个对象所属的类2. 在运行时判断任意一个类所具有的成员变量和方法3. 在运行时任意调用一个对象的方法4. 在运行时构造任意一个类的对象5. 通过反射对注解进行处理??java.lang.Class是反射的基础。每个类在类加载过程中进入方法区的时候都会创建一个相对应的class对象,该对象保存着相应类的信息,我们可以通过反射来操作。获取class可以通过instance.getClass();,Instance.class, Class.forName(“Instance”);
27. 反射生产的对象在jvm的哪里
阿里19年实习
个人所见,反射产生的对象也属于实例,只要是实例对象就会在堆中
会不会影响到永久代或者是元空间
不会影响,因为反射虽然能拿到private的数据,但是并没有改变private这个修饰符
网络和IO28. 创建socket的过程
滴滴19年秋招本科
对于NIO来说
1.server创建一个ServerSocketChannel,然后将端口绑定到其所创建的ServerSocket中2.通过Selector.open创建一个Selector,并将serverSocketChannel和其事件_(ACCEPT,CONNECT,READ,WRITE)_进行监听3.通过selector.select()阻塞方法获取监听事件成功的channel,然后通过迭代器遍历4.根据对应事件进行处理,处理成功并销毁
对于BIO来说
1.从server端开始说,首先创建一个ServerSocket套接字绑定端口,然后通过accept去等待连接2.accept操作之后,server就会接受client发来的信息BufferedReader reader = new BufferedReader( new InputStreamReader(socket.getInputStream()));3.server通过BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));输出client4.互联网这块网络编程用的也挺多的,比如rpc框架,netty等
对于AIO来说
1.server首先创建一个AsynchronousServerSocketChannel并绑定ip和端口,通过accept(null, new AcceptHandler)来等待客户端连接 acceptHandler要实现CompletionHandler<AsynchronousSocketChannel, Object>接口2.在该方法中,有两个方法,一个是成功,一个是失败,按照逻辑填入响应业务即可
29. 说下Java中的IO
滴滴19年秋招本科
??Java的IO包采用了装饰者模式。关闭流可以使用try-with-resource??从流的特点来说Java IO中包含字符流_(操作char,Reader、Writer, 使用缓冲区缓冲字符,不关闭流就不会输出 )、字节流(操作byte,OutputStream、InputStream)。按照流向还分为输入流(read),输出流(write)。通过OutputStreamWriter(Writer子类)_和InputStreamReader把字符流转为字节流
BIO、NIO、AIO的对应类实现了解吗
??BIO:同步并阻塞的IO,数据的读取写入必须阻塞在一个线程内等待其完成。是传统的java.io包下面的代码实现,参考上面两点* NIO方式适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,并发局限于应用中,编程比较复杂,JDK1.4开始支持。
??AIO:JDK7实现的,即Async非阻塞,是异步非阻塞的IO。异步非阻塞I/O模型。同步非阻塞需要一个线程不断去询问是否完成_(select)_,而异步非阻塞无需一个线程去轮询所有IO操作的状态改变,在相应的状态改变后,系统会通知对应的线程来处理 AIO方式适用于连接数目多且连接比较长(重操作)的架构,比如相册服务器,充分调用OS参与并发操作,编程比较复杂,JDK7开始支持
30. NIO的原理
阿里19年秋招
??NIO是在JDK1.4中引入的,原来的IO是基于流的,而NIO是通过buffer-chanel-buffer基于块的;同时原来的IO只能是输入或者输出单向的,但是NIO可以读,写或者同时读写,可以更好地反应底层OS的真实情况_(UNIX 模型中,底层操作系统通道是双向的 )_??使用fin.read(buffer)把输入chanel读入buffer时,需要clear()方法重设缓冲区,使它可以接受读入的数据。使用fout.write(buffer)向输出chanel写入buffer时,需要flip()方法让缓冲区可以将新读入的数据写入另一个通道。写之前向buffer填充是put;获取是get??NIO有三个状态变量:positon <= limit <= capacity??position:表明指针在buffer数组中的位置,buffer写入fout时表明写入了多少个;buffer读取fin时表示读出了多少个??limit:表明在buffer写入fout时还有多少个没写到fout中;buffer读取fin时还有多少个没读入到limit中??capacity:buffer数组的大小,整个buffer最大的容量??当buffer中有数据_(如read之后)准备write时_,此时position即为数据容量,调用filp()之后会使position=0,同时limit=原来的position,这是limit表明的意思便是前面说的 还有多少个没写到fout中;clear()会将position重新置为0,limit=capacity,使得buffer空间最大化,所以clear()经常用在read之前??NIO有分散和聚集,分片,文件锁定,直接映射内存等新特性
31. IO模型有哪几种
阿里
??阻塞式IO模型 BIO:当用户线程发出IO请求之后,内核会去查看数据是否就绪,如果没有就绪就会等待数据就绪,而用户线程就会处于阻塞状态,用户线程交出CPU。当数据就绪之后,内核会将数据拷贝到用户线程,并返回结果给用户线程,用户线程才解除block状态,如socket.accept()??非阻塞IO模型:用户线程发出IO请求之后,内核会去查看数据是否就绪,如果没有就绪就会等待数据就绪,在这个过程中用户线程不会等待,而是会不断去询问内核是否准备好。非阻塞IO不会交出CPU,而会一直占用CPU??IO复用模型 NIO(select,poll,epoll):Java NIO之前用的select,现在用的epoll。用户发出IO请求之后,有一个select线程去管理这些请求_(socket)_,它会不断阻塞轮询内核关于某事件的数据是否能准备好,没有事件准备好则会一直阻塞。适合连接数较多的情况;select基于long数组,将内核和用户态拷贝消耗大,有1024的限制;poll基于链表,没有大小限制;epoll基于map,通过事件通知方式,每当fd就绪,系统注册的回调函数就会被调用,将就绪fd放到ready队列里面,时间复杂度O(1) 需要注意的是:多路复用IO模型是通过轮询的方式来检测是否有事件到达,并且对到达的事件逐一进行响应。因此对于多路复用IO模型来说,一旦事件响应体很大,那么就会导致后续的事件迟迟得不到处理,并且会影响新的事件轮询??信号驱动IO模型:当用户线程发起一个IO请求操作,会给对应的socket注册一个信号函数,然后用户线程会继续执行,当内核数据就绪时会发送一个信号给用户线程,用户线程接收到信号之后,便在信号函数中调用IO读写操作来进行实际的IO请求操作??异步IO模型 AIO:当用户线程发起read操作之后,立刻就可以开始去做其它的事。而另一方面,从内核的角度,当它受到一个asynchronous read之后,它会立刻返回,说明read请求已经成功发起了,因此不会对用户线程产生任何block。然后,内核会等待数据准备完成,然后将数据拷贝到用户线程,当这一切都完成之后,内核会给用户线程发送一个信号,告诉它read操作完成了。也就说用户线程完全不需要实际的整个IO操作是如何进行的,只需要先发起一个请求,当接收内核返回的成功信号时表示IO操作已经完成,可以直接去使用数据了
IO复用和非阻塞IO的比较
非阻塞IO中,不断地询问socket状态时通过用户线程去进行的
而在多路复用IO中,轮询每个socket状态是内核在进行的,这个效率要比用户线程要高的多
JDK8 新特性32. 了解什么新特性
??函数式编程,是种编程方式,它将电脑运算视为函数的计算。函数编程语言最重要的基础是λ演算,而且λ演算的函数可以接受函数当作输入(参数)和输出(返回值)。其最主要的表现是lambda(会通过invokedynamic来实现)和Stream??lambda表达式可以简化匿名内部类,常与@FunctionInterface一起使用,集合常用的是Iterable和Map接口forEach方法??lambda中的外部变量必须是final常量。因为lambda是为了拥抱函数式编程,不应该为函数引入状态??为了支持函数式编程,JDK8在java.util.function包中引入了几个接口Function<T,R>接收T,返回R;BiFunction<T,U,R>接收T,U,返回R;Consumer< T >:接受一个输入,没有输出;Supplier< T >:没有输入,一个输出等等其他接口??新增了对时间日期的改进:DateTimeFormatter用来替换SimpleDateFormat,可以同步修改LocalDate为日期_(年月日)处理类、LocalTime为时间(时分秒)_处理类、LocalDateTime为日期时间处理类,简单判断闰年,日期的加减操作??JDK9的jshell,接口私有方法,多版本兼容jar,try-with-resourses的改进,创建不可变集合,增强stream API,把String的char[]改为byte[]??jdk11支持局部变量类型推导??jdk12 switch不用写break
33. 对Stream有什么了解吗
京东19年秋招本科
Stream是函数式编程和多核时代的产物,可以很方便的操作诸如平均值,最大值等对象集合。通过sequential() 或 parallel()来将其执行方式设置为顺序或并行。Stream 就如同一个迭代器(Iterator),单向,不可往复,数据只能遍历一次,遍历过一次后即用尽了,就好比流水从面前流过,一去不复返
使用时,可以先将数组/集合_Stream.of(), list.stream()_转化为流,然后通过一系列中间值的操作,最终转为最终值操作
??Intermediate
1.map:把一个元素类型为 T 的流转换成元素类型为 R 的流_(1:1)_,flatMap是1:n2.filter:按照某项标准进行过滤3.limit:截断流使其最多只包含指定数量的元素4.sorted:对流进行排序
??Terminal
1.forEach:接收一个 Lambda 表达式,然后在 Stream 的每一个元素上执行该表达式2. collect:将流中的元素转化为对应的集合或者其他类型