当前位置: 首页 > wzjs >正文

长沙网站运营关键词seo排名优化

长沙网站运营,关键词seo排名优化,向google提交网站,佛山做网站制作公司1.为什么java内存不可见 java线程是CPU调度的。每个CPU又L1、L2、L3的高速缓存。CPU调度某个线程的时候会将JVM中的数据拉取到高速缓存中。因为现在基本都是多核CPU,所以其他CPU如果也获取了相同的数据并且有写操作发生,就会导致多核之间高速缓存中的数据…

1.为什么java内存不可见

java线程是CPU调度的。每个CPU又L1、L2、L3的高速缓存。CPU调度某个线程的时候会将JVM中的数据拉取到高速缓存中。因为现在基本都是多核CPU,所以其他CPU如果也获取了相同的数据并且有写操作发生,就会导致多核之间高速缓存中的数据不一致。

2.什么是JMM

JMM是java内存模型(注意不是内存结构),属于并发编程。
不同的CPU厂商,CPU的实现机制不同。所以在内存和指令上又一些不同。JMM是为了屏蔽硬件和操作系统带来的差异,使得java程序能够在不同的硬件和操作系统下,实现并发编程的原子性、可见性、禁止指令重排列。
是存在CPU和JVM之间的一个规范,这个规范可以将JVM的字节码指令转换为CPU能够识别的一些指令。

3.JAVA里有哪些锁?区别是什么?

面试建议可以从乐观锁和悲观锁的实现方面回答。
乐观锁和悲观锁是两个概念,不是两个具体的锁。JAVA中针对这两种锁做了具体的落地。
乐观锁:认为在操作的时候,没有线程并发操作,如果有并发会操作失败,返回false,成功返回true。不会阻塞、等待,失败了就再试一次。
悲观锁:认为在操作时,会有并发操作。发生并发时,就会先去尝试竞争锁资源,如果拿不到资源,则会将线程挂起、阻塞等待。

JAVA中的实现:
乐观锁:CAS,在JAVA中是以Unsafe类中的native方法形式存在的,到了底层就是CPU支持的原子操作。
悲观锁:synchronized、Lock锁。

4.乐观锁和悲观锁的区别,乐观锁一定好吗?

乐观锁:不会让线程阻塞、挂起,可以让CPU调度执行这个乐观锁,可以直到成功为止。
悲观锁:会在竞争锁资源失败后阻塞、挂起。等待锁资源释放后,才可能唤醒这个线程去竞争资源。
核心区别在于是否会挂起线程,因为挂起线程这个操作在用户态时不能这么操作,需要从用户态转换到内核态,让OS去唤醒挂起的线程。用户态和内核态切换比较耗时。
如果竞争很激烈,导致乐观锁一直失败,那么CPU会一直去调度。此时会浪费CPU资源。

5.CAS有没有加锁,有哪些用的地方?

在JAVA中没有涉及到锁的情况,因为没有涉及到线程的阻塞挂起和唤醒操作。
但是CAS是在CPU是基于某个特定指令去实现的,而CPU是多核的。那么在多个核心都会去对一个变量进行CAS操作时,会添加LOCK前缀指令,可能会基于缓存锁或者总线锁,只让一个CPU执行这个CAS操作。
一般在开发中用不到CAS操作。但是在java并发包下可能会用到,比如synchronized、ReentrantLock、ThreadPoolExecutor、CountDownLatch等
(不知道实现中哪里具体用到了CAS锁?)

6.java中锁的底层实现

1)CAS ,CPU的cmpxchg指令
2)synchronied:
a.对象头中MarkWord,锁升级、无锁、偏向锁、轻量级锁、重量级锁
(如果深入问,要掌握到什么程度?)
3)Lock
a.AQS
(如果深入问,要掌握到什么程度?)

7.为什么HashMap的kv允许是null,而CHM(CurrentHashMap)不允许kv为null

hashMap的使用场景是现成局部使用,不存在多线程并发操作的问题。kv存null不影响当前线程的操作。
CHM设计的目标是在多线程的环境下去使用,如果允许存储null,会存在二义性问题,即:get(k) 得到的的v是null,是获取到了?还是没获取到?多线程操作的情况下,null值,极有可能造成空指针异常。

8.hash冲突有几种解决方式?

