java基础_面试题笔记
1.equal和"=="的区别
使用”==”判断的是二者是否为同一个对象,比较的是两个对象的地址,即便两个对象的值是相同的,地址不同也会输出false。
使用equal比较的是两者的值,即便不是同一个对象,只要值相同,就会输出true。
2.运算符优先级
Java中的运算符,一元运算符优先级很高,四则运算符其次,再是移位运算符,然后是关系运算符、位运算符、与或(非是一元运算),最后是赋值运算符。
java 黙认浮点类型为double。float数据类型有一个后缀为" f "或" F "。long类型有一个后缀,为" l " 或者" L "。
3.内部类
要创建成员内部类的对象,前提必须创建一个外部类的对象,方法如下:
4.代码执行过程
执行Parent的静态块
执行Child的静态块
执行Grandpa的普通块(如果有显示调用父类构造super(),则执行,否则执行默认构造)
执行Parent的普通块(如果有显示调用父类构造super(),则执行,否则执行默认构造)
执行Child的普通块
执行Child的构造方法(被调用:new Child();)
5.socket编程
6.节点流和处理流
按照流是否直接与特定的地方(如磁盘、内存、设备等)相连,分为节点流和处理流两类。
- 节点流:可以从或向一个特定的地方(节点)读写数据。如FileReader.
- 处理流:是对一个已存在的流的连接和封装,通过所封装的流的功能调用实现数据读写。如BufferedReader.处理流的构造方法总是要带一个其他的流对象做参数。一个流对象经过其他流的多次包装,称为流的链接。
JAVA常用的节点流:
- 文 件 FileInputStream FileOutputStrean FileReader FileWriter 文件进行处理的节点流。
- 字符串 StringReader StringWriter 对字符串进行处理的节点流。
- 数 组 ByteArrayInputStream ByteArrayOutputStreamCharArrayReader CharArrayWriter 对数组进行处理的节点流(对应的不再是文件,而是内存中的一个数组)。
- 管 道 PipedInputStream PipedOutputStream PipedReaderPipedWriter对管道进行处理的节点流。
常用处理流(关闭处理流使用关闭里面的节点流)
- 缓冲流:BufferedInputStrean BufferedOutputStream BufferedReader BufferedWriter 增加缓冲功能,避免频繁读写硬盘。
- 转换流:InputStreamReader OutputStreamReader 实现字节流和字符流之间的转换。
- 数据流 DataInputStream DataOutputStream 等-提供将基础数据类型写入到文件中,或者读取出来.
流的关闭顺序
- 一般情况下是:先打开的后关闭,后打开的先关闭
- 另一种情况:看依赖关系,如果流a依赖流b,应该先关闭流a,再关闭流b。例如,处理流a依赖节点流b,应该先关闭处理流a,再关闭节点流b
- 可以只关闭处理流,不用关闭节点流。处理流关闭的时候,会调用其处理的节点流的关闭方法。
7.序列化
序列化:将数据结构转换称为二进制数据流或者文本流的过程。序列化后的数据方便在网络上传输和在硬盘上存储。
反序列化:将二进制数据流或者文本流转换称为易于处理和阅读的数据结构的过程。
本质其实还是一种协议,一种数据格式,方便数据的存储和传输。
8.接口interface
接口的属性默认是:Public static final,方法默认是:public abstract。(可以用static或者default修饰接口中的方法)
native是调用本地方法库(如操作系统底层函数)
9.线程方法
所谓的释放锁资源实际是通知对象内置的monitor对象进行释放,而只有所有对象都有内置的monitor对象才能实现任何对象的锁资源都可以释放。又因为所有类都继承自Object,所以wait()就成了Object方法,也就是通过wait()来通知对象内置的monitor对象释放,而且事实上因为这涉及对硬件底层的操作,所以wait()方法是native方法,底层是用C写的。其他都是Thread所有,所以其他3个是没有资格释放资源的而join()有资格释放资源其实是通过调用wait()来实现的。
sleep()方法
在指定时间内让当前正在执行的线程暂停执行,但不会释放“锁标志”。不推荐使用。
sleep()使当前线程进入阻塞状态,在指定时间内不会执行。
wait()方法
在其他线程调用对象的notify或notifyAll方法前,导致当前线程等待。线程会释放掉它所占有的“锁标志”,从而使别的线程有机会抢占该锁。
当前线程必须拥有当前对象锁。如果当前线程不是此锁的拥有者,会抛出IllegalMonitorStateException异常。
唤醒当前对象锁的等待线程使用notify或notifyAll方法,也必须拥有相同的对象锁,否则也会抛出IllegalMonitorStateException异常。
waite()和notify()必须在synchronized函数或synchronized block中进行调用。如果在non-synchronized函数或non-synchronized block中进行调用,
虽然能编译通过,但在运行时会发生IllegalMonitorStateException的异常。
yield()方法
暂停当前正在执行的线程对象。
yield()只是使当前线程重新回到可执行状态,所以执行yield()的线程有可能在进入到可执行状态后马上又被执行。
yield()只能使同优先级或更高优先级的线程有执行的机会。
join()方法等待调用join方法的线程结束,再继续执行。如:t.join();//主要用于等待t线程运行结束,若无此句,main则会执行完毕,导致结果不可预测。
注意:
CountDownLatch 是等待一组线程执行完,才执行后面的代码。此时这组线程已经执行完。
CyclicBarrier 是等待一组线程至某个状态后再同时全部继续执行线程。此时这组线程还未执行完。
进程间通信的方式——信号、管道、消息队列、共享内存
10.volatile和synchronized关键字
关键字
volatile
是线程同步的轻量级实现,所以
volatile
性能肯定比
synchronized
要好,并且只能修改变量,而
synchronized
可以修饰方法,以及代码块。
多线程访问
volatile
不会发生阻塞,而
synchronized
会出现阻塞。
volatile
能保证数据的可见性,但不能保证原子性;而
synchronized
可以保证原子性,也可以间接保证可见性,因为它会将私有内存和公共内存中的数据做同步。
关键字
volatile
解决的下变量在多线程之间的可见性;而
synchronized
解决的是多线程之间资源同步问题。
11.HashMap和TreadLocalMap
TreadLocalMap使用开放定址法解决hash冲突,HashMap使用链地址法解决hash冲突.
12.JVM