面试之java知识

目录

一、基础

二、NIO

三、jvm

四、多线程

五、容器

六、并发容器


一、基础

1、与kotlin的区别

语法简洁、非空安全性调用、支持协程、原型扩展函数等

http://157.7.135.42/kotlin/docs/reference/server-overview.html

2、serialVersionuUid
https://www.cnblogs.com/duanxz/p/3511695.html

如果序列化和反序列化的serialVersionUid不同,则会反序列化会失败;

static变量不会序列化,

transient变量不参与序列化,

 父类需要显示说明是否序列化;

3、ArrayList的subList

返回的是ArrayList的视图,最终的操作会反馈到原ArrayList上

4、Arrays.asList

体现的是适配器模式,只是转换接口,不支持add/remove/clear方法,并且最终的修改也会反馈到原数组,因为内部的操作针对的都是原始数组

5、不在foreach循环中对元素进行remove/add

6、comparator要遵循自反性、传递性、对称性

在 JDK7/JDK8(当前JDK8),Comparator 要满足自反性、传递性、对称性,不然 Arrays.sort,Collections.sort 会报 IllegalArgumentException 异常。(JDK7 Comparator,JDK8 Comparator)

说明:

1) 自反性:x,y 的比较结果和 y,x 的比较结果相反。

2) 传递性:x>y,y>z,则 x>z。

3) 对称性:x=y,则 x,z 比较结果和 y,z 比较结果相同。

7、SimpleDateFormat是线程不安全的类,不能定义为static。jdk8之后可以换新的时间日期API

8、finally块不能包含return块,finally块中的return返回后方法结束执行,不会再执行try或catch中的return语句

9、异常体系

二、NIO

https://www.cnblogs.com/wangcq/p/3520400.html

http://gee.cs.oswego.edu/dl/cpjslides/nio.pdf

基于上面的交互,将其细分:read、decode、process、encode、send,然后细分几个事件,每个handler只负责处理相应的事件,各司其职,也就不用一直等待其他的事件结束,将一个串行处理变成了并行处理,类似CPU的指令执行

(这是我自己的一种理解,如错误,望指正)

三、jvm

1、类加载初始化

1.父类静态成员和静态初始化快,按在代码中出现的顺序依次执行。

2.子类静态成员和静态初始化块,按在代码中出现的顺序依次执行。

3. 父类的实例成员和实例初始化块,按在代码中出现的顺序依次执行。

4.执行父类的构造方法。

5.子类实例成员和实例初始化块,按在代码中出现的顺序依次执行。

6.执行子类的构造方法。

2、classload双亲委派

加载时,都先由父加载器加载,如果加载不到,则由子加载器加载,这样的优点是:保证了java类型的的最基础的行为,各个加载器的基础类的统一,比如java.lang.Object不论在哪都是唯一的,因为其他的类加载器都加载不到自定义的java.lang.Object

3、内存区域

4、内存模型

原子性、

可见性:一个线程修改了共享变量的值,其他线程可以看到,volatile,synchronize

有序性:单一线程里有序,不同线程间无序

5、垃圾收集算法

标记-清除算法:效率不高;碎片问题

复制算法:内存缩小为原来的一半,需要有担保策略

标记-整理:基于标记-清除,但是会将所有存活对象整理到一端

分代回收

6、垃圾收集器

https://blog.csdn.net/havedream_one/article/details/88381530

四、多线程

1、线程状态转换

blocked:等待锁

waiting:等待其他事件

(没太清楚有什么区别,?)

线程池

https://blog.csdn.net/havedream_one/article/details/87783594

2、转换相关的基础函数

1. Object   wait、notify、notifyAll

2. LuckSupport  park、unpark

3. synchronize

4. Thread  sleep、join、yield

3、Unsafe

直接原子操作内存地址

4、LockSupport

提供了阻塞线程和唤醒线程的功能

和wait和notify的区别是,无需同步块

5、AQS

当我们自定义一个同步器时,首先需要一个代表资源的变量,其是线程可见的(private volatile int state),接着需要一个队列,保存着所以等待资源的线程(CLH队列),然后需要原子的操作资源(Unsafe);

基本上AQS也是这样的一个原理,但是它是一个抽象的同步器,具体的资源请求和释放是由子类来实现。

AQS相当于一个同步器模板,其他的基于这个模板实现即可

故有几个抽象方法

protected boolean tryAcquire(int arg) {
    throw new UnsupportedOperationException();
}
protected boolean tryRelease(int arg) {
    throw new UnsupportedOperationException();
}
protected int tryAcquireShared(int arg) {
    throw new UnsupportedOperationException();
}
protected boolean tryReleaseShared(int arg) {
    throw new UnsupportedOperationException();
}
protected boolean isHeldExclusively() {
    throw new UnsupportedOperationException();
}

子类不需要每个方法都实现,只需要选择适合自己的就行