链地址法
多次hash法
公共溢出区:将hash表分为基准表和溢出表,但凡出现了hash冲突,就将冲突的数据扔到溢出表里。
开放地址法:有关键字的哈希地址(i),出现冲突时,以这个地址(i)为基准,产生另一个hash地址(i2),若i2还有冲突,则以(i2)为基准再生成一个i3,以此类推,直到产生一个不冲突的地址。
线性探测:顺序往后找hash地址,0有冲突看1,1有冲突看2…
二次平方探测:2,4,8,。。。

9.怎么用runable实现callable的功能

本质就是问futuretask
区别就是是否能抛异常,是否有返回值。
Callable本质是通过futuretask去执行。而在futuretask中有一个成员变量outcome,任务执行过程中抛出的异常或者返回的结果,都会被封装到outcome中,执行者需要结果时则会返回outcome中存储的内容。

10.ThreadLocal的应用场景,key和value是什么?

真正存储数据的是每个thread的threadLocalMap
应用场景(同一个线程中做参数传递):
1)声明事务,service层和mapper层使用的是同一个connection
2)日志
3)在filter中截获token,在controller中使用token。
key:threalLocal本身
value:put的内容

11.子线程如何获取父线程的信息

1)采用共享变量的方式,来做数据传递
2)java提供了inheritableThreadLocal类来实现这个操作

12.java中如何唤醒一个阻塞的线程

java中线程中阻塞的方式只有一种,就是park()所以唤醒的方法有:
1)interrupt方法
2)Unsafe.unpark()

java对阻塞的状态细分了三种:
1)BLOCKED:synchronied(在c++中线程会被唤醒,但是在java层面来看就没有唤醒)
2)WAITING
3)TIMED_WAITING
三个状态的区别不理解
blocked:争夺锁造成的阻塞
waiting:无限期等待,通常是Object.wait()(需在 synchronized 块中调用)Thread.join()(等待目标线程终止)LockSupport.park()(底层工具方法)造成
timed_waiting:线程调用带有超时参数的等待方法,进入有限期等待状态,一般调用如下方法会造成:
Thread.sleep(long millis)
Object.wait(long timeout)
Thread.join(long millis)
LockSupport.parkNanos(long nanos)
LockSupport.parkUntil(long deadline)

13.多个任务同时达到临界点,主线程执行如何实现?

1)减法计数器(CountDownLatch)锁实现
2)thread.join()方法实现
3)FutureTask
4)CompleableFuture

14.如何让20个线程同时开始执行?

CyclicBarrier 加法计数器实现
CyclicBarrier的底层是基于ReentrantLock实现的。到位的线程会基于await挂起,并且丟到Condition单向链表中。等到计数器到0时,会基于signalAll的方法,将所有到位的线程一个一个的唤醒,每个唤醒的线程还需要到AQS的同步队列中获取锁资源,才能继续往下执行,所以他们是存在先后顺序的。
示例代码:
public static void main(String[] args) {
int parties = 4; // 参与线程数
CyclicBarrier barrier = new CyclicBarrier(parties, new Runnable() {
//每一轮执行完都打印一下日志
@Override
public void run() {
System.out.println(“所有线程已到达屏障, 开始汇总结果或进行下一轮准备…”);
}
});

for (int i = 0; i < parties; i++) {new Thread(new Worker(barrier, "Worker-" + i)).start();
}

}

