马士兵
- 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 数组+链表/红黑树
来源:https://www.cnblogs.com/qiming666/p/16460412.html
本站部分图文来源于网络,如有侵权请联系删除。