https://www.cnblogs.com/200911/p/6031350.html

https://juejin.im/post/5d37019a51882564c966add6

6、可重入锁ReentrantLock

如果获取到锁,则可一直重新进入,实现原理:判断是自身,则直接获取到资源

state:0表示可以获取到锁,如果大于0,表示已经有线程获取到锁。

7、CyclicBarrier

作用:实现某些线程一起执行的作用

维护几个变量:count,reentrantLock,Condition

count用来记录当前阻塞的线程,当线程调用CyclicBarrier.await时,count--,如果count不为0,则当前线程阻塞Condition.await;如果count为0,则调用Condition.signalAll唤醒所有等待线程继续执行;reentrantLock在此处的作用是count--的线程安全。

8、CountDownLatch

作用:await等待多个线程执行完毕,再继续执行

内部实现了AQS的两种方法:

class CountDownLatch{
    ...
    class Sync extends AbstractQueuedSynchronizer{

        //这个count就是我们设置的count
        Sync(int count) {
            setState(count);
        }
        
        //直到state == 0,才说明可以获取到锁,否则就阻塞
        protected int tryAcquireShared(int acquires) {
            return (getState() == 0) ? 1 : -1;
        }
        
        //每次执行countDown,state--,直到0
        //只有最后一个才会去唤醒阻塞的线程,唤醒一个还是唤醒所有呢?
        protected boolean tryReleaseShared(int releases) {
            // Decrement count; signal when transition to zero
            for (;;) {
                int c = getState();
                if (c == 0)
                    return false;
                int nextc = c-1;
                if (compareAndSetState(c, nextc))
                    return nextc == 0;
            }
        }
    }
    ...
    //最终会调用tryAcquireShared
    public void await() throws InterruptedException {
        sync.acquireSharedInterruptibly(1);
    }
    
    //最终调用tryReleaseShared
    public void countDown() {
        sync.releaseShared(1); 
    }
    ...
}

问题:如果有多个线程调用了await,则会唤醒几个?会唤醒所有,

 

五、容器

1、快速失败ConcurrentModificationException

快速失败,在迭代过程中,如果expectedModCount != count,则立即抛出异常,如java.util下的集合类

安全失败,将元数据复制一个副本,然后对副本进行迭代, 如java.util.concurrent下的集合类

2、HashMap扩容原理

红黑树与AVL树

红黑树的查询性能略微逊色于AVL树,因为他比avl树会稍微不平衡最多一层,也就是说红黑树的查询性能只比相同内容的avl树最多多一次比较,但是,红黑树在插入和删除上完爆avl树,avl树每次插入删除会进行大量的平衡度计算,而红黑树为了维持红黑性质所做的红黑变换和旋转的开销,相较于avl树为了维持平衡的开销要小得多

1.重新计算新的capacity和threshold,

2.初始化新的hash表

3.重新hash

3、map的K/V是否为null

集合类keyvaluesuper说明
Hashtable不允许为null不允许为nullDictionary线程安全
ConcurrentHashMap不允许为null不允许为nullAbstractMap线程安全
TreeMap不允许为null允许为nullAbstractMap线程非安全
HashMap允许为null允许为nullAbstractMap线程非安全

4、LinkedHashMap实现LRU

class LRUMap extends LinkedHashMap<KeyType, CacheEntry<KeyType, ValueType>> {
  private int maximumSize;
  LRUMap(int maximumSize) {
    this.maximumSize = maximumSize;
  }
  @Override
  protected boolean removeEldestEntry(Map.Entry<KeyType, CacheEntry<KeyType, ValueType>> eldest) {
    return size() > maximumSize;
  }
  
}

5、容器框架

https://blog.csdn.net/havedream_one/article/details/88597231

https://blog.csdn.net/havedream_one/article/details/88370123

六、并发容器

1、ConcurrentHashMap

对应的并发容器:HashMap

2、CopyOnWriteList

对应的非并发容器:ArrayList

读不加锁,写加锁;

在写操作时,先申请lock,然后复制一个副本,对副本进行写操作,写完之后,更新原数组至副本,然后释放锁即实现了写的多线程安全

增加副本的优点,对读操作无影响,写操作实现多线程安全

3、CopyOnWriteSet

对应的非并发容器:HashSet

基于CopyOnWriteList实现,内部的操作都转向了内部的CopyOnWriteList变量,跟hash没有了任何关系

4、ConcurrentSkipListSet

对应的非并发容器:TreeSet

5、ConcurrentSkipListMap

对应的非并发容器:TreeMap

6、ConcurrentLinkedQueue

非阻塞式并发队列

7、LinkedBlockingQueue

对应的非并发容器:LinkedList

阻塞式并发队列

8、PriorityBlockingQueue

阻塞式并发队列

9、ArrayBlockingQueue

阻塞式并发队列

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值