这个国庆,打算把自己梳理过的一些java后端的面试考点梳理一下,简单的将自己的笔记整理发上来,都是一些八股文,可以根据这些由浅入深的学习下去,给大家一个方向,也方便我保存。。那么进入正题。
java题库
java面试大多出自以下技术栈:java基础知识,集合容器,并发编程,JVM,Spring全家桶,MyBatis等ORMapping框架,MySQL数据库,Redis缓存,RabbitMQ消息队列,Linux操作技巧等
BigDecimal
float和double主要为了科学计算和工程计算。他们执行二进制浮点运算,为了在广域数值范围上提供较为精确的快速近似计算而精心设计的,但是没有提供完全精确的结果,所以在用于精确结果的场合,要用上BigDecimal
浮点数没有办法用二进制进行精确计算,CPU表示浮点数由两个部分组成:指数和尾数。这样的表示方法会失去精确度。
BigDecimal构造方法
public BigDecimal(double val) 将double表示形式转换为BigDecimal*不建议使用
public BIgDecimal(int val) 将int表示形式转换为BigDecimal
public BigDecimal(String val) 将String表示形式转换为BigDecimal
对于常用的加减乘除,BigDecimal提供了相应的成员方法
public BigDecimal add(BigDecimal value) //加法
public BigDecimal subtract(BigDecimal value) //减法
public BigDecimal multiply(BigDecimal value) //乘法
public BigDecimal divide(BigDecimal value) //除法
a.add(b); a+b
a.subtract(b) a-b
a.multiply(b) a*b
a.divide(b) a/b
java中操作字符串有哪些类,区别?
解:
有String,StringBuffer,StringBuilder
String,StringBuffer,StringBuilder的区别,String声明是不可变的对象,每次操作都会生成新的String,并将指针指向新的String地址。
StringBuffer和StringBuilder可以在原有对象的基础上进行操作,是可变象,所以在经常改变字符串内容的情况下最好不用String
StringBuffer和StringBuilder最大区别在于,StringBuffer线程安全,但是性能低,多线程推荐,或者要求运行安全的情况下推荐
StringBuilder线程不安全,性能较高,在单线程的情况下推荐使用
在效率上,StringBuilder>StringBuffer>String
原因?
String是字符串常量,也是不可改变的对象
public final class String{}
StringBuffer是字符串变量(有同步锁)
StringBuilder是字符串变量(无同步锁)
所以,为了应对经常性操作字符串的场景,java才提供了其他两个操作字符串的类,StringBuffer,StringBuilder。我们用它们对字符串做操作时,实际上是在一个对象上操作的,不会像String创建其他地址对象。
StringBuffer、StringBuilder
使用方法,对于StringBuffer、StringBuilder,主要操作是append和insert方法。这些方法允许被重载,接收任意类型的数据,每个方法都能有效地将给定的数据转换为字符串,然后将字符串的字符追加或插入到字符串缓冲区。
区别在于:append始终添加到缓冲区的末端。
insert指定的点(index)添加字符
1.StringBuilder一个可变的字符序列是JDK1.5新增的,此类提供一个与StringBuffer兼容的API,但不保证同步,是StringBuffer的简易替换,用在字符串缓冲区被单个线程使用的时候
2.建议优先采用StringBuilder类,因为在大多数实现中,它比StringBuffer要快,但是!!如果要求线程安全,必须使用StringBuffer
3.在经常改变字符串的内容时,不要用String,当无引用对象过多以后,JVM的GC开始工作,速度相当缓慢,且当new String的速度>GC的速度的时候,会导致内存溢出ERROR。OutOfMemoryError
StringBuffer、StringBuilder的线程安全
StringBuffer允许多线程进行字符串操作,因为在源代码中StringBuffer的很多方法都被synchronized了,同步锁。
synchronized的含义:
锁,当一个对象加了锁以后,必须等它运行完才能。保证在同一个时刻,其他线程只能处于等待状态,直到当前线程处理完释放锁。可保证一个线程的变化(主要是共享数据的变化)被其他线程所看到(保证可见性,完全可以替换Volatile功能)
实际应用场景中:
1.如果不是在循环体中进行字符串拼接的话,直接用String的"+"就行
2.单线程循环中操作大量字符串数据——》StringBuilder.append();添加到缓冲区末端
3.多线程循环中操作大量字符串数据——》StringBuffer.append();添加到缓冲区末端
数据结构
Deque
线性集合,支持两端的元素插入与移除,习惯上称为双端队列。大多数Deque实现对它们可能包含的元素的数量没有固定的限制,但是该接口支持容量限制的deques以及没有固定大小限制的deque。
方法集合
打开IDEA,输入Deque,鼠标右键+ctrl,自己看。
对比Vector、ArrayList、LinkedList有何区别
三者都是实现了集合框架中的List,也就是有序集合,所以功能也类似,都有提供按照位置进行定位,添加,删除等操作,都是提供迭代器以遍历其内容等。但因为具体设计区别,在行为、性能、线程安全等方面表现不同
Vector
是java早期提供的线程安全的动态数组,如果不需要线程安全,并不建议使用,因为同步要有额外的开销
vector内部是使用对象数组来保存数据,可以根据需要自动增加容量,当数组已满,扩容时,会先创建新的扩容后数组,并拷贝原有数组数据,最后删除原数组
ArrayList(擅长”查询“和更新)
动态数组实现,本身线程不安全,性能高,扩容是增加50%,与Vector不同,它是增加1倍
与LinkedList区别
- 数据结构:ArrayList是动态数组的数据结构
- 随机查询效率:(优势)ArrayList》LinkedList,因为LinkedList是线性的存储方式,需要移动指针从前往后依次查找,而ArrayList只要根据下标index就能锁定
- 插入和删除:(劣势)因为ArrayList增删操作要影响数组内其他数据的下标(整体移动),但是如果是尾插,那大体相同
- 内存占用:(优势)因为LinkedList的节点除了存储数据,还存储了两个引用,一个指向前的一个,一个指向后的一个
LinkedList(”插入“和”删除“)
java提供的双向链表,所以不需要像上面两种那样调整容量,但也不是线程安全的
- 数据结构:双向链表
- 插入和删除:(优势)LinkedList按序号查询数据时需要进行前向或后向遍历,插入数据时只需要记录当前项的前后项即可,增删时也只需要修改链表指向即可,所以效率高
多线程下怎么用ArrayList
增加Collections的synchronized方法,将其转换成线程安全的容器后再使用
List<String> syncList = Collections.synchronizedList(arratlist);
List和Set有哪些区别
都是继承Collection接口
区别:
-
重复对象
list可以重复对象,set不允许重复对象
-
null元素
list可以有多个null元素,set只允许一个null元素
-
是否有序
list是一个有序容器,保持了每个元素的插入顺序,即输入顺序就是输出顺序
set是一个无序容器,无法保证每个元素的存储顺序(注意:TreeSet是有序的,通过自然排序或Comparator进行排序)
-
常用实现类
list常用实现类:ArrayList、LinkedList和Vector。如上所述,ArrayList最常用,提供索引index访问,定位、查询效率高。LinkedList索引,删除、插入等更适用。Vector线程安全,但因为效率低被边缘化
Set常用实现类:HashSet、TreeSet(继承SortedSet)、LinkedHashSet。最常用的是基于HashMap实现的HashSet,其中TreeSet实现了SortedSet接口,所以可以用compare和compareTo方法进行排序的有序容
-
遍历方式:
List因为存在下标,所以可用迭代器(iterator)或者遍历实现。而Set因为没有下标且无序,所以只能用遍历实现
、
那今天就先到这里,明天着重梳理面试的必中考点hash。