并发编程有三大问题
(1)CPU 缓存,在多核 CPU 的情况下,带来了可见性问题
(2)操作系统对当前执行线程的切换,带来了原子性问题
(3)译器指令重排优化,带来了有序性问题
什么是Java的内存模型?
原由:
在了解什么是 Java 内存模型之前,先了解一下为什么要提出 Java 内存模型。
为了解决并发编程的三大问题,提出了 JSR-133,新的 Java 内存模型,JDK 5 开始使用。
Java 内存模型是JVM的一种规范
(1)定义了共享内存在多线程程序中读写操作行为的规范
(2)屏蔽了各种硬件和操作系统的访问差异,保证了 Java 程序在各种平台下对内存的访问效果一致
(3)解决并发问题采用的方式:限制处理器优化和使用内存屏障
(4)增强了三个同步原语(synchronized、volatile、final)的内存语义
(5)定义了happens-before规则
在Java中,重载和重写使用时机
(1)重载是多态的集中体现,在类中,要以统一的方式处理不同类型数据时
(2)重写的使用是建立在继承关系上的,子类在继承父类的基础上,增加新的功能时
总结:
重载是多样性,目的是提高程序的多样性和健壮性,以适配不同场景使用时,使用重载进行扩展
重写是增强剂,目的是在不修改原方法及源代码的基础上对方法进行扩展或增强时,使用重写
实例化对象的方式
(1)new
(2)clone()
(3)反射
//用 Class.forName方法获取类,在调用类的newinstance()方法
Class<> cls = Class.forName("com.dao.User");
User u = (User)cls.newInstance();
(4)序列化反序列化
//将一个对象实例化后,进行序列化,再反序列化,也可以获得一个对象(远程通信的场景下使用)
ObjectOutputStream out = new ObjectOutputStream (new FileOutputStream("D:/data.txt"));
//序列化对象
out.writeObject(user1);
out.close();
//反序列化对象
ObjectInputStream in = new ObjectInputStream(new FileInputStream("D:/data.txt"));
User user2 = (User) in.readObject();
System.out.println("反序列化user:" + user2);
in.close();
byte类型127+1等于多少
byte的范围是-128~127
字节长度为8位,最左边的是符号位,而127的二进制为01111111,所以执行+1操作时,01111111变为10000000。
大家知道,计算机中存储负数,存的是补码的兴衰。左边第一位为符号位。
那么负数的补码转换成十进制如下:
一个数如果为正,则它的原码、反码、补码相同;一个正数的补码,将其转化为十进制,可以直接转换。
已知一个负数的补码,将其转换为十进制数,步骤如下:
先对所有位进行取反;
将其转换为十进制数;
加上负号,再减去1;
例如10000000,最高位是1,是负数,①对各位取反得01111111,转换为十进制就是127,加上负号得-127,再减去1得-128;
Collection和Collections的区别
(1)Collection是最基本的集合接口
(2)Collections是一个包装类,它包含各种有关集合操作的静态方法(对集合的搜索、排序、线程安全化等)
list与Set
(1)List
ArrayList:由数组实现的List。允许对元素进行快速随机访问,但是向List中间插入与移除元素的速度很慢
LinkedList :对顺序访问进行了优化,向List中间插入与删除的开销并不大。随机访问则相对较慢
(2)Set
Set具有与Collection完全一样的接口,因此没有任何额外的功能。实际上Set就是Collection,只是行为不同
存入Set的每个元素都必须是唯一的,因为Set不保存重复元素。加入Set的元素必须定义equals()方法以确保对象的唯一性。Set与Collection有完全一样的接口。Set接口不保证维护元素的次序
HashSet:为快速查找设计的Set。存入HashSet的对象必须定义hashCode()
TreeSet: 保存次序的Set, 底层为树结构。使用它可以从Set中提取有序的序列
(3)list与Set区别
相同点:List,Set都是继承自Collection接口
List:元素有放入顺序,元素可重复
和数组类似,List可以动态增长,查找元素效率高,插入删除元素效率低,因为会引起其他元素位置改变
Set:元素无放入顺序,元素不可重复,重复元素会覆盖掉
检索元素效率低下,删除和插入效率高,插入和删除不会引起元素位置改变
HashMap 和 Hashtable 有什么区别?
(1)HashMap是线程不安全的,HashTable是线程安全的
(2)HashMap中允许键和值为null,HashTable不允许
(3)HashMap的默认容器是16,为2倍扩容,HashTable默认是11,为2倍+1扩容
数组和 List 之间的转换
String[] arr = {"zs","ls","ww"};
List<String> list = Arrays.asList(arr);
System.out.println(list);
ArrayList<String> list1 = new ArrayList<String>();
list1.add("张三");
list1.add("李四");
list1.add("王五");
String[] arr1 = list1.toArray(new String[list1.size()]);
System.out.println(arr1);
for(int i = 0; i < arr1.length; i++){
System.out.println(arr1[i]);
}
集合类是线程安全的
Vector:就比Arraylist多了个同步化机制(线程安全)
Stack:栈,也是线程安全的,继承于Vector
Hashtable:就比Hashmap多了个线程安全
ConcurrentHashMap:是一种高效但是线程安全的集合
迭代器 Iterator
为了方便的处理集合中的元素,Java中出现了一个对象,该对象提供了一些方法专门处理集合中的元素.例如删除和获取集合中的元素.该对象就叫做迭代器(Iterator)
使用
(1)java.lang.Iterable 接口被 java.util.Collection 接口继承,java.util.Collection 接口的 iterator() 方法返回一个 Iterator 对象
(2)next() 方法获得集合中的下一个元素
(3)hasNext() 检查集合中是否还有元素
(4)remove() 方法将迭代器新返回的元素删除
Iterator 和 ListIterator 有什么区别
(1)ListIterator 继承 Iterator
(2)ListIterator 比 Iterator多方法
(3)使用范围不同,Iterator可以迭代所有集合;ListIterator 只能用于List及其子类