面试题整理

本文详细介绍了Java垃圾收集器的CMS、G1和ZGC策略,包括它们的各个阶段和特点。CMS通过并发标记和清除来减少停顿时间,G1能利用多CPU优势并支持并发。ZGC则着重于缩短停顿时间。文章还涵盖了并发编程、数据库优化、Spring的依赖注入、一致性模型、锁机制的比较以及线程同步工具CountDownLatch。最后讨论了代码审查注意事项和SQL性能优化策略,包括索引创建原则。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

gc策略 cms g1 和 zgc 

1. 初始标记(CMS initial mark)

2. 并发标记(CMS concurrent mark)

3. 重新标记(CMS remark)

4. 并发清除(CMS concurrent sweep)

G1能充分利用多CPU,多核的硬件优势来缩短Stop—The—World停顿的时间,部分其它收集器原本需要停顿用户线程执行的GC动作,
G1依然可以通过并发的方式让用户线程继续执行。

并行 指用户线程与垃圾收集线程同时执行(但不一定是并行的,可能会交替执行);
用户程序在继续运行,而垃圾收集程序线程运行于另一个CPU上
    
zgc 缩短时长的策略几乎都是从串行改为并行

做了哪些工作来提高查询的速度 查询的并发数 
单个reqeust 对CPU消耗越高,外部系统接口、IO影响速度越慢,系统吞吐能力越低,反之越高。

2.1增加并发数1.比如增加tomcat并发的线程数,开喝服务器性能匹配的线程数,可以更多满足服务请求。
2.增加数据库的连接数,预建立合适数量的TCP连接数
3.后端服务尽量无状态话,可以更好支持横向扩容,满足更大流量要求
4.调用链路上的各个系统和服务尽量不要单点,要从头到尾都是能力对等的,不能让其中某一点成为瓶颈。
5.RPC调用的尽量使用线程池,预先建立合适的连接数。

2.2减少平均响应时间
1.请求尽量越前结束,越好,这样压力就不要穿透到后面的系统上,可以在各个层上加上缓存
2.流量消峰。放行适当的流量,处理不了的请求直接返回错误或者其他提示。和水坝道理很类似
3.减少调用链
4.优化程序
5.减少网络开销,适当使用长连接
6.优化数据库,建立索引


spring生成对象默认是单例的。通过scope属性可以更改为多例
Spring核心机制:依赖注入  反射

控制反转还是依赖注入,他们都可以这样理解:当某个Java实例(调用者)需要另一个Java实例(被调用者)时,在传统的程序设计过程中,通常有调用者来创建被调用者的实例。但是在依赖注入/控制反转模式下,创建被调用者的工作不再是有调用者来完成,而是由Spring容器来完成,然后注入调用者。
 
          对于Spring而言,Spring采用动态、灵活的方式来管理各种对象。对象与对象之间的具体实现都是透明的。Spring的依赖注入对调用者和被调用者几乎没有任何要求,完全支持对POJO之间依赖关系的管理。
 
          依赖注入通常有如下两种:
         1、  
设置注入:IoC容器使用属性的setter方法来注入被依赖的实例。
         2、  
构造注入:IoC容器使用构造器来注入被依赖的实例。


一致性模型数据的一致性模型可以分成以下 3 类:
强一致性:数据更新成功后,任意时刻所有副本中的数据都是一致的,一般采用同步的方式实现。
弱一致性:数据更新成功后,系统不承诺立即可以读到最新写入的值,也不承诺具体多久之后可以读到。
最终一致性:弱一致性的一种形式,数据更新成功后,系统不承诺立即可以返回最新写入的值,但是保证最终会返回上一次更新操作的值。

yncronized 与 lock 区别

下,你对synchronized是不是了解的很清晰了呢。接下来我们再聊一聊Lock。

Lock:Lock实现和synchronized不一样,后者是一种悲观锁,它胆子很小,它很怕有人和它抢吃的,所以它每次吃东西前都把自己关起来。
而Lock呢底层其实是CAS乐观锁的体现,它无所谓,别人抢了它吃的,它重新去拿吃的就好啦,所以它很乐观。具体底层怎么实现,


可见性与原子性
   可见性:一个线程对共享变量的修改,更够及时的被其他线程看到
   原子性:即不可再分了,不能分为多步操作。比如赋值或者return。比如"a = 1;"和 "return a;"这样的操作都具有原子性。类似"a += b"这样的操作不具有原子性,在某些JVM中"a += b"可能要经过这样三个步骤:
① 取出a和b
② 计算a+b
③ 将计算结果写入内存

(1)Synchronized:保证可见性和原子性    Synchronized能够实现原子性和可见性;在Java内存模型中,synchronized规定,线程在加锁时,先清空工作内存→在主内存中拷贝最新变量的副本到工作内存→执行完代码→将更改后的共享变量的值刷新到主内存中→释放互斥锁。
(2)Volatile:保证可见性,但不保证操作的原子性

