更新时间:2022-12-29 11:22:48 来源:极悦 浏览900次
说道Java高级程序员面试题,网上肯定是有不少资料,但是大家找一找不难发现出问题,就是很多高级程序员面试题中都没有答案,只有题目,所以我们还需要花费大量的时间去搜集一些带有题目和答案的面试汇总,为了大家的方便,小编今天就汇总了一些大厂的高级面试题,大家可以进行参考:
1. Java如何开启线程?怎么保证线程安全?
答:线程与进程的区别:进程是操作系统进行资源分配的最小单元。线程是操作系统进行任务分配的最小单元,线程隶属于进程。
如何开启线程?1. 继承Thread类,重写run方法。2. 实现Runable接口,实现run方法。3. 实现Callable接口,实现call方法。通过FutureTask创建一个线程,获取到线程执行的返回值。4. 通过线程池来开启线程。
怎么保证线程安全?核心思想就是加锁:1. JVM提供的锁,也就是Synchronized关键字。 2. JDK提供的各种锁Lock.
2. Volatile和Synchronized有什么区别?Volatile能不能保证线程安全?DCL(Double Check Lock)单例为什么要加Volatile
答:1. Synchronize关键字,用来加锁,Volatile只是保持亦是的线程可见性。通常适用于一个线程写,多个线程读的场景。
2. Volatile关键字不能保证线程安全,只能保证线程可见性,不能保证原子性。
3.Volatile防止指令重排,在DCL中,防上高并发情况下,指令重排造成的线程安全问题。
3.Java线程锁机制是怎么样的?偏向锁、轻量级锁、重量级锁有什么区别?锁机制是如何升级的?
答:1.Java的锁就是在对象的Markword中记录一个锁状态,无锁、偏向锁、轻量级锁、重量级锁对应不同的锁状态。
2. Java的锁机制就是根据资源竟争的激烈程度不断进行锁升级的过程。
4.谈谈你对AQS的理解。AQS如何实现可重入锁?
答:1. AQS是一个Java线程同步的框架,是JDK中很多锁工具的核心实现框架。
2. 在AQS中,维护了一个信号量state和一个线程组成的双向链表队列,其中,这个线程队列就是用来给线程排队的,而state就像是一个红绿灯,用来控制线程排队或才放行的,在不同的场景下,有不同的意义。
3.在可重入锁这个场景下,state就用来表示加锁的次数,0表示无锁,每加一次锁state就加1,释放锁state就减1.
5.有A、B、C三个线程,如何保证三个线程同时执行?如何在并发情况下保证三个线程依次执行?如何保证三个线程有序交错进行?
答:CountDownLatch,CylicBarrier,Semaphore
public class ThreadSafeDemo {
public int count = 0;
public void add(){
count++;
}
public static void main(String[] args) throws InterruptedException{
int size = 3;
ThreadSafeDemo threadSafeDemo = new ThreadSafeDemo();
CountDownLatch countDownLatch = new CountDownLatch(1);
for(int i=0;i<size;i++){
new Thread(()->{
try{
countDownLatch.await();
System.out.println(System.currentTimeMillis());
Thread.sleep(100);
}catch (Exception ex){
ex.printStackTrace();
}
}).start();
}
Thread.sleep(5000);
countDownLatch.countDown();
}
}
public class OldThread2 {
static volatile int tickts = 1;
public static void main(String[] args){
Thread t1 = new Thread(()->{
while (true){
if(tickts==1){
try {
Thread.sleep(100);
for(int i=0;i<10;i++){
System.out.println("a"+i);
}
}catch (InterruptedException ie){
ie.printStackTrace();
}
tickts=2;
return;
}
}
});
Thread t2 = new Thread(()->{
while (true){
if(tickts==2){
try {
Thread.sleep(100);
for(int i=0;i<10;i++){
System.out.println("b"+i);
}
}catch (InterruptedException ie){
ie.printStackTrace();
}
tickts=3;
return;
}
}
});
Thread t3 = new Thread(()->{
while (true){
if(tickts==3){
try {
Thread.sleep(100);
for(int i=0;i<10;i++){
System.out.println("c"+i);
}
}catch (InterruptedException ie){
ie.printStackTrace();
}
tickts=1;
return;
}
}
});
t1.start();
t2.start();
t3.start();
}
}
public class OldThread {
private static Semaphore s1 = new Semaphore(1);
private static Semaphore s2 = new Semaphore(1);
private static Semaphore s3 = new Semaphore(1);
public static void main(String[] args){
try {
s1.acquire();
s2.acquire();
}catch (InterruptedException ex){
ex.printStackTrace();
}
new Thread(()->{
while (true){
try {
s1.acquire();
}catch (InterruptedException iex){
iex.printStackTrace();
}
try {
Thread.sleep(500);
}catch (InterruptedException ex2){
ex2.printStackTrace();
}
System.out.println("A");
s2.release();
}
}).start();
new Thread(()->{
while (true){
try {
s2.acquire();
}catch (InterruptedException iex){
iex.printStackTrace();
}
try {
Thread.sleep(500);
}catch (InterruptedException ex2){
ex2.printStackTrace();
}
System.out.println("B");
s3.release();
}
}).start();
new Thread(()->{
while (true){
try {
s3.acquire();
}catch (InterruptedException iex){
iex.printStackTrace();
}
try {
Thread.sleep(500);
}catch (InterruptedException ex2){
ex2.printStackTrace();
}
System.out.println("C");
s1.release();
}
}).start();
}
}
6. 如何对一个字符串快速进行排序?
答:Fork/Join框架
public class MargeTest {
private static int MAX = 100;
private static int inits[] = new int[MAX];
//随机队列初始化
static {
Random r = new Random();
for(int index = 0; index<MAX;index++){
inits[index-1] = r.nextInt(1000);
}
}
public static void main(String[] args) throws Exception{
long beginTime = System.currentTimeMillis();
ForkJoinPool pool = new ForkJoinPool();
MyTask task = new MyTask(inits);
ForkJoinTask<int[]> taskResult = pool.submit(task);
try {
int[] ints = taskResult.get();
System.out.println(Arrays.toString(ints));
}catch (InterruptedException ex){
ex.printStackTrace();
}
long endTime = System.currentTimeMillis();
System.out.println("耗时:"+(endTime-beginTime));
}
static class MyTask extends RecursiveTask<int[]>{
private int source[];
public MyTask(int source[]){
this.source = source;
}
@Override
protected int[] compute() {
int sourcelen = source.length;
if(sourcelen>2){
int midIndex = sourcelen/2;
MyTask task1 = new MyTask(Arrays.copyOf(source,midIndex));
task1.fork();
MyTask task2 = new MyTask(Arrays.copyOfRange(source,midIndex,sourcelen));
task2.fork();
int result1[] = task1.join();
int result2[] = task2.join();
int mer[] = joinInts(result1,result2);
return mer;
}else{
if(sourcelen==1 || source[0]<source[1]){
return source;
}else{
int targetTp[] = new int[sourcelen];
targetTp[0] = source[1];
targetTp[1] = source[0];
return targetTp;
}
}
}
}
}
7. TCP和UDP有什么区别?TCP为什么是三次握手,而不是两次?
答:TCP Transfer Control Protocol 是一种面向连接的,可靠的,传输层通信协议。
特点:好比打电话,面向连接的,点对点的通信,高可靠的,效率比较低,占用的系统资源比较多。
UDP User Datagram Protocol 是一种无连接的,不可靠的,传输层通信协议。
特点:好比广播,不需要连接,发送方不管接收方有没有准备好,直接发消息;可以进行广播发送。传输不可靠,有可能丢失消息;效率比较高,协议比较简单,占用的系统资源比较少。
TCP建立连接三次握手,断开连接四次挥手。如果是两次握手,可能造成连接资源浪费的情况。
8. Java有哪几种IO模型?有什么区别?
答:
BIO 同步阻塞IO。可靠性差,吞吐量低,适用于连接比较少且比较固定的场景。JDK1.4之前唯一的选择。编程模型最简单。
NIO 同步非阻塞IO。可靠性比较好,吞吐量比较高,适用于连接比较多,并且连接比较短(轻操作),例如聊天室,编程模型最复杂。
AIO 异步非阻塞IO。可靠性是最好的,吞吐量也是非常高的,适用于连接比较多,并且连接比较长(重操作)。例如相册服务器。视频流点播等,JDK1.7版本之后提供的。编程模型比较简单,需要操作系统来支持。
同步、异步【针对请求】和阻塞、非阻塞【针对客户端】
在一个网络请求中,客户端会发一个请求到服务端。
1. 客户端发了请求后,就一直等着服务端响应。客户端: 阻塞。 请求:同步
2. 客户端发了请求后,就去干别的事情了,时不时过来检查服务端是否给出了相应。客户端:非阻塞。请求:同步。
3. 换成异步请求。 客户端发了请求后,就坐在椅子上,等着服务端返回响应。客户端:阻塞。 请求:异步。
4. 客户端发了请求后,就去干别的事情了。等到服务端给出响应后,再过来处理业务逻辑。 客户端: 非阻塞。请求:异步。
以上就是“Java高级程序员面试题,内含解析答案”,你能回答上来吗?如果想要了解更多的相关内容,可以关注极悦Java官网。
0基础 0学费 15天面授
Java就业班有基础 直达就业
业余时间 高薪转行
Java在职加薪班工作1~3年,加薪神器
工作3~5年,晋升架构
提交申请后,顾问老师会电话与您沟通安排学习