java 基础
-
jvm、jre 和 jdk,jvm 提供 java 程序运行载体,jre 包含 jvm + 一些 java 类库,提供 java 程序运行环境,jdk 包含 jre + 编译和工具,提供 java 程序开发环境;
-
& 和 &&,| 和 ||,&& 和 || 是短路操作,而 & 和 | 不是;
-
自增和自减,i = i++ 是通过 temp = i; i++;i=temp 来实现的;
-
private、defalut、protected 和 public,访问程度依次开放;
-
抽象类和接口,只能继承一个抽象类,可以实现多个接口,抽象类可以有非抽象方法;
-
final 关键字:类不可被继承,方法不能被重写,变量不能被修改,变量指向的对象,其对象内部可以修改;
-
== 和 equals,默认比较的都是对象的内存地址,基本类型比较的是值,很多类重写了 equals 方法,使其比较的是对象的内容;
-
equals 和 hashcode,后者是 Object 类的 native 方法,通常是将对象的内存地址转换为整数返回,主要在哈希表这类集合中用到,哈希表是根据哈希取余来判断数组下标的,因此两个相等的对象,其 hashcode 一定要相等,这样才能在哈希表结构中保证没有重复对象,所以重写了 equals,重新定义了相等的对象,也要重新定义 hashcode;
-
java 是值传递,引用类型传递是给方法参数赋值为对象的内存地址;
-
浅拷贝和深拷贝,浅拷贝对于引用类型,拷贝的是其内存地址值,堆中的对象不会拷贝,因此原对象和拷贝对象中的引用类型成员变量指向的是同一个堆中对象,深拷贝就是将堆中对象也复制一份,拷贝对象的成员变量指向这个新复制对象,浅拷贝可通过 clone() 实现,深拷贝需要重写 clone 方法,自己实现,或者序列化的方式;
-
String 是特殊的引用类型,是 final 修饰的类,不可被继承,任何对 String 对象的修改都会引发新的 String 对象生成,不过 java8 对其进行了优化,优化后是用 StringBuilder 来创建的,StringBuilder 对象可被修改,不会新创建对象,StringBuffer 是 StringBuilder 的线程安全版本,其方法用 synchronized 修饰;
-
String s1 = new String(“abc”) 这个操作,会在堆中创建一个 String 对象,如果字符串常量池中没有 abc 对象,就会在字符串常量池中创建 abc 对象;String s2 = “abc” 这个操作是将 s2 指向字符串常量池的 abc 对象;
-
Integer 会缓存 -128 到 127 的 Integer 对象,因此在此范围内的 Integer 对象,都指向的是缓存池中同一对象,Integer a= 127,Integer b = 127,Integer c= 128,Integer d = 128 其中 a 和 b 相等, c 和 d 不相等;具体缓存在 Integer 内部类 IntegerCache 中,Integer.valueOf 方法首先会去 IntegerCache 中寻找;
-
BIO,NIO,AIO,分别是同步阻塞 io、同步非阻塞 io 和异步非阻塞 io,bio 一个线程一次只能处理一个 io 连接,线程需要阻塞等待 io 响应,nio 是单线程使用多路复用的方式能够同时处理多个 io 连接,多路复用是轮询建立连接的 io,发现有准备好的 io 连接,进行处理,仍是同步的,线程需要轮询,aio 是异步不阻塞,单线程可以管理多个 io 连接,通过事件通知机制来处理有数据的 io;
bio:inputStream,reader
nio:channel,selector,buffer
aio:AsynchronousChannel
-
序列化和反序列化是对象和二进制流的相互转换,Serializable 和 serialVersionUID 都是用来保证某些场景序列化的正确性,序列化不包括 static 变量,对于不想序列化的变量,使用 transient 关键字修饰;
-
常用的 java 序列化方式:Java 对象流列化、Json 序列化和 ProtoBuff 序列化,分别使用 ObjectOutputStream 和 ObjectInputStream,jackson/fastjson,并且 ProtoBuff 序列化后非常轻便,大大减小数据传输;
-
泛型提供编译时类型安全检测,将所操纵的数据类型指定为参数,可以使用在类,接口和方法中,并且泛型在编译期生效,后续会被擦除,泛型擦除是为了兼容 jdk5 以下;
-
注解可以理解为一种标记手段,修饰在类,方法或属性上,然后在编译期或运行期,去识别这些标记,作用域有SOURCE,class,runtime,分别是编译期使用,类加载使用,和运行时使用;
-
反射:Class、Field、Constructor、Method,通过这些类,可以在运行时获取任意类的任何属性和方法,框架、注解解析都大量运用了反射,原理是类加载时类信息加载到了方法区,反射是获取这些信息;
-
java8 有:接口 default 方法,lambda 表达式/函数式接口,Stream api,LocalDate,Optional 类等,接口默认方法即允许接口有方法实现;lambda 表达式即匿名内部类的简写,并可以用作方法的参数使用,Stream api 是提供结合 lambda 表达式来简化集合类的操作(查找、过滤、映射),Optional 提供了空指针的判断方法,代替 null 检查;
-
只有函数式接口才能用 lambda 表达式的写法,函数式接口即只包含一个抽象方法的接口,java8 提供的函数式接口有: Comparator,Runnable,Callable,Predicate,Function,Supplier,Consumer 等;
-
Stream 流用于集合对象,常用的操作有 filter 过滤,sorted 排序,map 转换,match 匹配,count 计数,reduce 合并为一个值;