两个方法都使用iterator解决
过程:
获取 map/list的iterator
whlie(iterator.hasNext){
//获取下一个元素
entry = iterator.next();
if(entry.getKey == 指定的值)
iterator.remove()
}
并发注意加锁
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(3, 10,
200, TimeUnit.SECONDS, new ArrayBlockingQueue<>(100), new ThreadPoolExecutor.CallerRunsPolicy());
1.线程等待实现,缺点:实现功能有限,需要手动实现
2.JDK自带的Timer实现,缺点:基于绝对时间,不是相对时间,不会捕获异常
3.JDK自带ScheduledExecutorservice,缺点:只有执行时调度才是一个真正的线程,其余时间都是轮询任务的状态
4.Quartz框架结合Spring实现
5.Spring Task 由@Scheduled指定执行 可以使用fixedDelay和fixedRate,缺点:不支持持久化,
6.Quartz 分布式 异步策略保证唯一性 缺点:只解决高可用问题,处理瓶颈在数据库,没有执行层面的任务分片,无法zzuzui最大化效率
7.经常用轻量级神器XXL-Job,特点:平台化、易部署、开发迅速、学习简单、轻量级、易扩展
8.Elastic-job、Saturn基于Elastic-job(唯品会)
1.不关闭资源引发内存泄露,如数据库连接、网络连接、IO连接、使用忘了关闭,GC无法回收
静态集合、饿汉单例、不合理的设置变量作用域都会使对象生命周期变长,从而导致内存泄漏
非静态内部对象有隐式指向外部对象的指针、使用集合不删除元素等都会隐式导致内存泄漏
忘记关闭资源导致内存泄漏(try-with-resource自动关闭解决)
使用散列表时,充当Key 对象的哈希值被改变导致内存泄漏(key 使用逻辑不可变对象,关键域不能被修改)
缓存引发内存泄漏(使用弱引用解决)
static List list = new ArrayList<>();
@Test
public void Test() {
Object object = new Object();
list.add(object);
}
客户端与服务端的约定,是否关闭TCP连接。
复用减少创建/关闭d多个TCP连接的开销(响应时间、cpu资源等)
优化:
控制持久的生存时间和最大服务请求数
方法1:
如果配置慢SQL参数,在/etc/my.cnf
文件位置
默认会保存在mysql的data文件夹下,文件名为host_name-slow.log即 主机名-slow.log
这时你可以去查看日志,记录了查询慢的sql语句,分析优化进行。
方法2:
使用 top 查看进程
top -H -p
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
23974 mysql 20 0 1658m 358m 12m R 99.9 1.1 0:05.52 mysqld
12295 mysql 20 0 1658m 358m 12m S 0.3 1.1 0:02.44 mysqld
12283 mysql 20 0 1658m 358m 12m S 0.0 1.1 0:01.60 mysqld
12284 mysql 20 0 1658m 358m 12m S 0.0 1.1 0:00.00 mysqld
12285 mysql 20 0 1658m 358m 12m S 0.0 1.1 0:02.63 mysqld
12286 mysql 20 0 1658m 358m 12m S 0.0 1.1 0:02.24 mysqld
12287 mysql 20 0 1658m 358m 12m S 0.0 1.1 0:01.68 mysqld
12288 mysql 20 0 1658m 358m 12m S 0.0 1.1 0:01.77 mysqld
12289 mysql 20 0 1658m 358m 12m S 0.0 1.1 0:01.64 mysqld
12290 mysql 20 0 1658m 358m 12m S 0.0 1.1 0:01.80 mysqld
12291 mysql 20 0 1658m 358m 12m S 0.0 1.1 0:02.37 mysqld
方法3:
查询低效率sql:show processlist
然后 根据 explain 分析执行计划
1.两个sql都有锁的情况,互相访问对方的加锁数据会产生死锁
锁表情况:
1.多个数据库连接,同时对一个表的数据进行更新操作,持续一段时间后将出现数据表被锁的现象
解决办法:相关字段加索引
2.并发情况下:
索引字段且值不是唯一
更新操作如果一个id 有多个值相同的记录,会锁表
解决办法:索引唯一则是行锁,反之锁表
3.同一个表,有两个索引 A,B字段
delete from table where A=1 and b=2
delete from table where A=1
也会锁表,解决方法:删除条件尽量统一
order by 、group by、limit、通配符、子查询、正则表达式、
运算符如算术、比较、逻辑
聚合函数如sum等、字符串函数length、trim等
日期函数如day、week、dayofweek等
连表如 inner join 、left join等
视图如创建视图、更新视图等
1.实现applicationListener容器刷新成功,应用程序可以达到 监听容器初始化完成事件
2.实现ServletContextAware接口重写setServletContext方法
3.实现ServletContextListener接口重写contextlnitialized方法
4.@PostConstruct注解 前提这些操作不依懒其它Bean的初始化
5.实现ApplicationRunner接口重写runf方法
6.实现CommandLineRunner接口重写run方法
applicationRunner比CommandLineRunner先执行
等方法
控制bean初始化顺序
7.实现ordered接口
8.使用@order注解
指系统中的所有数据副本经过一段时间后,最终能够达到一致的状态
基如消息队列的解决方案
如使用RabbitMQ实现分布式事务的最终一致性。
如 电商系统
用户下单和支付不是同时进行的,使用MQ的延迟队列,设置30分钟支付过期时间,将该队列绑定到一个延迟交换机上
下单后先锁库存,如果没有支付、延迟队列没有被消费者消费,会被投递到绑定的死信交换机,并路由到死信队列。死信队列可以记录日志,发送告警等操作
支付成功代表消费者消费了订单信息,但处理失败,我们可以将消息重新发送到一个专门用于重试的队列,设置最大重试次数3次,重试间隔为5分钟。在重试队列中,消费者会尝试处理消息,并进行3次的重试,如果还是无法处理成功,则消息会被投递到绑定的死信交换机,并路由到死信队列