java实战面试问题汇总
JAVA层面
jvm参数调优
-server 一定要作为第一个参数,在多个cpu时性能最佳。
-Xms:设置JVM初始分配的堆内存。
-Xmx:设置JVM最大可用堆内存。
-Xms 默认是物理内存的1/64;-Xmx默认为物理内存的1/4。
如果-Xmx不指定或者偏小,应用可能会导致java.lang.OutofMemory,此错误来自JVM,不是Throwable,无法用try…catch捕捉。
JVM内存模型
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3fmUJyTU-1631955472928)(C:\Users\50470\AppData\Roaming\Typora\typora-user-images\image-20210803214030454.png)]
方法区,java堆,java栈,程序计数器,本地方法栈。
JVM内存模型:
jvm运行时内存 = 共享内存区 + 线程内存区;
共享内存区 = 持久代 + 堆
java的反射原理
指的是运行状态下,对任意一个类,都能够知道这个类的所有属性和方法;
对于任意一个对象,都能调用它的任意一个方法。
Spring层面
spring中Bean的装配流程
先走构造函数 -> 然后就是Bean的Set方法注入->InitializingBean的afterPopertiesSet方法->init-method方法
Spring的常用的注解
声明bean:
@Controller,@RestController,@responseBody,@RequestMapping,@GetMapping,@PostMapping,@Service,@Respository
注入:
@Autowired,@Resource
配置类:
@Bean,@Configuration,@ComponentScan
SpringMVC的流程
① 用户向服务器断发送一次请求,请求会先到前端控制器DispatcherServlet
② DispatcherServlet接收到请求后会调用HandlerMapping处理器映射器,具体分配到哪个controller执行
③ Controller之后得到ModelAndView,并层层返回给DispatcherServlet
④ DispatcherServlet将ModelAndView将给ViewReslover解析器解析,然后返回真正的视图
⑤ DispatcherServlet将模型数据填充到视图中
⑥ DispatcherServlet将结果响应给用户
SpringClound的常用组件
Eureka:
服务治理,主要用来实现各个微服务实例的自动化注册和发现。
Ribbon:
客服端的负载均衡
Hystrix:
断路器
Zuul:
服务网关
Config:
分布式配置
HTPP的三次握手,详细说明
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Q7M6KFH4-1631955472929)(C:\Users\50470\AppData\Roaming\Typora\typora-user-images\image-20210728224103856.png)]
- 客户端向服务器发出请求连接报文。
- 服务收到请求报文后,如果同意,则发出确认报文。
- 客户端收到服务器确认之后,再向服务器给出确认,此时客户端进入established(已建立连接)状态。
- 当服务器收到客户端确认请求之后,服务器就进入established(已建立连接)状态,双方可以开始通信。
分布式锁是怎么实现的
使用ZooKeeper来实现分布式锁
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BFPwMnva-1631955472930)(C:\Users\50470\AppData\Roaming\Typora\typora-user-images\image-20210803233152249.png)]
排队机制:
① 首先创建一个锁节点下的一个接着一个的临时节点
② 如果自己不是第一个节点,会对上一个节点加监听器
③只要上一个节点释放了锁,自己就排到前面去了,相当于排队机制
自动释放锁机制:
某一个客户端创建临时顺序节点之后,不小心宕机了,zk可以知道宕机的客户端,会自动删除对应的临时顺序节点,相当于自动释放锁。
分布式事务如何实现
使用TCC编程模型
包含三个阶段:Try,Confirm,Cancel
Try:尝试执行业务,完成所有的业务检查,预留相应的引入资源。
Confirm:如果Try阶段执行成功,不再进行业务检查,进行真正的业务提交,只要Try成功,Confirm阶段一定成功。
Cancel:此阶段是发生在Try阶段出现失败的时候,回滚之前的操作。
Mysql层面
mysql的索引结构
mysql索引的数据结构就是用到的B+树
数据只会存在叶子节点上面,非叶子节点只存放索引列的数据
怎么优化SQL
①尽量避免全表扫描,首先考虑到where以及order by涉及的列上建立索引
②尽量避免在where子句中进行null指判断
③尽量避免在where子句中使用or来连接条件
④任何时候不要使用select * from table
慢查询怎么排查
oracle:查看解释计划
mysql:执行show processlist;查看mysql正在运行的sql线程;可以看到sql语句的运行时间
数据库事务的特性
【ACID】
Atomicity :原子性
Consistency:一致性
Durability:持久性
Isolation:隔离性
Redis层面
redis的基本类型
string,list,hash,set,zset
redis分布式锁实现原理
先拿 setnx 来争抢锁,抢到之后,再用 expire 给锁加一个过期时间防止锁忘记了释放。 如果在 setnx 之后执行 expire 之前进程意外 crash 或者要重启维护了,那会怎么样? set 指令有非常复杂的参数,这个应该是可以同时把 setnx 和 expire 合成一条指令来用的!
基于Redis实现的分布式锁常用的框架是Redisson
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rWPapY9T-1631955472931)(C:\Users\50470\AppData\Roaming\Typora\typora-user-images\image-20210803231720617.png)]
某个客户端要加锁。如果该客户端面对的是一个Redis Cluster集群,它首先会根据hash节点选择一台机器,这里注意,仅仅只是选择一台机器。紧接着就会发送一段lua脚本到redis上。
锁互斥机制:
如果有其他客户端进行加锁,会进行判断,会获取到锁的剩余生存时间,此时客户端进行不断while循环,尝试加锁。
watch线程自动延期机制:
客户端A加锁的锁key默认生存时间只有30秒,如果超过了30秒,客户端A还想一直持有这把锁,怎么办?其实只要客户端A一旦加锁成功,回启动一个后台线程,会每隔10秒检查一下,如果客户端A还持有锁key,那么就会不断的延长锁key的生存时间。
可重入加锁机制:
当存在锁时,可以继续lock()进行加锁。
Liunx层面
linux的常用命令
ls:命令
cat:查看文件内容
cd:进入目录
pwd:查看当前工作目录
mkdir:创建目录
rm -f 删除名称
vi,vim 修改文件;wq:保存修改;q:不保存修改
echo打印命令
其他层面
瀑布开发,敏捷开发,迭代开发的区别
Liunx层面
linux的常用命令
ls:命令
cat:查看文件内容
cd:进入目录
pwd:查看当前工作目录
mkdir:创建目录
rm -f 删除名称
vi,vim 修改文件;wq:保存修改;q:不保存修改
echo打印命令