【面试问题总结】3

Java线程池核心参数与工作流程,拒绝策略
public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {

线程池有六个参数:
1、corePollSize:核心线程数
2、maximumPoolSize:最大线程数。线程池所允许的最大线程个数。当队列满了,且一创建的线程数小于最大线程数,则线程池就会创建新的线程来执行任务。无界队列,可忽略此参数。
3、keepAliveTime:多于线程存活时间。当线程池中的线程数大于核心线程数时,线程的空闲时间超过线程存活时间,那么这个线程就会被销毁,知道线程池中的线程数小于等于核心线程数。
4、workQueue:队列:用于传输和保存等待执行任务的阻塞队列。
5、threadFactory:线程创建工厂。用于创建新线程。
6、handler:拒绝策略。当线程池和队列都满了,再加入线程会执行此策略。

拒绝策略:
当线程池和队列都满了,如果还有任务到来就会采用再拒绝策略。

1、AbortPolicy:丢弃任务并抛出 RejectedExecutionException异常
2、DiscardPolicy:也是丢弃任务,但不会抛出异常
3、DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务
4、CallerRunsPolicy:由调用线程处理该任务

Synchronized实现原理 及和Lock的与区别

synchronized实现原理:

synchronized用的锁是存在Java对象头里的。其中,Mark Word里存储了锁的信息,包括锁的标志位与状态。
synchronize获取锁的过程其实是在Mark Word加入线程信息的过程

在这里插入图片描述

区别:

1、synchronized是java关键字,Lock是一个接口
2、synchronized可以用在方法上,代码块上,但是lock只能写在代码里。
3、synchronized可以自动释放锁,lock需要手动使用unlock释放
4、synchronized不可中断,lock可以中断避免死锁的发生
5、synchronized无法得知是否获取锁成功,lock可以使用tryLock方法得知是否加锁成功
6、synchronized的布道所就一直等待,lock可以设置获取锁失败的超时时间

重写和重载的区别

1、范围不同:重载是在一个类的内部进行的,重写是在发生了父子类之间
2、要求不同:重载要求方法名相同,方法参数不同,与返回值类型无关。重写要求子类的方法名、方法参数要和父类完全相等、以及子类的返回值、抛出的异常要小于等于父类方法,访问修饰符大于等于父类方法。父类的私有方法不能被子类重写。

线程的状态及转移

线程分为五种状态:新建New、就绪Ready、运行Running、阻塞Blocked、死亡Dead
当一个线程使用new关键字被创建后处于新建态,当执行调用了start方法,线程处于就绪态,等待cpu的调度,获取到了时间片之后进入运行态,如果在运行态调用的sleep方法、请求阻塞IO、等待同步锁、等待通知都会进入到阻塞态,当对应的sleep时间结束、IO方法返回、获得同步锁、收到通知就会在进入就绪态,再次去等待cpu的调度,等线程任务正常结束或者抛出异常了,变成死亡态。

Jvm垃圾回收器

根据分代收集理论,针对不同的区域有不同的垃圾回收器。对于新生代有:Serial、ParNew、Parallel Scavenge
老年代有:Serial Old、CMS、Parallel Old;。其中G1即收集新生代的垃圾也收集老年代的。

追问1:CMS垃圾回收器的过程是什么样的?会带来什么问题?

过程:

CMS垃圾回收器使用的是算法是标记清除。主要步骤就是三标记一清除,就是初始标记、并发标记、重新标记、标记清理。其中初始标记只是标记GCRoots能直接关联的对象。并发标记标记从GCRoots直接关联的对象能到所有的对象,即标记整个对象图,时间会比较长。重新标记是标记刚才程序运行时产生的新的垃圾。标记清除就是对刚才标记的对象进行回收。

问题:

不能回收浮动垃圾以及内存碎片问题

“浮动垃圾”:
因为 CMS 在 并发标记 时是并发的,GC 线程和用户线程并发执行,这个过程当然可能会因为线程的交替执行而导致新产生的垃圾(即浮动垃圾)没有被标记到;而 重新标记 的作用只是修改之前 并发标记 所获得的不可达对象,所以是没有办法处理 “浮动垃圾” 的。

追问2:G1垃圾回收器的改进是什么?相比于CMS突出的地方是什么?

G1整体上采用的时标记整理算法。它仍然遵守分代收集理论,但是他不再坚持固定大小以及固定数量的分代区域划分,而是将堆内存划分成多个大小相等的独立区域Region,每个Region可以根据需要扮演新生代的Eden空间、幸存区或者老年代。对于大对象将它们存在在Humongous('hju:mərəs)区域中,G1认为只要大小超过了一个Region容量一般的对象就为大对象,每次都有优先回收大对象。它在后台维护一个优先级队列,优先处理回收价值收益最大的那些Region,保证了G1收集器在有限的时间内获取尽可能高的收集效率。

G1突出的地方:

基于标记整理算法,不产生垃圾碎片。

追问3:现在jdk默认使用的是哪种垃圾回收器?

jdk1.7 默认垃圾收集器Parallel Scavenge(新生代)+Parallel Old(老年代)
jdk1.8 默认垃圾收集器Parallel Scavenge(新生代)+Parallel Old(老年代)
jdk1.9 默认垃圾收集器G1

HashMap与ConcurrentHashMap在Jdk1.7和1.8的区别

HashMap

在jdk1.7的时候采用的数据结构是Entry数组+链表,采用头插法。根据计算的hashCode将对应的kv键值对存储到数组中,发生哈希碰撞的时候将其放在已有元素的后面,形成链表,但是链表上存放的元素过多时,时间复杂度为O(n)查询效率不高。

在jdk1.8时采用Node数组+链表+红黑树,采用尾插法。当链表上存在存放元素达到阈值时会选择将其转为红黑树,时间时间复杂度为O(logN)

ConcurrentHashMap

ConcurrentHashMap在JDK1.7的时候由Segment数据结构和HashEntry数组结构构成。
使用的是Segment分段锁的思想,将数据分成段,每个段都有个可重入锁,则多线程的时候不会影响到其他线程访问其他段的数据。
Segment是将数据分成段,默认是16,每个段都有一把锁,则理论最高支持16个线程并发

在这里插入图片描述

ConcurrentHashMap在JDK1.8的时候由Node数组+链表+红黑树
使用的是CAS+synchronized方式,抛弃了Segment分段锁的思想,CAS是一个乐观锁,则在不加锁情况下实现赋值,在桶为空的时候采用CAS方式添加数据,而不为空的时候采用synchronized 的方式
在这里插入图片描述

CAS操作原理与实现

CompareAndSwap使用了三个基本操作数:内存地址V、旧的预期值A、要修改的新值B,在更新数据之前先看比较一下内存V中的该值与预期的旧数值是不是一样的,一样才更新,不一样就不该更新。cas属于乐观锁,线程会不断地去尝试更新

CAS带来的问题是什么?如何解决的?

带来ABA问题。cas再赋值时进行比较,如果此时的数值由A被别人修改成了B但又被其他线程改为了A,此时线程进行比较时,会认为该值之前没有被别人修改过,进行更新。这样其他线程的修改就会丢失,再复杂的数据结构中比如链表、队列、树等可能出现不可预知的问题。

解决:

利用AtomicStampedReference,加一个版本号,比较的时候除了比较对象值,还需要比较状态戳(类似与时间戳),每次修改成功也会同时修改状态戳。

TCP与UDP区别

1、连接:TCP是面向连接的,UDP无连接的
2、可靠性:TCP有ARQ协议、超时重传等,可以保证提供可靠的服务,但是UDP没有这些它是尽最大努力的交付
3、有序性:TCP可以利用序列号保证有序性,UDP不能
4、速度:TCP比较复杂所以比较慢,UDP比较快
5、量级:TCP的报文是20个字节,UDP报文时8个字节。

追问:TCP和UDP的使用场景?

TCP因为是连接的可靠的服务,比较适用于文件传输、发送和接收邮件、远程登陆
UDP无连接的传输速度比较快,比较适用于即时通信,例如QQ音视频、直播

TCP是如何保证可靠传输的?

1、应用数据被分割成TCP认为最合适发送的数据块。
2、、有序性:TCP给发送的每一个包进行编号,接收方对数据包进行排序,把有序数据传给应用层。
3、校验和: TCP将保持它首部和数据的校验和。端到端的校验和,目的是检测数据在传输过程中的任何变化。如果收到端的校验和有错误,TCP将丢弃这个报文段和不确定收到此报文段。
4、TCP的接收端会丢弃重复的数据
5、流量控制:TCP连接的每一方都有固定大小的缓冲空间,TCP的接收端只允许发送断发送接收端换成去能接纳的数据。当接收方来不及处理发送方的数据,能提示发送发降低发送频率,防止包丢失。TCP使用的流量控制协议是可变大小的滑动窗口协议。
6、拥塞控制:当网络拥塞时,减少数据的发送。
7、ARQ协议:它的基本原理就是每发完一个分组就停止发送,等待对方确认。在收到确认后再发下一个分组。
8、超时重传:当TCP发出一个报文段之后,启动一个计时器,等待目的端确认收到这个报文段。如果不能及时收到一个确认,将重发这个报文段。

本贴来源–高频问题汇总

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值