海盗船|字节内部Java技术岗‘面试真题’泄露,冒死发布!( 五 )


16、 建立连接可以两次握手吗?为什么?
17、 可以采用四次握手吗?为什么?
18、 第三次握手中 , 如果客户端的ACK未送达服务器 , 会怎样?
19、 如果已经建立了连接 , 但客户端出现了故障怎么办?
20、 初始序列号是什么?
二、Java并发专题面试
I.多线程
1、启动线程方法 start()和 run()有什么区别?
只有调用了 start()方法 , 才会表现出多线程的特性 , 不同线程的 run()方法里面的代码交替执行 。 如果只是调用 run()方法 , 那么代码还是同步执行的 , 必须等待一个线程的 run()方法里面的代码全部执行完毕之后 , 另外一个线程才可以执行其 run()方法里面的代码 。
2、Java 实现线程有哪几种方式?

  • 继承 Thread 类实现多线程
  • 实现 Runnable 接口方式实现多线程
  • 使用 ExecutorService、Callable、Future 实现有返回结果的多线程
3、用 Java 实现阻塞队列 。
这是一个相对艰难的多线程面试问题 , 它能达到很多的目的 。 第一 , 它可以检测侯选者是否能实际的用 Java 线程写程序;第二 , 可以检测侯选者对并发场景的理解 , 并且你可以根据这个问很多问题 。 如果他用 wait()和 notify()方法来实现阻塞队列 , 你可以要求他用最新的 Java 5 中的并发类来再写一次 。
4、Java 中你怎样唤醒一个阻塞的线程?
这是个关于线程和阻塞的棘手的问题 , 它有很多解决方法 。 如果线程遇到了 IO 阻塞 , 我并且不认为有一种方法可以中止线程 。 如果线程因为调用 wait()、sleep()、或者 join()方法而导致的阻塞 , 你可以中断线程 , 并且通过抛出 InterruptedException 来唤醒它 。 我之前写的《How to deal with blocking methods in java》有很多关于处理线程阻塞的信息 。
5、你将如何使用 threaddump?你将如何分析 Thread dump?
6、线程池启动线程 submit()和 execute()方法有什么不同?
7、什么是重入锁?
8、一个线程运行时发生异常会怎样?
9、线程同步需要注意什么?
10、线程 yield()方法有什么用?
11、violatile 关键字的作用?
12、什么是乐观锁和悲观锁?
13、常用的几种线程池并讲讲其中的工作原理 。
14、Java 中的 volatile 关键是什么作用?怎样使用它?在 Java 中它跟 synchronized 方法有什么不同?
15、你如何在 Java 中获取线程堆栈?
16、Jdk 中排查多线程问题用什么命令?
17、在 Java 中 CycliBarriar 和 CountdownLatch 有什么区别?
18、多线程同步有哪几种方法?
19、什么是守护线程?有什么用?
20、Java 中堆和栈有什么不同?
II.Java并发编程
1、 synchronized 和 volatile 的区别是什么?
2、 为什么 wait() notify()和 notifyAll()必须在同步方法或者同步块中被调用?
当一个线程需要调用对象的 wait()方法的时候 , 这个线程必须拥有该对象的锁 , 接着它就会释放这个对象锁并进入等待状态直到其他线程调用这个对象上的 notify()方法 。 同样的 , 当一个线程需要调用对象的 notify()方法时 , 它会释放这个对象的锁 , 以便其他在等待的线程就可以得到这个对象锁 。 由于所有的这些方法都需要线程持有对象的锁 , 这样就只能通过同步来实现 , 所以他们只能在同步方法或者同步块中被调用 。
3、 如何在两个线程间共享数据?
一般来说 , 共享变量要求变量本身是线程安全的 , 然后在线程内使用的时候 , 如果有对共享变量的复合操作 , 那么也得保证复合操作的线程安全性 。
4、 为什么我们调用 start() 方法时会执行 run() 方法 , 为什么我们不能直接调用 run() 方法?