爱奇艺面试
面试过程:
1、请你自我介绍一下你自己?
2、你觉得你个性上最大的优点是什么?
3、说说你最大的缺点?
回答提示:这个问题企业问的概率很大,通常不希望听到直接回答的缺点是什么等,如果求职者说自己小心眼、爱忌妒人、非常懒、脾气大、工作效率低,企业肯定不会录用你。绝对不要自作聪明地回答“我最大的缺点是过于追求完美”,有的人以为这样回答会显得自己比较出色,但事实上,他已经岌岌可危了。企业喜欢求职者从自己的优点说起,中间加一些小缺点,最后再把问题转回到优点上,突出优点的部分,企业喜欢聪明的求职者。
问填空题:
(1)java程序分为两类:java应用程序Application和 applet。
(2)设x=2.5,a=7,y=4.7,算术表达式x+a%3*(int)((x+y)%2/4)的值为:_______。
(3)java语言种实现跳转的语句是break和 continue。
(4)执行下列语句String s=“这是棵梨树”;int L=s.length();L的值是____5___。
(5)用关键字___final__修饰的类不能再派生出子类。
(6)java中复杂类型数据包括类、接口和__数组_____。
(7)容器是一种特殊的组件。AWT容器分为两类:外部容器和___内部_____。
(8)在java的异常类的层次组织结构中,___Throwable___是所有异常类的父类,它是Object类的直接子类。
刚刚做了 答案是Throwable。
虽然我个人觉得应该是Exception,错误和异常的父类才应该是throwable。
(9)Java中的线程由一个虚拟处理机、CPU执行的代码和代码操作的数据等三部分组成。
(10)在java中TCP/IPSocket连接是由系统包java.net提供的ServerSocket类和 Socket 类完成的。
名词解释:
(1)java虚拟机
(2)继承
(3)布局管理
(4)接口回调
( 5) Socket套接字
TCP用主机的IP地址加上主机上的端口号作为TCP连接的端点,这种端点就叫做套接字(socket)或插口。套接字用(IP地址:端口号)表示,区分不同应用程序进程间的网络通信和连接,主要有3个参数:通信的目的IP地址、使用的传输层协议(TCP或UDP)和使用的端口号。
1.新生老年代gc算法的怎么实现
新生代:复制;
老年代:标记整理
2.maven冲突如何解决;
build-helper-maven-plugin
synchronized 和 ReentrantLock 区别是什么?
两者的共同点:
1. 都是用来协调多线程对共享对象、变量的访问
2. 都是可重入锁,同一线程可以多次获得同一个锁
3. 都保证了可见性和互斥性
两者的不同点:
1. ReentrantLock 显示的获得、释放锁,synchronized 隐式获得释放锁
2. ReentrantLock 可响应中断、可轮回,synchronized 是不可以响应中断的,为处理锁的
不可用性提供了更高的灵活性
3. ReentrantLock 是 API 级别的,synchronized 是 JVM 级别的
4. ReentrantLock 可以实现公平锁
5. ReentrantLock 通过 Condition 可以绑定多个条件
6. 底层实现不一样, synchronized 是同步阻塞,使用的是悲观并发策略,lock 是同步非阻
塞,采用的是乐观并发策略
7. Lock 是一个接口,而 synchronized 是 Java 中的关键字,synchronized 是内置的语言
实现。
8. synchronized 在发生异常时,会自动释放线程占有的锁,因此不会导致死锁现象发生;
而 Lock 在发生异常时,如果没有主动通过 unLock()去释放锁,则很可能造成死锁现象,
因此使用 Lock 时需要在 finally 块中释放锁。
9. Lock 可以让等待锁的线程响应中断,而 synchronized 却不行,使用 synchronized 时,
等待的线程会一直等待下去,不能够响应中断。
10. 通过 Lock 可以知道有没有成功获取锁,而 synchronized 却无法办到。
11. Lock 可以提高多个线程进行读操作的效率,既就是实现读写锁等
5、volatile和synchronized区别
1)volatile本质是在告诉jvm当前变量在寄存器中的值是不确定的,需要从主存中读取,synchronized则是锁定当前变量,只有当前线程可以访问该变量,其他线程被阻塞住.
2)volatile仅能使用在变量级别,synchronized则可以使用在变量,方法.
3)volatile仅能实现变量的修改可见性,而synchronized则可以保证变量的修改可见性和原子性.
《Java编程思想》上说,定义long或double变量时,如果使用volatile关键字,就会获得(简单的赋值与返回操作)原子性。
4)volatile不会造成线程的阻塞,而synchronized可能会造成线程的阻塞.
5、当一个域的值依赖于它之前的值时,volatile就无法工作了,如n=n+1,n++等。如果某个域的值受到其他域的值的限制,那么volatile也无法工作,如Range类的lower和upper边界,必须遵循lower<=upper的限制。
6、使用volatile而不是synchronized的唯一安全的情况是类中只有一个可变的域。
JVM的垃圾回收算法有哪些
常用的垃圾回收算法有如下四种:标记-清除、复制、标记-整理和分代收集。
标记-清除算法
从算法的名称上可以看出,这个算法分为两部分,标记和清除。首先标记出所有需要被回收的对象,然后在标记完成后统一回收掉所有被标记的对象。
这个算法简单,但是有两个缺点:一是标记和清除的效率不是很高;二是标记和清除后会产生很多的内存碎片,导致可用的内存空间不连续,当分配大对象的时候,没有足够的空间时不得不提前触发一次垃圾回收。
复制算法
这个算法将可用的内存空间分为大小相等的两块,每次只是用其中的一块,当这一块被用完的时候,就将还存活的对象复制到另一块中,然后把原已使用过的那一块内存空间一次回收掉。这个算法常用于新生代的垃圾回收。
复制算法解决了标记-清除算法的效率问题,以空间换时间,但是当存活对象非常多的时候,复制操作效率将会变低,而且每次只能使用一半的内存空间,利用率不高。
标记-整理算法
这个算法分为三部分:一是标记出所有需要被回收的对象;二是把所有存活的对象都向一端移动;三是把所有存活对象边界以外的内存空间都回收掉。
标记-整理算法解决了复制算法多复制效率低、空间利用率低的问题,同时也解决了内存碎片的问题。
分代收集算法
根据对象生存周期的不同将内存空间划分为不同的块,然后对不同的块使用不同的回收算法。一般把Java堆分为新生代和老年代,新生代中对象的存活周期短,只有少量存活的对象,所以可以使用复制算法,而老年代中对象存活时间长,而且对象比较多,所以可以采用标记-清除和标记-整理算法。
Stop-The-World:
在新生代进行的GC叫做minor GC,在老年代进行的GC都叫major GC,Full GC同时作用于新生代和老年代。在垃圾回收过程中经常涉及到对对象的挪动(比如上文提到的对象在Survivor 0和Survivor 1之间的复制),进而导致需要对对象引用进行更新。为了保证引用更新的正确性,Java将暂停所有其他的线程,这种情况被称为“Stop-The-World”,导致系统全局停顿。Stop-The-World对系统性能存在影响,因此垃圾回收的一个原则是尽量减少“Stop-The-World”的时间。
作者:陈阳001
链接:https://www.jianshu.com/p/d686e108d15f
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
AIO 是彻底的异步通信。
NIO 是同步非阻塞通信。
有一个经典的举例。烧开水。
假设有这么一个场景,有一排水壶(客户)在烧水。
AIO的做法是,每个水壶上装一个开关,当水开了以后会提醒对应的线程去处理。
NIO的做法是,叫一个线程不停的循环观察每一个水壶,根据每个水壶当前的状态去处理。
BIO的做法是,叫一个线程停留在一个水壶那,直到这个水壶烧开,才去处理下一个水壶。
可以看出AIO是最聪明省力,NIO相对省力,叫一个人就能看所有的壶,BIO最愚蠢,劳动力低下。
简单的描述一下BIO的服务端通信模型:采用BIO通信模型的服务端,通常由一个独立的Acceptor线程负责监听客户端的连接,它接收到客户端连接请求之后为每个客户端创建一个新的线程进行链路处理 处理完成后,通过输出流返回应答给客户端,线程销毁。即典型的一请求一应答通宵模型。
刚开始人们为了解决上面,高并发下服务器建立线程过多而枯竭,有人就想出了使用线程池来控制建立线程的数量,不至于服务器挂掉,于是就有了伪异步的io编程
一(1)、伪异步I/O编程
为了改进上面这种一连接一线程的模型,我们可以使用线程池来管理这些线程,实现1个或多个线程处理N个客户端的模型(但是底层还是使用的同步阻塞I/O),通常被称为“伪异步I/O模型“。
我们知道,如果使用CachedThreadPool线程池(不限制线程数量),其实除了能自动帮我们管理线程(复用),看起来也就像是1:1的客户端:线程数模型,而使用FixedThreadPool我们就有效的控制了线程的最大数量,保证了系统有限的资源的控制,实现了N:M的伪异步I/O模型。
但是,正因为限制了线程数量,如果发生大量并发请求,超过最大数量的线程就只能等待,直到线程池中的有空闲的线程可以被复用。而对Socket的输入流就行读取时,会一直阻塞,直到发生:
有数据可读
可用数据以及读取完毕
发生空指针或I/O异常
所以在读取数据较慢时(比如数据量大、网络传输慢等),大量并发的情况下,其他接入的消息,只能一直等待,这就是最大的弊端。而后面即将介绍的NIO,就能解决这个难题。
二、NIO 编程(非阻塞I/O)
JDK 1.4中的java.nio.*包中引入新的Java I/O库,其目的是提高速度。实际上,“旧”的I/O包已经使用NIO重新实现过,即使我们不显式的使用NIO编程,也能从中受益。速度的提高在文件I/O和网络I/O中都可能会发生,但本文只讨论后者。
(1)缓冲区buffer
buffer是一个对象,包含了读取和写入的数据,在nio中,所有的数据都是通过缓冲区来处理的。在写入数据时,也是写入到缓冲区中。任何时候访问NIO中的数据,都是通过缓冲区进行操作。
缓冲区实际是一个数组结构,并提供了对数据结构化访问以及维护读写位置等信息。
8种基本类型都有相应的缓冲区:ByteBuffe、CharBuffer、 ShortBuffer、IntBuffer、LongBuffer、FloatBuffer、DoubleBuffer。他们实现了相同的接口:Buffer。
(2)通道channel
我们对数据的读取和写入都要通过channel,它就像水管一样,是一个通道。通道不同于流的地方就是通道是双向的,可以用于读、写和同时读写操作。
底层的操作系统的通道一般都是全双工的,所以全双工的Channel比流能更好的映射底层操作系统的API。
channel主要有2大类:
selectablechannel 用于用户网络的读写(后面代码会涉及的ServerSocketChannel和SocketChannel都是SelectableChannel的子类。)
Filechannel 用于文件的操作
(3)多路复用器 Selector
Selector是Java NIO 编程的基础。
提供选择已经就绪的任务的能力:Selector会不断轮询注册在其上的Channel,如果某个Channel上面发生读或者写事件,这个Channel就处于就绪状态,会被Selector轮询出来,然后通过SelectionKey可以获取就绪Channel的集合,进行后续的I/O操作。
一个Selector可以同时轮询多个Channel,因为JDK使用了epoll()代替传统的select实现,所以没有最大连接句柄1024/2048的限制。所以,只需要一个线程负责Selector的轮询,就可以接入成千上万的客户端。
(4)NIO服务端
创建NIO服务端的主要步骤如下:
- 打开ServerSocketChannel,监听客户端连接
- 绑定监听端口,设置连接为非阻塞模式
- 创建Reactor线程,创建多路复用器并启动线程
- 将ServerSocketChannel注册到Reactor线程中的Selector上,监听ACCEPT事件
- Selector轮询准备就绪的key
- Selector监听到新的客户端接入,处理新的接入请求,完成TCP三次握手,简历物理链路
- 设置客户端链路为非阻塞模式
- 将新接入的客户端连接注册到Reactor线程的Selector上,监听读操作,读取客户端发送的网络消息
- 异步读取客户端消息到缓冲区
- 对Buffer编解码,处理半包消息,将解码成功的消息封装成Task
- 将应答消息编码为Buffer,调用SocketChannel的write将消息异步发送给客户端
所以不能保证一次能吧需要发送的数据发送完,此时就会出现写半包的问题。我们需要注册写操作,不断轮询Selector将没有发送完的消息发送完毕,然后通过Buffer的hasRemain()方法判断消息是否发送完成。
(5)NIO客户端
三、AIO编程
NIO 2.0引入了新的异步通道的概念,并提供了异步文件通道和异步套接字通道的实现。
异步的套接字通道时真正的异步非阻塞I/O,对应于UNIX网络编程中的事件驱动I/O(AIO)。他不需要过多的Selector对注册的通道进行轮询即可实现异步读写,从而简化了NIO的编程模型。
API比NIO的使用起来真的简单多了,主要就是监听、读、写等各种CompletionHandler。此处本应有一个WriteHandler的,确实,我们在ReadHandler中,以一个匿名内部类实现了它。
AIO是真正的异步非阻塞的,所以,在面对超级大量的客户端,更能得心应手
基本流程:一面,二面,三面。就不分开介绍了,直接是面试中全问到的问题。
这篇文章分享之前我还是要推荐下我自己的JAVA群:452180294 ,不管你是小白还是大牛,小编我都挺欢迎,不定期分享干货,包括我自己整理的一份2017最新JAVA资料和零基础入门教程,欢迎初学和进阶中的小伙伴
java面试第一步:
从项目问起。 对项目进行深入的问,各个模块的技术实现。项目总体的思维。
java面试第二步:
具体的问题:
-
1,方法重载,何时用重载,为什么要使用重载?而不是把一个方法名字换成不同的。
-
2,垃圾回收GC,什么时候会回收对象,怎么判断这个对象可以被回收。对象的的几种生存状态。
-
3,缓存问题,缓存与内存的区别。以及数据库连接池。
-
4,volatile关键字介绍一下。 没有原子性,有可见性(多线程下,),有序性
- https://blog.csdn.net/zzti_erlie/article/details/86355477
-
-
5,JVM介绍一下,从他的编译之类,加载(忘记回答父类,子类,以及静态代码块,普通代码块的加载过程)
-
6,Map,Collection的关系。
-
7,ArrayList扩充问题。add()方法的底层实现。
-
8,spring 的核心如:IOC AOP等,注入一个UserDaoImpl时,UserDaoImpl有几个实例,一个还是多个。
-
-
9,介绍一下同步,安全与不安全。
-
10,Thread中,ThreadLocal,Lock等。
-
11, 数据库索引的底层实现。B二叉树
-
13.线程池,线程池有多少种,每种的特点。
-
14.多线程实现方式,三种。
-
15.多线程同步方式,加关键字;实现Lock接口。
-
16,各个容器的底层实现,比如arraylist,hashmap,set,底层的数据结构,画出结构图。
单例
1. Spring 事务简介
Spring 本身并不实现事务,Spring事务 的本质 还是 底层数据库 对事务的支持,没有 数据库 事务的支持,Spring事务就不会生效。
Spring 事务 提供一套抽象的事务管理,并且结合 Spring IOC 和 Spring AOP,简化了应用程序使用数据库事务,通过声明式事务,可以做到对应用程序无侵入的实现事务功能。例如 使用JDBC 操作数据库,想要使用事务的步骤为:
1、获取连接 Connection con = DriverManager.getConnection()
2、开启事务con.setAutoCommit(true/false);
3、执行CRUD
4、提交事务/回滚事务 con.commit() / con.rollback();
5、关闭连接 conn.close();
采用Spring 事务后,只需要 关注第3步的实现,其他的步骤 都是Spring 完成。
Spring事务的本质 其实就是 AOP 和 数据库事务,Spring 将数据库的事务操作提取为 切面,通过AOP的方式 增强 事务方法。
作者:白袜子先生
链接:https://www.jianshu.com/p/2449cd914e3c
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
Object类有哪些方法
作者:Randn
链接:https://ac.nowcoder.com/discuss/411822
来源:牛客网
一面
- 3.30 一面 - (视频面 - 50min)
- Java 相关
- 操作系统 / Linux 相关:
- 如何查看系统的启动时间(我答了查看日志,应该是回答 uptime)
- CPU Load 和 CPU利用率的区别(不会)
- 查看系统当前所有的 Python 进程
- top 的作用
- 管道的作用
- IO 重定向
- 进程和线程的区别
- 介绍协程(不会)
- 死锁相关
- 死锁的产生
- 预防和检测死锁
- IO 多路复用,select、poll、epoll 调用
- 数据库相关:
- 手写SQL:给出一个表,字段有班级、性别和分数,求每个班男生的平均分
- 网络相关:
- TCP 和 UDP 的区别
- HTTP 状态码
- 介绍一下 RPC(不会)
二面
- 3.30 二面 (视频面 - 50min)
- Java Map 原理
- HashMap、HashTable、ConcurrentHashMap 的原理
- HashMap 的扩容机制
- ConcurrentHashMap 如何保证线程安全
- Java 的内存模型
- static 什么时候被初始化
- Java 的垃圾回收机制
- Jvm 分代回收模型
- 持久代的作用(不会)
- SpringMVC 的大致流程是什么?
- Spring Aop 的实现原理
- 手写SQL语句:给出一张表,字段有学号、名字、年龄、性别
- 找出最大年龄的人
- 找出最大年龄的人有几个
- 找出最多年龄人数的年龄
- MySQL 索引的原理
- 对名字、性别、年龄建立组合索引
- 哪个字段不适合作索引
- 查询名字、年龄会走索引吗?
- 对名字、性别、年龄建立组合索引
- 算法题:
- Java Map 原理
三面(Boss面)
- 3.31 三面 (视频面 - 20min)
- Java 相关
- ArrayList 和 LinkedList 的原理和实现
- HashMap 的实现原理
- 如何通过Key获得Value
- GC 垃圾回收机制
- 如何在C++中调用汇编代码
- 编译原理课程做了什么
- SSL 握手的过程
- 有几次RTT
- 快速恢复SSL的方法
- 对称加密和非对称加密的对比
- Java 相关
小结
面试时用的ZOOM,流程还是挺快的,一面二面是一天内完成的,三面是放在了第二天。
最后 pending 俩礼拜后还是挂了,主要还是一面的DLC单例很久没复习忘了实在是不应该,一面的表现确实也不太好。面一次也有一次的收获吧。