Synchronized和Volatile的比较    
1)Synchronized保证内存可见性和操作的原子性   
 2)Volatile只能保证内存可见性   
 3)Volatile不需要加锁,比Synchronized更轻量级,并不会阻塞线程(volatile不会造成线程的阻塞;synchronized可能会造成线程的阻塞。)    
4)volatile标记的变量不会被编译器优化,而synchronized标记的变量可以被编译器优化(如编译器重排序的优化).   
 5)volatile是变量修饰符,仅能用于变量,而synchronized是一个方法或块的修饰符。

主线程等待所有线程都运行完后,再执行逻辑
,这个需求很普遍。比如,在处理数据时,为了效率期间,起了10个线程,分别处理一块数据,这样能缩短处理时间,10个线程都执行完后,继续进行下边的逻辑(有点map/reduce的意思)

。这里我们就需要用到java的线程同步类 CountDownLatch ,count down是计数的意思,latch是门闩的意思,合起来也就是计数的开关。我们看一下CountDownLatch的API。

个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。
  
  用给定的计数 初始化 CountDownLatch。由于调用了 countDown() 方法,所以在当前计数到达零之前,await 
  方法会一直受阻塞。之后,会释放所有等待的线程,await 
  的所有后续调用都将立即返回。这种现象只出现一次——计数无法被重置。如果需要重置计数,请考虑使用 CyclicBarrier。
  
  CountDownLatch 是一个通用同步工具,它有很多用途。将计数 1 初始化的 CountDownLatch 
  用作一个简单的开/关锁存器,或入口:在通过调用 countDown() 的线程打开入口前,所有调用 await 的线程都一直在入口处等待。用 
  N 初始化的 CountDownLatch 可以使一个线程在 N 个线程完成某项操作之前一直等待,或者使其在某项操作完成 N 
  次之前一直等待。
  
  CountDownLatch 的一个有用特性是,它不要求调用 countDown 
  方法的线程等到计数到达零时才继续,而在所有线程都能通过之前,它只是阻止任何线程继续通过一个 await。


codeReview 时候主要关注哪些方面?有那些固定的代码规范 
比如 代码提交前一定要格式化   异常处理不能吃掉异常 
集合初始化时,指定集合初始值大小 如hashmap 默认是16
java.util.Objects#equals (JDK7引入的工具类)
在foreach循环里进行元素的remove/add操作。remove元素请使用Iterator方式,如果并发操作,需要对Iterator对象加锁。

捕获异常是为了处理它,不要捕获了却什么都不处理而抛弃之,如果不想处理它,请将该异常抛给它的调用者。最外层的业务使用者,必须处理异常,将其转化为用户可以理解的内容。


mysql问题

如何提高sql语句的执行效率 有哪些方面需要注意    关联表少 建立索引 频率高 多字段组合 不要用模糊 计算 索引范围太小 分辨率   最左原则不知道  b+数 

mysql的索引的原则  用在a、b两列上创建复合索引,应该把a放前面,还是把b放前面    

mysql的两种存储引擎的索引存储机制
MyISAM索引实现 InnoDB索引实现

目前大部分数据库系统及文件系统都采用B-Tree或其变种B+Tree作为索引结构
B-树的特性:
1.关键字集合分布在整颗树中;
2.任何一个关键字出现且只出现在一个结点中;
3.搜索有可能在非叶子结点结束;
4.其搜索性能等价于在关键字全集内做一次二分查找;
5.自动层次控制

请简述项目中优化sql语句执行效率的方法,从哪些方面。sql语句性能如何分析?

(1)尽量选择较小的列 
(2)将where中用的比较频繁的字段建立索引 
(3)select子句中避免使用‘*’ 
(4)避免在索引列上使用计算,not,in和<>等操作 
(5)当只需要一行数据的时候使用limit 1 
(6)保证表单数据不超过200w,适时分割表 
(7)针对查询较慢的语句,可以使用explain来分析该语句具体的执行情况

建索引的几大原则
(1) 最左前缀匹配原则

对于多列索引,总是从索引的最前面字段开始,接着往后,中间不能跳过。比如创建了多列索引(name,age,sex),会先匹配name字段,再匹配age字段,再匹配sex字段的,中间不能跳过。mysql会一直向右匹配直到遇到范围查询(>、<、between、like)就停止匹配。
(2) 尽量选择区分度高的列作为索引
(3) =和in可以乱序

比如a = 1 and b = 2 and c = 3,建立(a,b,c)索引可以任意顺序,mysql的查询优化器会帮你优化成索引可以识别的形式。

(4) 索引列不能参与计算,保持列“干净”

比如:Flistid+1>‘2000000608201108010831508721‘。原因很简单,假如索引列参与计算的话,那每次检索时,都会先将索引计算一次,再做比较,显然成本太大。

(5) 尽量的扩展索引,不要新建索引。

mysql可以开启慢sql日志 通过查看日志文件来监控慢sql

也可以使用Druid连接池来监控SQL执行状态

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值