Java基础
之前也是太navie,觉得java基础没什么用。但最近在做项目的时候的确感受到自己基础不是很牢。所以在这里记录下java的基础,以后找工作也能用得上。
Java有哪些优点?
- 看书前我的思考:面向对象的高级语言、跨平台,一份代码,三个平台都能用,上手快而且语法简单。
- 跨平台,因为java是解释性语言,编译器会把Java代码变成中间代码,然后交给jvm上解释运行。
- Java有垃圾回收器,可以让我们从内存管理中解脱出来。
为什么Java会比较慢?
- 因为java是解释性语言,java语言需要先解释为字节码,然后再由JVM去解释执行,而C/C++是直接编译成二进制代码就可以执行,但是不可以跨平台。
float和double的区别?
- 对编程人员来说,float和double的区别在于精度问题,float的有效数字为7位,而double的有效数字为16位。float占4个字节,用32位二进制表示,而double占8个字节,用64位表示。
StringBuilder和StringBuffer的区别?
- 在执行速度方面StringBuilder会比StringBuffer快,因为StringBuilder是线程不安全的,而StringBuffer是线程安全的。
- 扩展:为什么StringBuilder会比String快? 因为当你用String进行字符串增删操作时候,例如s=s+“a”,是先将s+“a”的结果赋予一个String,就是说先new一个String来存储s+“a”的结果,然后再将这个新new出来的String赋值给s。
静态块
一个Java文件中是否可以有多个类?
- 可以,但是最多只能有一个public修饰的类。同事如果有一个文件有多个类,那Java文件解释成字节码的时候会解释成两个.class文件。
怎么复制一个对象?
- 类实现Cloneable接口,然后重写掉clone方法。
- 需要注意的是复制分浅拷贝和深拷贝。当类里面有复杂的数据类型,如数组,其他类的时候,使用浅拷贝也只会复制类里面的复杂数据类型的引用。如果想完全复制的话就要用到深拷贝,即把复杂类型也实现clone。
深拷贝例子:
@Override
protected Object clone() throws CloneNotSupportedException {
TestClass testClass = null;
testClass = (TestClass) super.clone();
testClass.obj = (Obj) obj.clone();
return testClass;
}
什么是面向对象?
- 首先说一下对象,我们把数据和方法绑定在一起,作为一个相互依存的整体,这就是我们说的对象。(就好像猫,他没有飞的方法,但是有爬树的方法,即数据和方法是相互依存的)。
- 对同类对象抽象出共性,就是类。然后类是通过接口和外接产生联系。
- 对象和对象之间通过消息进行通信,程序流程由用户决定。
面向对象的特征?
- 封装、抽象、继承、多态。
- 抽象:忽略一个主题中与当前目标无关的方面。就好像我现在在做一个学生成绩管理系统,那么对于学生这个对象我们更多地去关注成绩、班级、姓名等信息而不是身高,体重。
- 继承:继承的类能使用被继承类的所有功能。
- 封装:就是把客观的事物封装成抽象的类。
- 多态:允许将子类类型指针赋值给父类类型指针。其中实现多态又有覆盖和重载这两种。
- 重载:会根据传入的参数类型而选择运行哪个方法。(方法同名)
- 覆盖:子类型指针赋值给父类型指针的时候,父类型的方法会被覆盖成子类型的方法。
那么为什么要用面向对象开发?
抽象类和接口有什么不同。
- 抽象类:只要类里面有一个方法是抽象的!那这个类就必须是抽象类。和接口一样,他们都不能被实例化。
- 抽象类在开发中很常见。就好像安卓开发中,当我继承一个监听Listener时,就必须实现其的Onclick
的方法才能将其实例化。
final、finally、finalize的区别?
- final用于声明属性、方法和类,分别表示属性不可变、方法不可覆盖和类不可被继承。
- 属性不可变指的是引用不可变,即被赋予final的属性的所指向的是对象是不可改变的。
- 方法不可覆盖指的是,子类不可重写这个方法。
- 类不可被继承:此类不可被继承和所有方法也不能被重写。(String类就是final的,所以他既不能被继承也不能被重写方法)
- finally,异常处理,无论有没有发生异常,都会执行finally的内容代码。经常被用于释放资源用。
- finalize,垃圾回收器执行的时候会调用被回收对象的finalize方法,很少用。
static关键字有啥用?
- static关键字的作用是,使得被static修饰的属性,方法不用和对象绑定而是跟类绑定,就是说可以不创建对象也能被使用。经常用于定义变量,单例模式也经常会用到。
位运算
- <<表示左移一位,每移一位就等于乘以2,这样计算会效率高
-
表示右移一位,每移一位等于除以二。
char变量中是否可以存储一个汉字
- Java默认使用的是Unicode编码方式,每个字母占一个字节,而每个汉字占两个字节。
“==”“equal”“hascode”
- ==比较的是地址,equal如果被覆盖掉的话其实也是比较地址,但是例如String那些不可变类有重写掉equal的方法所以能用来比较值。
socket
- socket的建立分三个过程,首先是服务器监听端口,然后客户端向端口发送请求,然后服务器接受请求,建立通信。
序列化
- java对象序列化:能将对象转为二进制进行传输。
- 什么时候会用到序列化:需要网络传输一个对象时和进行序列化深拷贝对象的时候
JVM是怎么加载类的?
- JVM将生成的class按照一定的规则加载到内存中
- 类的加载分为隐式加载和显式加载,new对象出来的是隐式加载,Class.forName的那种是显式加载。
GC(垃圾回收器)
- 主要作用:回收程序中不再使用的内存。
- 完成内存分配、确保被引用的对象的内存不被错误的回收,回收不再引用的对象内存
- 垃圾回收器使用有向图来记录和管理堆内存中所有的对象。
既然有了GC,那Java也还是会有内存泄漏
- 容易造成内存泄漏的原因很多,如静态集合类,各种数据库连接没有close掉,监听器
堆和栈有什么区别
- 基本上基本类型、对象的引用变量,都会放在栈上,变量出了作用域就会自动被释放。而引用类型的变量其内存是分配在堆或者常量池中,需要通过new来创建。
- 每当调用新的函数时,就会压栈,函数调用完毕,就会弹栈。
- 简单来说,堆是用来存对象的,而栈是用来运行程序的。栈的存取速度会比栈快很多。
TreeSet你听说过吗?
- 我们都知道Set是不可以放入重复的元素的,其接口类有两个,一个是HashSet和TreeSet,他们的区别是TreeSet是有序的而HashSet是无序的,那么为什么TreeSet用得少呢,那是因为他的效率很低,每插入一个元素就会重新排序一次,所以性能比较慢,用的人也自然会少啦。
HashMap的实现原理
LinkList和Vector
- LinkList是线程不安全的,Vecotr是线程安全的。
- 为什么Vecotr是线程安全的呢?因为Vector里面所有的方法都是同步的,即synchronization。
使用ToStringBuilder
ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
使用这种方法有两个好处。第一是,PO属性有变化的时候,不需要变动toString方法。第二是,普通的toString方法都是用+号来连接的,这种方式会产生大量的String对象,导致消耗的内存增加。使用这种方式则可以避免这种问题。