C++&Java
-
Java是更纯粹的面向对象的语言,C++为了兼容C还保留了一些面向过程的东西
-
Java经过编译得到字节码文件,再经过JVM的解释得到机器指令文件,因此可以跨平台运行;C++编译直接得到的是机器指令文件
-
Java有垃圾回收机制,可以释放未存活的Java对象占用的空间;C++创建对象之后需要调用delete方法销毁
-
C++中有多继承;Java只支持单继承,可以通过接口实现多继承
-
Java运行速度比C++更慢
装箱&拆箱
- 装箱:把基本类型用它们相应的引用类型包装起来,使其具有对象的性质,如Integer a = 10
- 拆箱:将引用类型数据变为值类型数据
序列化&反序列化
- 序列化:将Java对象转换为字节序列的过程
- 反序列化:将字节序列恢复为Java对象的过程
- 序列化使用场景:1.将对象永久保存到硬盘上;2.在网络上传输对象。
String、StringBuffer、StringBuilder
-
String
-
字符串常量
-
final修饰,不可继承
-
直接赋值(String str="abc")创建0个或者1个对象(在常量池),new String创建1个或2个对象(在堆和常量池)
-
尽量直接赋值,提高JVM性能和减少内存开销
-
-
StringBuffer
-
字符串操作类,字符串变量
-
final修饰,不可继承
-
同步处理
-
toString对象缓存,减少复制开销
-
线程安全
-
-
StringBuilder
-
字符串操作类,字符串变量
-
final修饰,不可继承
-
非同步处理
-
toString返回新创建的对象,没有缓存
-
非线程安全
-
ArrayList和LinkedList
-
ArrayList基于索引的数据接口,底层是数组;LinkedList是基于数据链表的数据接口
-
ArrayList随机访问时间是O(1),LinkedList访问时间O(n)
-
ArrayList插入删除涉及到大小和索引的改变,LinkedList插入和删除操作时间复杂度O(1)
-
LinkedList比ArrayList更占内存,需要额外存储两个引用
Map类
-
HashMap
-
采用哈希表存储,使用数组+链表+红黑树实现
-
非线程安全
-
不保证顺序性
-
线程安全:ConCurrentHashMap
-
默认容量16,扩容*2
-
-
LinkedHashMap
-
HashMap基础上添加了按顺序访问的机制
-
引入header、before和after组成双向链表,实现按顺序访问
-
-
TreeMap
-
根据key排序,默认升序
-
-
Hashtable
-
继承字典类,尽量不使用
-
抽象类和接口
-
抽象类需要被子类继承,接口需要被类实现
-
抽象类和接口都不能直接实例化,要想实例化,抽象类变量需要指向实现所有抽象方法的子类对象,接口类变量需要指向实现所有接口方法的类对象
-
抽象类可以做方法声明也可以做方法实现,抽象方法只能声明不能实现,接口只能做方法声明
-
接口里定义的变量只能是公共静态常量,抽象类里的变量是普通的变量
-
有抽象方法的类是抽象类
-
类不可以继承多个类,接口可以继承多个接口,类可以实现多个接口,Java不支持多继承类的原因是多继承类比较复杂,涉及到了方法的重写,可以实现多个接口是因为接口只有声明没有定义
继承和聚合
-
继承:类继承另一个类、接口继承另一个接口并增加自己的新功能,Java中用extends关键字标识
-
聚合:一种特殊的关联关系,体现整体与部分的关系,整体与部分之间可分离,可以具有自己的生命周期,部分可以属于多个整体,也可以被整体共享
final
-
final修饰的类叫最终类,最终类不能被继承
-
final修饰的方法不能被重写
-
final修饰的变量是常量,常量必须初始化,且初始化后不能修改
不需要重写hashcode和equals方法的情况
-
类的每个实例本质上都是唯一的
-
不关心类是否提供了“逻辑相等”的测试功能
-
从超类继承过来的equals对子类是合适的
-
类是私有的,可以保证它的equals方法永远不会被调用
hashcode的作用及与equals的关系
-
提供了对象的hashCode值,这个值是对象头部的一部分二进制位组成的数字,具有一定的标识对象的意义
-
作用:在HashMap和HashSet中作为对象的key值
-
equals相等的两个对象hashcode一定相等,hashcode相等的两个对象不一定equals相等
访问修饰符:public、protect、default和private
-
public:所有类可见
-
protect:本包和所有子类可见
-
default:本包可见
-
private:本类可见
深拷贝&浅拷贝
-
深拷贝:复制值,复制整个对象,不同对象之间互不影响
-
浅拷贝:对引用类型的对象来说,复制引用,不复制整个对象,一个对象对内容的修改会对其余的对象带来影响
-
与C++由于浅复制导致的野指针相比,Java的深复制和浅复制的影响没有那么显著
数组和链表
-
内存空间:数组连续、链表不连续
-
访问:数组支持随机访问、链表不支持
-
插入和删除:中间位置的插入和删除,数组需要移动元素时间复杂度O(n),链表不需要移动元素,时间复杂度O(1)
-
查找:无序情况下都是O(n),有序情况下,数组可以通过二分查找将时间复杂度变为O(logn)
-
扩容:数组需要移动和拷贝,额外的时间开销,链表不需要额外开销
-
占用内存:链表需要存储上一个节点和下一个节点的指针,占用内存更多
error和exception
-
Throwable是所有异常的根,Error表示错误信息,Exception表示异常信息
-
Exception
-
Checked异常:可以被处理的异常,Java程序必须显式处理该异常,包括Java.lang.ClassNotFoundException/Java.lang.NoSuchMethodException/Java.io.IOException
-
当前方法知道如何处理该异常,用try...catch处理
-
当前方法不知道如何处理,直接抛出异常
-
-
Runtime异常:除数是0,数组越界等产生频繁,处理麻烦的异常,显示声明对程序可读性和运行效率影响很大,因此由系统检测并交给缺省的异常处理程序,包括Java.lang.ClassCastException/Java.lang.IndexOutOfBoundsException/Java.lang.NullPointerException/Java.lang.ArithmeticException/Java.lang.ArrayStoreExcetpion
-
-
Error
-
程序发生不可控错误时的提示信息,由Java虚拟机生成并抛出,包括动态连接失败、虚拟机错误等,程序不处理,通知用户并终止程序执行
-
泛型
-
泛型的本质是参数化类型,所操作的数据类型被指定为一个参数
-
在编译时检查类型安全,所有强制转换是自动和隐式的,提高代码重用率
HashSet
-
底层是基于HashMap实现
-
需要重写hasCode和equals函数
==和equals
-
==对基本数据类型来说是值比较,对引用数据类型来说是引用比较
-
equals默认情况下是引用比较,但是String和Integer重写了该方法,变成了值比较
Java I/O流
-
按功能划分:输入流和输出流
-
按类型划分:字节流和字符流
-
字节流:以字节为单位输入输出数据(8位)
-
字符流:以字符为单位输入输出数据(16位)
-
List、Set和Map
-
List和Set继承了Collection接口
-
Set和Map有key的概念在,List没有Key的概念
-
List的元素可以重复,Set(equals判断)和Map的元素不可以重复
-
List是有序的,HashSet和HashMap是无序的
-
List的Vector是线程安全的,Hashtable是线程安全的
Vector和List之间的转换
-
Vector转List:调用Arrays的asList方法
-
List转Array:调用ArrayList的toArray方法
Vector和ArrayList
-
Vector是同步的,ArrayList是异步的,ArrayList会更快一些,不会过载
-
ArrayList更加通用,可以使用Collections工具类获取同步列表和只读列表
Array和ArrayList
-
Array可以容纳基本类型和对象,ArrayList只能容纳对象
-
Array指定大小,ArrayList初始大小固定
-
Array比ArrayList功能少,包括addAll、removeAll、iterator等
queue中poll()和remove()的区别
-
联系:都是从队列中取元素
-
区别
-
poll取不到返回空
-
remove取不到抛出异常
-
线程安全的集合类
-
Vector:比ArrayList多了同步机制,但是效率低,不建议用
-
Stack
-
Hashtable
-
enumeration:枚举,相当于迭代器
迭代器iterator
-
一种设计模式
-
一个“轻量级”对象,创建代价小
-
可以在不了解序列底层结构的前提下,遍历并选择序列中的对象
-
公共基类Collection提供iterator方法
Iterator和ListIterator
-
Iterator可以遍历Set和List,ListIterator只能遍历List
-
Iterator只能单向移动,ListIterator可以双向移动
-
ListIterator实现了Iterator接口,并包含其它的功能,如增加、替换等
Synchronized和volatile
-
volatile本质是告诉JVM当前变量的值在寄存器或内存中是不确定的,需要从主存中读取;synchronized是锁定当前变量,只能被当前线程读取,其它线程被阻塞
-
volatile仅能使用在变量级别;synchronized可以使用在变量、方法和类级别
-
volatile只能保证变量的修改可见性,上一年吃肉你这都能保证变量的修改可见性和原子性
-
volatile不会造成线程的阻塞,synchronized会造成线程的阻塞
-
volatile标记的变量不会被编译器优化;synchronized标记的变量可以被编译器优化
-
在访问volatile变量时不会执行加锁操作,因此也就不会使执行线程阻塞,因此volatile变量是一种比sychronized关键字更轻量级的同步机制。
switch关键字可以接受的类型
-
byte、char、short、int、string、enum
HashMap&HashTable&ConcurrentHashMap
-
HashMap:非线程安全,无法保证并发安全性
-
HashTable:线程安全
-
阻塞的,锁住整张表
-
优:可以保证总是能拿到更新后的数据
-
缺:所有调度都需要排队,效率比较低
-
-
ConcurrentHashMap:线程安全
-
非阻塞的,更新的时候只锁住部分表,读取的时候是完全并发的,jdk1.7通过分段锁实现,jdk1.8通过CSA+Synchronized实现,数据结构是数组+链表+红黑树
-
优点:调度合理的情况下,效率较高
-
缺点:读取操作不能保证反应最近的更新
-
Servlet
-
运行在Web服务器或应用服务器上的Java类,作为来自Web浏览器或其它http客户端的请求和HTTP服务器上的数据库或应用程序之间的中间层
-
任务:读取客户端发送的数据、处理数据并生成结果、发送数据到客户端
-
Servlet过滤器可以动态拦截请求和响应,以变换或使用包含在请求或响应中的信息