马士兵
-
String、StringBuffer SttingBuiler
-
String 是final修饰的,不可变的,每次操作都会产生新的String对象
-
StringBuffer是线程安全的
-
StringBuiler是线程不安全的
-
优先使用StringBuilder,多线程时使用String Buffer
-
-
jdk1.7到jdk1.8虚拟机发生了哪些变化
-
1.7有永久代、1.8没有永久代,有元空间,元空间不是在虚拟机内部,在本地内存空间。
-
不管是永久代和元空间都是方法区的具体实现
-
Jrockit统一
-
方法区存储的类信息通常是难以确定的,所以对于方法区的大小难以指定,太小容易方法区溢出,太大占用太多虚拟机空间内存,本地内存则不会影响虚拟机的内存
-
-
Arraylist和LinkedList
-
Arraylist 是数组实现 适合随机查找
-
LinkedList 链表实现 适合删除、添加。
-
都实现了list接口,Linklist还实现了Deque接口,所以Linklist可以当作双端队列来使用
-
-
GC如何判断对象可以被回收
-
引用计数法,没IgE 对象有一个引用计数属性,新增一个引用就加一,引用释放就减一,当为0时就会被回收,python采用,java不采用,互相引用就永远无法被回收,效率很高
-
可达性分析法,GCRoots开始向下搜索,能找到的对象就不会被回收,没被找到的对象会被回收,java采用
-
-
GCRoots的对象
-
虚拟机栈中引用的对象(new出来的)
-
方法区中类静态属性引用的对象
-
方法区中常量引用的对象
-
本地方法栈中 Native方法 引用的对象
-
-----------
-
第一次会被标记,第二次会在虚拟机中自动建立的Finalizer队列中判断是否需要执行Finalize方法
-
如果对象不可达时,GC先判断对象是否覆盖额finalize方法,如果未覆盖则会直接回收,如果覆盖了未执行过就会放入F-Queue队列,由一低优先级现场执行队列中对象的finalize方法,执行finalize方法完毕后,GC 再次判断对象是否可达,若不可达,则进行回收,否则对象“复活”
-
-
java类加载器
-
bootstrap classloader。加载java home下的jar包和class文件,是ext的父类
-
extClassLoader。是app的父类加载器,是负责加载java home 下lib/ext下的jar包和class文件
-
AppClassLoader。是自定义加载器的父类,负责加载classpath下的类文件,是系统类加载器,也是线程上下文加载器
-
-
java内存结构
-
年轻代
-
edon区 伊甸区 8
-
surivor 区 1
-
surivor 区 1
-
-
老年代
-
年龄在15之后进入老年代
-
-
什么是字节码,采用字节码的好处是什么
-
字节码是class文件
-
class文件是面向jvm的
-
jvm是面向操作系统的
-
好处,效率提高,跨平台
-
-
高并发的集合有哪些问题
-
第一代线程安全集合
-
vector、hashtable
-
使用synchronized修饰方法
-
效率低下
-
-
第二代线程非安全集合
-
arraylist、hashmap
-
不安全、效率高
-
Collections.synchronizedList(list)、Collections.ssynchronizedMap(map)来保证线程安全
-
-
第三代线程安全集合
-
ConcurrentHashMap
-
CopyOnWriteArraylist
-
CopyOnWriteArraySet
-
采用Lock锁,保证安全同时效率高
-
-
黑马程序员 面试专题 关闭弹幕
-
二分查找
-
解决数字溢出问题:0~int最大值-1,二分查找到中间向右的时候
-
begin + (end-begin)/2
-
(begin + end)>>> 1
-
-
二分查找的最多次数是 log 2 N =2 ^N
-
-
冒泡排序
-
优化
-
每一轮排序后最后一个是最大的,所以最后一个不需要比较。每一轮可以减少一次比较
-
假如最后一轮比较没有发生交换,说明数组已经排好序了
-
记录下最后一次比较的i的位置,下次比较的次数就是i次
-
-
-
选择排序
-
每一轮 选择一个最小的放到前面
-
选择和冒泡 的事件负责度都是n^2
-
选择快于冒泡
-
如果集合有序度高,则冒泡优于选择
-
冒泡属于稳定排序算法,选择属于不稳定排序
-
-
插入排序
-
分 有序区和无序区
-
将无序区的第一个元素插入有序区
-
稳定算法,效率高于选择。时间复杂度n
-
-
希尔排序
-
先分组进行插入排序,再合并在分组再排序
-
假如有八个元素,则分组间隔为 4 2 1
-
-
快速排序
-
分而治之的思想
-
先选一个,然后将比他小的放左边,比他大的放右边,这轮结束后,这个数字的位置就是最终位置。
-
单边循环快排
-
选择最右的元素作为基准点
-
j指针负责找到比基准点小的元素,找到就和i交换
-
i指针维护小于基准点元素的边界,也是每次交换的目标索引
-
最后基准点与i交换,i即为分区位置
-
-
双边循环快排
-
选择最左元素作为基准点
-
j指针负责从右边向左找比基准点小的元素,i指针负责从左向右找比基准点大的元素,一旦找到二者交换,直至i,j相交
-
最后基准点与i(此时i与j相等)交换,i即为分区位置
-
-
快排 平均时间复杂度 nlog2n 最坏n^2
-
数据量大,优势很大
-
不稳定排序
-
-
ArrayList
-
Arraylist默认0个容量,当添加第一个元素则会扩容成10的容量,超过10个则扩容,扩容为原来的1.5倍。过程是先创建一个新的数组,再将原来的数组放入新数组。
-
List.addAll ,假如要添加11个元素,addAll则会从11和10选一个大的数字来扩容
-
迭代器
-
fail-fast 便利过程中,不允许修改集合,修改马上抛出异常,ArrayList采用
-
fail-safe 遍历的同时有人来修改,则有对应的应对策略,copyonWriteArraylist 采用,假如迭代的过程中新增了一个新元素,则当前循环不会执行到新元素。
-
-
实现了randomAccess接口,系统发现实现了这个接口,则会通过下标方式访问
-
可以利用cpu缓存,局部性原理
-
-
LinkedList
-
双向链表,随机访问慢,头插尾插快,占用内存多,头尾插删快
-
-
HashMap
-
1.7 数组+链表。 1.8 数组+链表/红黑树
-