2021.03.18 支付宝一面(45min)
1、自我介绍确定
2、收获最大的一个项目
3、项目的技术难点
4、线程和进程的区别
-
进程是系统进行资源分配和调度的一个独立单位;线程是进程的一个实体,是CPU调度和分派的基本单位
-
一个程序至少一个进程,一个进程至少一个线程
-
每个进程都有独立的内存地址空间;系统不会为线程分配内存,线程组之间只能共享所属进程的资源
-
程序之间的切换会有较大的开销;线程之间切换的开销小
5、线程和进程开销哪个大,为什么?
-
关于进程的定义有很多,一个经典的定义是一个执行中程序的实例,进程是程序的动态表现。 一个程序进行起来后,会使用很多资源,比如使用寄存器,内存,文件等。每当切换进程时,必须要考虑保存当前进程的状态。状态包括存放在内存中的程序的代码和数据,它的栈、通用目的寄存器的内容、程序计数器、环境变量以及打开的文件描述符的集合,这个状态叫做上下文(Context)。可见,想要切换进程,保存的状态还不少。
-
线程存在于进程中,一个进程可以有一个或多个线程。线程是运行在进程上下文中的逻辑流,简单说,线程可以理解为一个方法(Java)或函数(C),这个线程可以独立完成一项任务。同样线程有自己的上下文,包括唯一的整数线程ID, 栈、栈指针、程序计数器、通用目的寄存器和条件码。可以理解为线程上下文是进程上下文的子集。
-
由于保存线程的上下文明显比进程的上下文小,因此系统切换线程时,必然开销更小。
6、线程的几种状态?
7、等待和阻塞的区别?
-
sleep()方法 sleep()方法是Thread类的方法,通过其定义可知是个native方法,在指定的时间内阻塞线程的执行。而且从其注释中可知,并不会失去对任何监视器(monitors)的所有权,也就是说不会释放锁,仅仅会让出cpu的执行权。
-
wait()方法 wait()方式是基类Object的方法,其实也是个native方法。可以看出此方法调用的前提是当前线程已经获取了对象监视器monitor的所有权。该方***调用后不仅会让出cpu的执行权,还会释放锁(即monitor的所有权),并且进入wait set中,知道其他线程调用notify()或者notifyall()方法,或者指定的timeout到了,才会从wait set中出来,并重新竞争锁。
-
区别 最主要的区别就是释放锁(monitor的所有权)与否,但是两个方法都会抛出InterruptedException。
-
阻塞BLOCKED 阻塞表示线程在等待对象的monitor锁,试图通过synchronized去获取某个锁,但是此时其他线程已经独占了monitor锁,那么当前线程就会进入等待状态。
-
等待WAITING 当前线程等待其他线程执行某些操作,典型场景就是生产者消费者模式,在任务条件不满足时,等待其他线程的操作从而使得条件满足。可以通过wait()方法或者Thread.join()方法都会使线程进入等待状态。
图中Entry Set中的线程处于阻塞状态,也就是线程还没有拿到锁。Wait Set中的线程处于等待状态,也就是拿到锁后暂时释放锁(等待条件成熟会再次获取锁)。
线程和其他线程抢锁没抢到,就处于阻塞状态了;(此时线程还没进同步代码块)
线程抢到了锁进了同步代码块,(由于某种业务需求)某些条件下Object.wait()了,就处于了等待状态。(此时线程已经进入了同步代码块)
8、说一说Java中的集合?
9、Arraylist清除remove是不是就直接成功了,从它的数据结构来进行分析,时间复杂度?
java ArrayList.remove()的三种错误用法以及六种正确用法 https://blog.csdn.net/king0406/article/details/103789459
10、二叉树的遍历方式五种,后序遍历时间复杂度,n指的是?
-
非递归遍历(辅助栈) 时间复杂度:O(N) 空间复杂度:O(N)
由于每个节点都要进栈和出栈,所以时间复杂度为O(N),同样空间复杂度也为O(N),N为结点数。
-
递归遍历 时间复杂度:O(N) 空间复杂度:O(N)
递归实现的本质也是系统帮我们建立了栈结构,而系统栈需要记住每个节点的值,所以空间复杂度仍为O(N)。
11、HashMap是由什么组成的?JDK1.8以后有什么变化,HashMap清除操作速度慢,为什么
12、水平分表,大量数据如何进行分表,比如说淘宝一天有1亿个订单号?
13、如何解决大量用户的活跃度(当天登录就算活跃,登陆多次仍然算活跃)?
全部评论
(2) 回帖