上一家面试过后,紧接着又一家外包公司面试
也是上来问了我的项目。然后根据我项目使用到的技术点开始询问
这里不多说废话,直接上面试题
面试官:AOP他是如何实现的
果咩:他是采用的动态代理技术对特定的切点进行一个增强处理
动态代理他可以使用JDK动态代理或CGLIB动态代理
面试官:那你说一下动态代理是如何实现的
果咩:java的动态代理是基于JDK中Proxy和InvocationHandler来实现的,InvocationHandler用于实现接口的方法和业务的增强,Proxy通过静态方法newProxyInstance()来创建动态代理的class对象和实例。动态代理技术适用于对系统进行无侵入性的增强的时候适用;
面试官:反射他都有哪些方法属性,他可以用来干什么?
getclass 获取类对象
getFiled获取属性值
getDeclaredField获取私有属性值
getMethod获取方法
newInstance创建实例
在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性
所以我们经常用反射来动态构造对象,调用方法,根据类型获取相关的信息
面试官:创建线程的几种方式,他们的区别是什么
果咩:4种
继承Thread类,类单继承,重写run方法,调用start方法执行
实现runnable接口,接口实现,重写run方法,调用start方法执行
实现callable接口,接口实现,重写call方法,可抛异常,有返回值
使用线程池,通过Executors类,可以创建4种不同的线程池
面试官:如何停止一个线程
果咩:
- 线程运行结束,自动终止
- 使用退出标记符,我们自定义一个退出标记exit,当为true时,while退出循环
- Thread提供的interrupt()方法,他可以使一个线程抛出一个中断异常,然后我们捕捉异常从而使线程提前结束阻塞
- stop() 方法,不推荐,强行终端线程,会释放子线程所有的锁
面试官:线程池用过吗,说一下都有哪些线程池,和几个重要的属性
果咩:Java通过Executors提供四种线程池
newCachedThreadPool 创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。
newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
面试官:你们项目中用到过多线程吗?
果咩:使用过,我们项目有一个数据采集服务使用到了多线程
面试官:你们为什么使用多线程,解决了什么问题?
果咩:因为数据采集会同时有很多数据进行上报,并发比较大
所以我们使用了多线程进行异步的处理,减少阻塞,提升性能
面试官:spring的bean是单例的吗
果咩:默认是单例的
他可以指定5种scope分别是singleton, prototype, request, session,global session
面试官:为什么默认设置成单例的?有什么好处
果咩:减少了生成新实例的消耗,减少了jvm的垃圾回收,默认从缓存中获取所以可快速获取bean
唯一劣处就是他不是一个线程安全的
面试官:创建单例有几种方式
果咩:最简单的就是饿汉式和懒汉式
面试官:单例如何成为一个线程安全的?
果咩:使用双重锁检测
面试官:项目遇到了那些问题
果咩:我们项目使用websocket的时候,会出现连接失效的情景,然后我们对长连接进行心跳检测
面试官:那你说一下websocket吧
果咩:为了实现即时通信,我们在websocket之前使用轮询等技术
而这些技术都是通过浏览器发送请求到服务器上的
而WebSocket是一种在单个TCP连接上进行全双工通信的协议
双全工通信:通信的双方可以同时发送和接收信息的信息交互方式。
所以WebSocket可以直接在服务器发送消息到浏览器,他相对于轮询等技术,更好的节省服务的资源和带宽,更实时的进行通信
面试官:说一下tcp
果咩:TCP作为一种面向连接的,可靠的,基于字节流的传输层通信协议。只有在确认通信对端存在时才会发送数据,从而可以控制通信流量的浪费。TCP通过检验和、序列号、确认应答、重发控制、连接管理以及窗口控制等机制实现可靠性传输。
面试官:讲一下为什么需要三次握手?
果咩:tcp的三次握手在于创建一个双向的可靠通信连接
因为双方都维护了一个序列号seq, 为了保证传输的可靠性,所以需要对方都序列号做一个确认
比如:
1.A向B发送一个序列号seq为156
2.B收到后+1并返回ack为157
3.B向A发送一个序列号为234
4.A收到后+1并返回一个ack为235
本质是需要四次握手,这里因为23可以一起,所以是三次握手
他的可靠性是靠超时重传(确保消息有机会到达对面)来进行保证的
两次握手无法保证双发的序列号都得到了一个确认从而会引发其他问题
比如已失效的连接请求报文段突然又传送到了服务端,因而产生错误
而多次握手显的更是浪费没有必要
面试官:你的大致情况我已经了解了,今天的面试就到这里
我这有一份关于java的面试题,大家可以关注我的公众号 **果咩z**(在最下方!),回复:**java面试题** 来领取