赞
踩
使用redis为对象做持久化,就是把内存里的对象保存到磁盘(暂且叫做磁盘吧,可以等同于sp、db、文件、网络等)上,等以后需要这个对象的时候再从磁盘上还原到内存,因此需要序列化和反序列化。
什么是策略模式:
策略模式是对算法的包装,是把使用算法的责任和算法本身分隔开来,委派给不同的对象管理,最终可以实现解决多重if判断问题:
为什么叫策略模式:
每个if判断都可以理解为就是一个策略。
- public String toPay(String payCode){
- if(payCode.equals("ali_pay")){
- return "调用支付宝接口支付";
- }
- if(payCode.equals("weixin_pay")){
- return "调用微信支付接口支付";
- }
- if(payCode.equals("yinlian_pay")){
- return "调用银联支付接口支付";
- }
- return "未找到该支付接口";
- }
我们来看上面一段代码,我们传不同的payCode,得到对应的支付平台,调用接口行为是相同的,调用接口代码是不同的。
一、锁的优化的思路和方法
1、减少锁持有时间
2、减小锁粒度
(1)将大对象拆分成小对象,大大增加并行度,降低锁竞争
(2)偏向锁,轻量级锁成功率提高
(3)ConcurrentHashMap
- 若干个Segment:Segment<K,V>[]segments
- Segment中维护HashEntry<K,V>
- pu操作时,先定位到Segment,锁定一个Segment,执行put
- 在减小锁粒度后,ConcurrentHashMap允许若干个线程同步进入
(4)HashMap的同步实现
- Collections.synchronizedMap(Map<K,V> m)
- 返回SynchronizedMap对象
3、锁分离
(1)根据功能进行锁分离
(2)ReadWriteLock
(3)读多写少的情况,可以提高性能
(4)只要操作互不影响,锁就可以分离
(5)LinkedBlockingQueue:队列、链表
4、锁粗化
通常情况下,为了保证多线程间的有效并发,会要求每个线程持有锁的时间尽量短,即在使用完公共资源后,应该立即释放锁。只有这样,等待在这个锁上的其他线程才能今早的获得资源执行任务。但如果对同一个锁不停的进行请求、同步和释放,其本身也会消除系统宝贵的资源,反而不利于性能的优化
5、锁消除
在即时编译器时,如果发现不可能被共享的对象,则可以消除这些对象的锁操作
二、虚拟机内的锁优化
1、对象头Mark
(1)Mark Word,对象头的标记,32位
(2)描述对象的hash、锁信息,垃圾回收标记,年龄
(3)指向锁记录的指针、指向monitor的指令、GC标记、偏向锁线程ID
2、偏向锁
(1)大部分情况是没有竞争的,所以可以通过偏向来提高性能
(2)所谓偏向,即锁会偏向于当前已经占有锁的线程
(3)将对象头Mark的标记设置为偏向,并将线程ID写入对象头Mark
(4)只要没有竞争,获得偏向锁的线程,在将来进入同步块,不需要做同步
(5)当其他线程请求相同的锁时,偏向模式结束
(6)在竞争激烈的场合,偏向锁会增加系统负担
4、spring的IOC和AOP在写代码的时候哪里有用到?
ioc:
- @Controller //控制器,推荐给Controller层添加此注解
- @Service //业务逻辑,推荐给业务逻辑层添加此注解
- @Repository //仓库管理,推荐给数据访问层添加此注解
- @Component //给不属于以上基层的类添加此注解
aop:
- //标记这个类是一个切面
- @Aspect
- public class AnnotationPointCut {
- @Before("execution(* com.wzq.service.UserServiceImpl.*(..))")
- public void before() {
- System.out.println("==========方法执行前==========");
- }
-
- @After("execution(* com.wzq.service.UserServiceImpl.*(..))")
- public void after() {
- System.out.println("==========方法执行前==========");
- }
-
- //在环绕增强中,可以给定一个参数,代表想要获取处理切入的点
- @Around("execution(* com.wzq.service.UserServiceImpl.*(..))")
- public void around(ProceedingJoinPoint jp) throws Throwable {
- System.out.println("Around ==========方法执行前==========");
- //执行
- Object proceed = jp.proceed();
- //获取签名
- Signature signature = jp.getSignature();
- System.out.println(signature);
- System.out.println("Around ==========方法执行后==========");
- }
- }
* 保证同一个事务中
PORPAGATION_REQUIRED:支持当前事务,如果不存在 就新建一个(默认)
PROPAGATION_SUPPORTS:支持当前事务,如果不存在,就不使用事务
PROPAGATION_MANDATORY:支持当前事务,如果不存在,抛出异常
* 保证没有在同一个事务中
PROPAGATION_REQUIRES_NEW:如果有事务存在,挂起当前事务,创建一个新的事务
PROPAGATION_NOT_SUPPORTED:以非事务方式运行,如果有事务存在,挂起当前事务
PROPAGATION_NEVER:以非事务方式运行,如果有事务存在,抛出异常
PROPAGATION_NESTED:如果当前事务存在,则嵌套事务执行
又要懒加载、又要高性能,又要线程安全的时候用
最左前缀原则:顾名思义是最左优先,以最左边的为起点任何连续的索引都能匹配上。
当创建(a,b,c)复合索引时,想要索引生效的话,只能使用 a和a,b和a,b,c三种组合
由于首页数据变化不是很频繁,而且首页访问量相对较大,所以我们有必要把首页接口数据缓存到redis缓存中,减少数据库压力和提高访问速度。
泛型的使用有效的降低了代码的冗余,减少了重复无用的代码,使代码的可读性更高,更简洁,同时也缩短了搬 砖工人的重复劳动时间。
T:表示确定的类型,最常用的泛型表示方法。
? :表示不确定的类型,类似于通配符。
类型参数T主要用于,声明泛型类或泛型方法。
无界通配符?主要用于,使用泛型类或泛型方法
@SpringBootConfiguration:
该注解由Spring原生注解@Configuraction封装而成。
@ComponentScan:
该注解主要用来开启组件扫描,可以扫描该注解标注的类、以及该注解标注的类的目录路径下的类,并将其实例注册添加到Spring容器中。此处需注意,由于Spring仅仅整合了自己的注解,并没有接收Mybatis的注解,因此SpringBoot整合Mybatis时,需要额外添加注解:@MapperScan(“/指向mybatis的包路径”)
@EnableAutoConfiguration:
该注解主要用来提供自动装配,是这三个注解中最重要的一个注解。她是Spring Boot新添加的注解,提供了强大的自动依赖功能,是SpringBoot这么方便的大功臣。
自动装配原理:
@EnableAutoConfiguration注解的关键在于引入了AutoConfigurationImportSelector,其核心逻辑为selectImports方法,逻辑大致如下:
从配置文件META-INF/spring.factories加载所有可能用到的自动配置类;去重,并将exclude和excludeName属性携带的类排除;过滤,将满足条件(@Conditional)的自动配置类返回。
通过SqlSessionFactoryBuilder从mybatis-config.xml配置⽂件中构建出SqlSessionFactory会话工厂,然后SqlSessionFactory的实例直接开启⼀个SqlSession会话对象,再通过SqlSession实例获得Mapper对象并运⾏Mapper映射的SQL语句,完成对数据库的CRUD和事务提交,之后关闭SqlSession。
Zipkin 是一款开源的分布式实时数据追踪系统,由基于 Google Dapper 的论文设计而来,由 Twitter 公司提供开源实现,主要功能是聚集来自各个异构系统的实时监控数据,和微服务架构下的接口直接的调用链路和系统延时问题。
链路追踪即通过跟踪一个请求从发布到被响应的整个过程,了解到每个请求的详细经过,比如有哪些服务参与,参与顺序是什么,各服务调用了多少次数据库等。如此一来 ,当出现异常问题,开发就能快速定位问题根源,快速解决问题。
链路追踪优点:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。