static class Worker implements Runnable {
private final CyclicBarrier barrier;
private final String name;

Worker(CyclicBarrier barrier, String name) {this.barrier = barrier;this.name = name;
}@Override
public void run() {try {for (int i = 0; i < 3; i++) {// 每个线程执行三次任务Thread.sleep((long) (Math.random() * 1000)); // 模拟任务执行时间System.out.println(name + " 第 " + (i + 1) + " 次任务完成");barrier.await(); // 等待所有线程完成当前轮次}} catch (InterruptedException | BrokenBarrierException e) {Thread.currentThread().interrupt();e.printStackTrace();}
}

}

15.CountDownLatch和CyclicBarrier分别适用于什么业务,哪个可以复用,为什么?

CountDownLatch:等多个线程的操作完成,再去执行某个业务。在面试中建议结合项目经历来说。
Cyclicbarrier:等指定个线程都执行完毕,再去执行某个业务。比如拼团。

CyclicBarrier可以复用。
CountDownLatch是基于AQS中的state做计数,每完成一个任务,countDown方法执行后,会对state1,当state为0后,就会唤醒那些基于CountDownLatch执行await的线程。CyclicBarrier是自己搞了一个count属性,每当有一个线程到位之后,就会对count进行–操作。等到count计数到0后,依然会唤醒,可以优先触发一个任务,然后唤醒所有到位的线程。
CyclicBarrier是可以复用的。他提供了一个reset的方法,在这个reset方法中,会将所有之前到位,和即将到位的线程全部唤醒结束,清空当前CyclicBarrier,以便下次使用

16.线程池的执行过程

任务投递之后
1)如果当前线程池的核心线程数不满足设定的核心线程数,那么会创建核心线程去处理投递过来的任务。
2)如果线程个数等于设置的核心线程数,那么会将任务投递到工作队列中排队。
3)如果工作队列的长度大于排队数量,任务会被正常投递到工作队列
4)如果工作队列的任务数和现在排队的任务数一致(即工作队列满了),任务无法投递到工作队列,此时需要创建一个非核心线程来处理刚刚投递过来的任务。
5)创建非核心线程时,还需要判断一下线程个数是否小于设置的最大线程数。小于才会正常创建。
6)如果线程个数等于最大线程数,则会执行拒绝策略。
线程池的执行过程参考图片:
在这里插入图片描述

17.线程池中为什么任务队列满了,会创建一个非核心线程去执行要投递的任务,而不是先去执行队列中最靠前的任务?

减少任务提交等待时间。避免先去队列取一个任务出来执行的时间。

18.核心线程和非核心线程有什么区别

没区别,只有在创建的时候会区分。

19.核心线程可以被回收吗?

如果allowCoreThreadTimtOut(默认为false)设置为true,那么只要工作线程的空闲时间超过了最大空闲时间,那么该线程就会被回收。
false:仅对非核心线程生效
true:对所有线程生效

20.线程池连环问

java线程池,5核心、10最大、10队列
第六个任务来了处于什么状态?-仍在队列里(无论核心线程是否空闲)
第十六个任务怎么处理?-创建非核心线程去处理这个任务
第十六个任务来了,核心线程空闲,那么如何处理?-如果队列中十个任务已经被核心线程取走,那么直接加入队列。如果队列中的任务还没有被核心线程取走,则创建非核心线程处理。
队列满了以后执行队列的任务是从头还是尾获取?-从头取
核心线程和非核心线程执行结束后,谁先执行队列里的任务?-谁先空闲了,等待任务,谁就先执行。

21.线程池的工作线程在执行任务的过程中,如何取消任务的执行?

原生的ThreadPoolExecutor在提交普通的Runnable任务时,是无法做到的,需要通过提交FutureTask任务,在任务处理的过程中会记录是哪个线程在处理当前任务。这样可以通过cancel方法,取消该任务。
这样咱们就可以获取到执行当前任务的线程对象执行他的interrupt方法。如果有中断的出口,那就结束了,但是如果没有中断的出口,那即便你中断了,任务也会执行完毕!所以需要catch InterruptedException。
其次也可以在任务还没执行前,通过对任务提供状态的修饰,基于状态来阻止任务执行。

22.线程池参数怎么设置?

线程池参数:
核心线程数
最大线程数
最大空闲时间
空闲时间单位
工作队列
线程工厂
拒绝策略
如何设置,分三步回答
1 根据线上服务器配置去聊:
CPU内核数
内存大小
2 线程池任务处理情况:
CPU密集
IO密集
混合型
3 直接说明核心线程数设置的是多少,以及工作队列多长
核心线程数:与最大线程数保持一致(因为压测得出的核心线程数就是最优解)
可以提前编一个数值,但是要说明这个数值是压测出来的。
如果是混合型,那么50左右没问题,如果是CPU密集的,别太大,与核心数差不多就行。
工作队列:要么ArrayBlockingQueue,要么LinkedBlockingQueue。推荐使用LinkedBlockingQueue。因为底层是队列,且工作队列本身就是增删频繁的情况,所以用这个。长度要考虑并发情况,如果任务体量较大,会造成内存使用率过大。如果任务队列太长,那么任务被处理时,最大的延迟时间能否被接受。
队列长度要直接说是多少,一般是核心线程的2倍左右。

