1)Java类的初始化顺序
1、父类的静态变量和静态代码块(按声明顺序)
2、子类的静态变量和静态代码块(按声明顺序)
3、父类的普通成员变量和代码块
4、父类的构造方法
5、子类的普通成员变量和代码块
6、子类的构造方法
2)Integer i01 = 59; //直接赋值数字,java会自动装箱,自动调用Integer.valueOf(59)
int i02 = 59;
Integer i03 = Integer.valueOf(59);//Integer.valueOf(int i),当我们创建的 i 的范围在-128~127之间时,会直接返回缓存池中的对象,否则会返回一个新的对象。
Integer i04 = new Integer(59);
3)执行顺序优先级别:静态块>main()>构造块>构造方法
4)Hashtable与 HashMap不同
1、HashMap继承Dictionary类,实现了Map接口;Hashtable继承AbstractMap类,实现了Map 接口。
2、Hashtable是同步的,HashMap是非同步的。
3、Hashtable中key与value都不允许出现null值,HashMap中null值可以作为键这样的键只能有一个,可有一个或者多个键所对应的值为null。所以当get()返回null时,即可以表示不存在该键,也可以表示该键对应的值为null,所以应该使用containsKey()方法表示判断。
4、Hashtable默认hash数组大小是11,增加的方式是old * 2 + 1。HashMap的hash数组默认大小是16,一定是2的指数。
5)Java异常机制
Java将所有的异常来当作对象进行处理,并定义一个基类java.lang.Throwable作为所有异常的超类。Java API中定义了许多异常类,主要分为两大类,Error、Exception。
接下来Throwable分成了两个不同的分支,一个分支是Error,它表示不希望被程序捕获或者是程序无法处理的错误。另一个分支是Exception,它表示用户程序可能捕捉的异常情况或者说是程序可以处理的异常。其中异常类Exception又分为运行时异常(RuntimeException)和非运行时异常。Java异常又可以分为不受检查异常(Unchecked Exception)和检查异常(Checked Exception)。
Exception分支中有一个重要的子类RuntimeException(运行时异常),该类型的异常自动为你所编写的程序定义ArrayIndexOutOfBoundsException(数组下标越界)、NullPointerException(空指针异常)、ArithmeticException(算术异常)、MissingResourceException(丢失资源)、ClassNotFoundException(找不到类)等异常,这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理。这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生;而RuntimeException之外的异常我们统称为非运行时异常,类型上属于Exception类及其子类,从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。如IOException、SQLException等以及用户自定义的Exception异常,一般情况下不自定义检查异常。
检查异常
:在正确的程序运行过程中,很容易出现的、情理可容的异常状况,在一定程度上这种异常的发生是可以预测的,并且一旦发生该种异常,就必须采取某种方式进行处理。不受检查异常
:包括RuntimeException
及其子类和Error
。
6)JVM运行时数据区包括:虚拟机栈、堆、方法区、本地方法栈、程序计数器
虚拟机栈:线程私有、存放基本类型,对象的引用和returnAddress,在编译器完成分配;
堆:JAVA堆也称为GC堆,线程公有,存放对象的实例以及数组,JAVA堆是内存管理的主要区域;
方法区:线程共享,存储被虚拟机加载类的信息,常量和静态数据,这个区域中的内存回收主要是针对常量池的对象的回收和类的卸载;
程序计数器:线程私有,每个线程都有自己独立的程序计数器;
7)类加载机制
JVM的类加载机制主要包括五个部分:加载、验证、准备、解析、初始化
加载阶段:
1、通过一个类的全限定名来获取其定义的二进制字节流。
2、将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构。
3、在Java堆中生成一个代表这个类的java.lang.Class对象,作为对方法区中这些数据的访问入口。
验证阶段:
此阶段主要为保证加载类的正确性。
准备阶段:
准备阶段为类的静态变量分配内存,并将其初始化为默认值,而不是代码中赋予的初始值,初始值的赋予是在java类初始化阶段完成。
对于基本类型的静态变量一般被赋予0,对于引用的静态类型,一般被赋予null,但是如果被final修饰,准备阶段就会被赋予代码中的初始值,此时已经将变量值放入了方法区的常量池中。
解析阶段:
将字符引用解析为直接引用
初始化阶段:
为类的静态变量赋予正确的初始值(上个阶段已经赋值(默认值)),JVM负责对类进行初始化,主要对类变量进行初始化。
如果从java开发人员的角度来说,类加载器可以分为启动类加载器:BootstrapClassLoader,扩展类加载器:ExtensionClassLoader,应用程序类加载器:Application ClassLoader,自定义加载器
JVM在类加载时默认采取双亲委派机制,如果一个类加载器接收到了类加载的请求,它首先把这个请求委托给他的父类加载器去完成,每个层次的类加载器都是如此,因此所有的加载请求都应该传送到顶层的启动类加载器中,只有当父加载器反馈自己无法完成这个加载请求(它在搜索范围中没有找到所需的类)时,子加载器才会尝试自己去加载。
8)Java两个数值在进行二元操作时,会进行如下顺序转换:
1、如果两个数值一个是double类型,另一个操作数会转化为double。
2、否则,如果一个人操作数是float类型,另外一个操作数会转化为float类型。
3、否则,如果一个是long类型,另外一个会转化为long类型。
4、否则两个数都会转化为int类型。
9)同上数据类型转换,遵循一个原则;范围小到范围大的自动进行转换,范围大的到范围小的需要强制转换
byte , short,char -> int -> long -> float ->double
byte b3=(byte)(b1+b2);//byte类型在运算时都会自动转化为int类型,所以要么用强制转化把b1+b2变成byte
10)byte -128~127 (-2^7~2^7-1)
short -2^15 ~ 2^15 -1
int -2^31 ~ 2^31 -1
byte 1字节 short 2字节 int 4字节 long 8字节 char 2字节 float 4字节 double 8字节
11) equals 方法必须满足自反性(x.equals(x)必须返回 true)、对称性(x.equals(y)返回 true 时,y.equals(x) 也必须返回 true)、传递性(x.equals(y)和 y.equals(z)都返回 true 时,x.equals(z)也必须返回 true)和一致性(当 x 和 y 引用的对象信息没有被修改时,多次调用 x.equals(y)应该得到同样的返回值),而且对于任何非 null 值的引 用 x,x.equals(null)必须返回 false
12)
下面列举几个常见的 RuntimeException。
1)java.lang.NullPointerException 空指针异常;出现原因:调用了未经初始化的对象或者是不存在的对象。 2)java.lang.ClassNotFoundException 指定的类找不到;出现原因:类的名称和路径加载错误;通常都是程序
试图通过字符串来加载某个类时可能引发异常。
3)java.lang.NumberFormatException 字符串转换为数字异常;出现原因:字符型数据中包含非数字型字符。 4)java.lang.IndexOutOfBoundsException 数组角标越界异常,常见于操作数组对象时发生。 5)java.lang.IllegalArgumentException 方法传递参数错误。
6)java.lang.ClassCastException 数据类型转换异常。
7)java.lang.NoClassDefFoundException 未找到类定义错误。 8)SQLException SQL 异常,常见于操作数据库时的 SQL 语句错误。 9)java.lang.InstantiationException 实例化异常。 10)java.lang.NoSuchMethodException 方法不存在异常。
13) throw 和 throws 的区别
throw:
1)throw 语句用在方法体内,表示抛出异常,由方法体内的语句处理。
2)throw 是具体向外抛出异常的动作,所以它抛出的是一个异常实例,执行 throw 一定是抛出了某种异常。
throws:
1)throws 语句是用在方法声明后面,表示如果抛出异常,由该方法的调用者来进行异常的处理。
2)throws 主要是声明这个方法会抛出某种类型的异常,让它的使用者要知道需要捕获的异常的类型。
3)throws 表示出现异常的一种可能性,并不一定会发生这种异常。
14)
switch(expr)中,expr 可以是 byte、short、char、int、 enum,expr 还可以是字符串(String),但是长整型(long)在目前所有的版本中都是不可以的。
15)
public static HashMap<Integer, User> sortHashMap(HashMap<Integer, User> map) { // 首先拿到 map 的键值对集合 // 将 set 集合转为 List 集合,为什么,为了使用工具类的排序方法 // 使用 Collections 集合工具类对 list 进行排序,排序规则使用匿名内部类来实现 Collections.sort(list, new Comparator<Entry<Integer, User>>() { |
|
200 OK //客户端请求成功
301 Moved Permanently(永久移除),请求的 URL 已移走。Response 中应该包含一个 Location URL, 说明资 源现在所处的位置
302 found 重定向
400 Bad Request //客户端请求有语法错误,不能被服务器所理解
401 Unauthorized //请求未经授权,这个状态代码必须和 WWW-Authenticate 报头域一起使用
403 Forbidden //服务器收到请求,但是拒绝提供服务
404 Not Found //请求资源不存在,eg:输入了错误的 URL
500 Internal Server Error //服务器发生不可预期的错误
503 Server Unavailable //服务器当前不能处理客户端的请求,一段时间后可能恢复正常
16)
localhost、127.0.0.1和0.0.0.0和本机IP的区别
localhost
localhost其实是域名
,一般windows系统默认将localhost指向127.0.0.1
,但是localhost并不等于127.0.0.1
,localhost指向的IP地址是可以配置的
127.0.0.1
首先我们要先知道一个概念,凡是以127
开头的IP地址,都是回环地址(Loop back address),其所在的回环接口一般被理解为虚拟网卡,并不是真正的路由器接口。
所谓的回环地址,通俗的讲,就是我们在主机上发送给127
开头的IP地址的数据包会被发送的主机自己接收,根本传不出去,外部设备也无法通过回环地址访问到本机。
小说明:正常的
数据包
会从IP层
进入链路层
,然后发送到网络
上;而给回环地址
发送数据包
,数据包
会直接被发送主机的IP层
获取,后面就没有链路层
他们啥事了。
而127.0.0.1
作为{127}
集合中的一员,当然也是个回环地址。只不过127.0.0.1
经常被默认配置为localhost的IP地址。
一般会通过ping 127.0.0.1
来测试某台机器上的网络设备是否工作正常。
0.0.0.0
首先,0.0.0.0
是不能被ping
通的。在服务器中,0.0.0.0
并不是一个真实的的IP地址,它表示本机中所有的IPV4地址。监听0.0.0.0
的端口,就是监听本机中所有IP的端口。