百木园-与人分享,
就是让自己快乐。

2022-7-7学习日记

马士兵

  1. String、StringBuffer SttingBuiler
    1. String 是final修饰的,不可变的,每次操作都会产生新的String对象
    2. StringBuffer是线程安全的
    3. StringBuiler是线程不安全的
    4. 优先使用StringBuilder,多线程时使用String Buffer
  2. jdk1.7到jdk1.8虚拟机发生了哪些变化
    1. 1.7有永久代、1.8没有永久代,有元空间,元空间不是在虚拟机内部,在本地内存空间。
    2. 不管是永久代和元空间都是方法区的具体实现
    3. Jrockit统一
    4. 方法区存储的类信息通常是难以确定的,所以对于方法区的大小难以指定,太小容易方法区溢出,太大占用太多虚拟机空间内存,本地内存则不会影响虚拟机的内存
  3. Arraylist和LinkedList
    1. Arraylist 是数组实现 适合随机查找
    2. LinkedList 链表实现 适合删除、添加。
    3. 都实现了list接口,Linklist还实现了Deque接口,所以Linklist可以当作双端队列来使用
  4. GC如何判断对象可以被回收
    1. 引用计数法,没IgE 对象有一个引用计数属性,新增一个引用就加一,引用释放就减一,当为0时就会被回收,python采用,java不采用,互相引用就永远无法被回收,效率很高
    2. 可达性分析法,GCRoots开始向下搜索,能找到的对象就不会被回收,没被找到的对象会被回收,java采用
  5. GCRoots的对象
    1. 虚拟机栈中引用的对象(new出来的)
    2. 方法区中类静态属性引用的对象
    3. 方法区中常量引用的对象
    4. 本地方法栈中 Native方法 引用的对象
    5. -----------
    6. 第一次会被标记,第二次会在虚拟机中自动建立的Finalizer队列中判断是否需要执行Finalize方法
    7. 如果对象不可达时,GC先判断对象是否覆盖额finalize方法,如果未覆盖则会直接回收,如果覆盖了未执行过就会放入F-Queue队列,由一低优先级现场执行队列中对象的finalize方法,执行finalize方法完毕后,GC 再次判断对象是否可达,若不可达,则进行回收,否则对象“复活”
  6. java类加载器
    1. bootstrap classloader。加载java home下的jar包和class文件,是ext的父类
    2. extClassLoader。是app的父类加载器,是负责加载java home 下lib/ext下的jar包和class文件
    3. AppClassLoader。是自定义加载器的父类,负责加载classpath下的类文件,是系统类加载器,也是线程上下文加载器
  7. java内存结构
    1. 年轻代
      1. edon区 伊甸区  8
      2. surivor 区 1
      3. surivor 区 1
    2. 老年代
    3. 年龄在15之后进入老年代
  8. 什么是字节码,采用字节码的好处是什么
    1. 字节码是class文件
    2. class文件是面向jvm的
    3. jvm是面向操作系统的
    4. 好处,效率提高,跨平台
  9. 高并发的集合有哪些问题
    1. 第一代线程安全集合
      1. vector、hashtable
      2. 使用synchronized修饰方法
      3. 效率低下
    2. 第二代线程非安全集合
      1. arraylist、hashmap
      2. 不安全、效率高
      3. Collections.synchronizedList(list)、Collections.ssynchronizedMap(map)来保证线程安全
    3. 第三代线程安全集合
      1. ConcurrentHashMap
      2. CopyOnWriteArraylist
      3. CopyOnWriteArraySet
      4. 采用Lock锁,保证安全同时效率高

 
黑马程序员 面试专题 关闭弹幕

  1. 二分查找
    1. 解决数字溢出问题:0~int最大值-1,二分查找到中间向右的时候
      1. begin + (end-begin)/2
      2. (begin + end)>>> 1
    2. 二分查找的最多次数是 log 2  N =2 ^N
  2. 冒泡排序
    1. 优化
      1. 每一轮排序后最后一个是最大的,所以最后一个不需要比较。每一轮可以减少一次比较
      2. 假如最后一轮比较没有发生交换,说明数组已经排好序了
      3. 记录下最后一次比较的i的位置,下次比较的次数就是i次
  3. 选择排序
    1. 每一轮 选择一个最小的放到前面
    2. 选择和冒泡 的事件负责度都是n^2
    3. 选择快于冒泡
    4. 如果集合有序度高,则冒泡优于选择
    5. 冒泡属于稳定排序算法,选择属于不稳定排序
  4. 插入排序
    1. 分 有序区和无序区
    2. 将无序区的第一个元素插入有序区
    3. 稳定算法,效率高于选择。时间复杂度n
  5. 希尔排序
    1. 先分组进行插入排序,再合并在分组再排序
    2. 假如有八个元素,则分组间隔为 4  2  1
  6. 快速排序
    1. 分而治之的思想
    2. 先选一个,然后将比他小的放左边,比他大的放右边,这轮结束后,这个数字的位置就是最终位置。
    3. 单边循环快排
      1. 选择最右的元素作为基准点
      2. j指针负责找到比基准点小的元素,找到就和i交换
      3. i指针维护小于基准点元素的边界,也是每次交换的目标索引
      4. 最后基准点与i交换,i即为分区位置
    4. 双边循环快排
      1. 选择最左元素作为基准点
      2. j指针负责从右边向左找比基准点小的元素,i指针负责从左向右找比基准点大的元素,一旦找到二者交换,直至i,j相交
      3. 最后基准点与i(此时i与j相等)交换,i即为分区位置
    5. 快排 平均时间复杂度 nlog2n   最坏n^2
    6. 数据量大,优势很大
    7. 不稳定排序
  7. ArrayList
    1. Arraylist默认0个容量,当添加第一个元素则会扩容成10的容量,超过10个则扩容,扩容为原来的1.5倍。过程是先创建一个新的数组,再将原来的数组放入新数组。
    2. List.addAll ,假如要添加11个元素,addAll则会从11和10选一个大的数字来扩容
    3. 迭代器
      1. fail-fast 便利过程中,不允许修改集合,修改马上抛出异常,ArrayList采用
      2. fail-safe 遍历的同时有人来修改,则有对应的应对策略,copyonWriteArraylist 采用,假如迭代的过程中新增了一个新元素,则当前循环不会执行到新元素。
    4. 实现了randomAccess接口,系统发现实现了这个接口,则会通过下标方式访问
    5. 可以利用cpu缓存,局部性原理
  8. LinkedList
    1. 双向链表,随机访问慢,头插尾插快,占用内存多,头尾插删快
  9. HashMap
    1. 1.7 数组+链表。 1.8 数组+链表/红黑树

来源:https://www.cnblogs.com/qiming666/p/16460412.html
本站部分图文来源于网络,如有侵权请联系删除。

未经允许不得转载:百木园 » 2022-7-7学习日记

相关推荐

  • 暂无文章