Java整体知识架构详解-之冷知识
2020-01-15 13:57:59 4 举报
AI智能生成
写些Java的偏门点的冷知识,当然也可能是面试考点
作者其他创作
大纲/内容
Java基础
Java方法基本数据类型是值传递,那么引用数据类型就是引用传递吗?
java内部类传入外部变量为什么必须是final类型的?
1. 首先是生命周期不一致,方法执行完就出栈了,方法内的局部变量也会销毁,但此时内部类中引用的该局部变量可能还在使用
2. 由于第一点原因,内部类中必须保存的是传入外部变量的副本,这样哪怕外部变量失效,内部类中参数仍旧有效
3. 但第二点带来的问题是如果传入的是副本,在内部类方法执行之后如果又改变了这个传入变量怎么办?这会导致代码的混乱,你以为你改了这个外部变量,实际内部类中的变量还是原来的值,为了避免这样的问题,定义为final就可以有效避免了,定死外部的传入变量不能变也就不存在这个问题了
系统理解
QPS和RT的概念
QPS:每秒能处理的请求数(Query Per Second),计算方法QPS=并发数/RT
RT:这个好理解,请求响应时间
Java中的IO模型
类型
BIO(Blocking I/O)
同步阻塞I/O模型,数据的读取写入必须阻塞在一个线程内等待其完成
NIO(New I/O)
同时支持阻塞与非阻塞模式,但主要是使用同步非阻塞IO
AIO(Asynchronous I/O)
异步非阻塞I/O模型
同步异步和阻塞非阻塞
同步不等于阻塞,同步指一次请求等待服务器处理完请求后返回结果;
阻塞指一个请求就占用一个线程直到数据处理完成返回
阻塞指一个请求就占用一个线程直到数据处理完成返回
异步不等于非阻塞,异步指一次请求很快返回结果,而数据处理异步进行,直到处理完成再主动通知请求者;
非阻塞它指的是一个请求不会完全占据一条线程,它将请求送入一个通道,用一条线程来轮询请求,再送入线程池处理任务后返回
非阻塞它指的是一个请求不会完全占据一条线程,它将请求送入一个通道,用一条线程来轮询请求,再送入线程池处理任务后返回
liunx的IO模型
模型类型
阻塞IO模型
从请求开始的内核准备数据到复制数据到用户空间都要等待
非阻塞IO模型
内核数据准备的过程变非阻塞了,但需要每隔一定时间去判断数据是否准备好
信号驱动IO模型
内核数据准备过程非阻塞,同时不需要轮询了,当内核准备好数据时会通知进程已经准备好数据,进程再来调用数据复制到用户空间的过程
IO复用模型
多个进程建立多个通道注册到同一个select函数上,内核准备数据过程还是非阻塞,但select监听注册好的所有IO是阻塞的,当有一个IO准备好数据,就会返回,然后进程再调用内核进行数据复制到用户空间
异步IO模型
这就好比全自动化了,内核准备数据过程和数据复制到用户空间过程都不需要进程参与,在复制完成后会给进程发送信号,是异步非阻塞过程
总结
1. 所谓非阻塞指内核准备数据报的过程不需要等待
2. 阻塞IO,非阻塞IO,信号驱动IO,IO复用都是同步的,异步IO模型才是异步的,因为前四种在数据从内核复制到用户空间的过程都是阻塞的,其实都是需要等待的
谈架构要素
FPASE
F(Flexibility)伸缩性
P(performance)性能
A(Availability)可用性
S(security)安全性
E(expansibility)扩展性
MySQL
InnoDB的行锁加在哪里?
InnoDB是基于索引来完成行锁的,也就是查询条件必须包含索引,比如 `select * from tab_with_index where id = 1 for update;`的id必须是有索引的,否则将完成表锁
Mysql中count(*),count(1),count(字段)用哪个好?
我简单介绍下,具体请看链接文章:count(字段)查询的条数不包含字段为null的,所以有这需求的可以用;当要查询全部数据行数,则在count(1)和count(*)选择,mysql官网说明了,在innodb中这连个的性能是没差别的,实现都一样;但myisam引擎中mysql对count(*)有优化;myisam表级锁记录了总行数字段,可以直接读取会更快
开发技巧
@Async
这个注解可能大部分人都知道,但是很多时候不会意识到去用它,当你想要用自定义的线程去处理某个任务时,不妨考虑直接加上该注解去做异步处理,而不是自定义创建线程池
部分异步处理例子
LinkedHashMap
此类可以用来实现LRU缓存,因为他有个removeEldestEntry方法,可以用来移除最老的键值对
ThreadPoolTaskExecutor和ThreadPoolExecutor
区别
ThreadPoolExecutor是JDK的JUC也就是java并发工具包的线程池工具类
ThreadPoolTaskExecutor是对ThreadPoolExecutor进行了进一步封装的,spring core的封装线程池工具类
ThreadPoolTaskExecutor
实现例子
用法和ThreadPoolExecutor类似的,我的例子用了FutureTask,也可以不用
延迟队列
DelayQueue
合理使用延迟队列,比如订单到期处理,有些人可能会用定时拉取数据库到期订单做处理,但这样做问题太多,订单太多时读取数据库性能降低,定时间隔不好掌控。这里可以考虑使用延迟队列,延迟队列的核心使用的是优先级队列任务排序,取出最近到期任务执行,并计算下个任务的时间,延迟该时间后再取,使用一条线程就可以完成
RabbitMQ
用RabbitMQ来实现消息延迟,它可以对队列和消息分别设置TTL(消息存活时间),设置了队列的TTL超时消息就死了,设置消息的TTL可能到死亡时间还没死,需要被读取的时候判断是否超时,可能消息积压较多时会存活比较久;两者都设置了取小值。默认我们是不设置的,也就是永远不会过期。光消息过期还不够,还要加个死信交换机,也就是当消息过期时自动转发到死信交换机,消费者消费该交换机,就可以做到延迟接收了。当然还可以使用它自带的插件,参考右边链接
面试问考官的问题
对面试官
how
你觉得你作为老员工觉得这家公司怎么样,不管是企业文化或者工作环境
why
这个问题我觉得酌情考虑吧,你觉得进的可能性比较大,可以问你为什么当初进这家公司呢,它有什么吸引了你
对我
how
我觉得这次面试我还有很大进步空间,你觉得我还欠缺哪些方面呢
when
这次面试结果什么时候能给我回复呢
what
如果我加入了贵公司,我会加入什么部门,负责什么职责呢?你对我会有什么要求?
对公司
why
公司目前为什么要招这个岗位呢?在哪些方面或业务需要更多人手吗?
what
公司现在面临的最大挑战是什么?
易错代码
Netty服务端
等待服务端口关闭 future.channel().closeFuture().sync();注意这里不是close()方法,是closeFuture(),写成close你的服务就开不起来了
Cglib代理
我们一般都会用jdk动态代理,但有时候如果用到Cglib代理,注意invoke方法中的调用方法,不再是jdk动态代理中的invoke()而是invokerSuper()
0 条评论
下一页