23.设置线程池参数压测时,需要查看哪些指标?

CPU占用率:
IO密集型任务,CPU占用率不用提太多。
混合型或者CPU密集型任务中,需要时刻关注CPU占用率的情况,一般不超过70%都没啥问题,最好控制在50-60。

内存资源:
内存资源自然是线程本身也会占用,一般占1M。并且任务的处理过程中也会占用额外的线程资源。在队列中排队的任务也会占用内存资源。不能让内存资源占据太多。峰值时占据50-60即可。

磁盘资源:
一般不太考虑

吞吐量:越大越好 500个/s
响应时间:越小越好 200ms

还需要查看GC情况,如果任务体量比较大,如果新生代的内存不够,可能导致对象直接进入老年代,或者新生代频繁GC,就可能导致FULL GC频繁。

其他资源:比如数据库连接

优先根据配置自己确认要一个预估的数值,然后开始压测,查看指标情况。
逐步增加并发的数值,以及线程池的参数,去查看性能指标。
如果在逐渐调整数值后,依然无法达到性能要求,根据前面的指标,查看瓶颈在哪里,做优化。
重复上述操作,知道性能满足要求。

24.CopyOnWrite如何保证线程安全,为什么要这么做

基于写入操作前,获取reentrantLock,毕竟写写操作互斥,然后将本地数据复制一份,在复制的内容中完成写操作,在写完之后,用副本覆盖掉本地数据。

虽然会让内存占用量变大,但是读操作和写操作不互斥。当有读线程,则读取本地数据。

适合读多写少的场景。

25.CuncurrentHashMap在红黑树的读写并发会发生什么问题?

红黑树为了保证平衡,在写入数据时,可能会旋转、变色。
如果读写并行执行,可能导致在写操作导致数旋转时,读取到错误的路径,导致数据没有找到。
如果发生了读写同时进行的情况,读操作并不会被阻塞,而是直接去读取双向链表。
注意:
CurrentHashMap的结构

但是读线程如何知道有写线程写读数据?

26.实际项目中有使用过CurrentHashMap吗?

用于缓存一些热点数据。
需要准备项目

27.工作中的死锁如何处理?

死锁的行成条件:
1 不可剥夺
2 环路等待
3 互斥条件
4 请求保持

避免环路等待锁的情况
不要走lock的方式,采用tryLock 获取不到锁就结束的情况

如何定位?
采用jstack、jdk自带工具、arthas

http://www.dtcms.com/wzjs/287928.html

相关文章:

  • 英语网站排名竞价推广托管
  • 做旅游网站的目的seo优化网站优化
  • 烟台商机互联做网站吗必应收录提交入口
  • 靠谱个性化网站开发百度优化推广
  • 免费做章子的网站seo搜索引擎优化推广专员
  • 在线定制手机壳福建seo关键词优化外包
  • 湛江网站seoseo网站推广报价
  • 艺术网站定制重庆seo排名技术
  • 深圳网站建设方维游戏推广
  • 深圳市网站建设公司天津最新消息今天
  • 长沙岳麓区网站开发商城推广软文范文
  • wordpress子站共享用户名独立站seo外链平台
  • 松原手机网站开发培训机构是干什么的
  • 自己的网站统计输入词企业培训课程名称大全
  • 南京鼓楼做网站公司广州白云区疫情实时动态
  • 湖北省工程建设协会网站百度指数的搜索指数
  • 新闻录入网站模板网络推广宣传
  • 免费网站建设塔山双喜天津seo实战培训
  • 做模板网站的公司博客网站登录
  • 做网站建设一年能赚多少钱百度关键词优化排名技巧
  • 手机网站 焦点图微商怎么找客源人脉
  • 做网页专题 应该关注哪些网站网络营销怎么做推广
  • 零食天堂 专做零食推荐的网站短期培训学什么好
  • 训做网站的心得体会范文免费网站推广方式
  • 即时设计生成网页武汉seo创造者
  • mvc5 网站开发之美网站建设教程
  • 南昌网站建设索q.479185700宁波网站建设公司哪家好
  • 如何新建网站dw深圳网络推广收费标准
  • 广州市外贸网站建设b站推广入口2022
  • 网站续费合同高质量网站外链平台