@Autowired
@Resource
@RequestMapping
@RequestBody
@GetMapping
@PostMapping
@PutMapping
@DeleteMapping
@PatchMapping
@ControllerAdvice
@ResponseBody
@ExceptionHandler
@ResponseStatus
@PathVariable
@RequestParam
@Controller
@RestController
@ModelAttribute
@CrossOrigin
@InitBinder
@SpringBootApplication
@EnableAutoConfiguration
@ConditionalOnClass与@ConditionalOnMissingClass
@ConditionalOnBean与@ConditionalOnMissingBean
@ConditionalOnProperty
@ConditionalOnResource
@ConditionalOnWebApplication与@ConditionalOnNotWebApplication
@ConditionalExpression
@Conditional
单例模式
工厂模式
原型模式
建造者模式
装饰器模式
模板方法模式
观察者模式
简单工厂(非23种设计模式中的一种)
工厂方法
单例模式
适配器模式
装饰器模式
代理模式
观察者模式
策略模式
模版方法模式
IOC是inverse of control的简写,译为控制反转,是一种创建对象的思想。那什么又是控制反转呢?就是将创建对象的权力交给Spring容器,其实就是让Spring容器帮你创建对象,而你不需要在javel代码中new对象了。在没学IOC之前,在java代码中,如果你想创建类名为ClassA的对象classa,你是怎么创建对象的呢?是不是这样:ClassA classa=new ClassA();
但是,学了IOC之后,我们想要获取对象classa就不需要写以上语句来获取了,而是加载Spring容器,Spring容器就会创建classa对象,我们直接拿过来使用就可以了
PointCut是指哪些方法需要被执行"AOP"PointCut表达式可以有一下几种方式
一般用于指定方法的执行
格式:execution( 方法类型(public等,可省略) 方法的返回值类型 包路径(可省略) 方法的名称(参数) 异常类型(可省略) )
是用来指定类型的,指定类型中的所有方法将被拦截是用来指定类型的,指定类型中的所有方法将被拦截
SpringAOP是基于代理的,this就代表代理对象,语法是this(type),当生成的代理对象可以转化为type指定的类型时表示匹配。
SpringAOP是基于代理的,target表示被代理的目标对象,当被代理的目标对象可以转换为指定的类型时则表示匹配。
args用来匹配方法参数
带有相应标注的所有类的任意方法,比如@Transactional
@within(org.springframework.transaction.annotation.Transactional)
@target(org.springframework.transaction.annotation.Transactional)
带有相应标注的任意方法,比如@Transactional
@annotation(org.springframework.transaction.annotation.Transactional)
@within和@target针对类的注解,@annotation针对方法的注解
参数带有相应标注的任意方法,比如@Transactional
@args(org.springframework.transaction.annotation.Transactional)
//PointCut表达式
@Pointcut("execution(public * com.example.demo.controller.UserController.*(..))")
//PointCut签名
public void log(){
}
//下面直接调用log(),相当于直接使用上面的表达式,简化代码
@After("log()")
public void doAfter(){
logger.info("222222222");
}
PointCut中可以使用&&、||、!运算
@Pointcut("execution(public * com.example.demo.controller.UserController.*(..))")
public void cutController(){
}
@Pointcut("execution(public * com.example.demo.Service.UserService.*(..))")
public void cutService(){
}
//使用 && 运算符,则cutAll()的作用等同于 cutController 和 cutService 之和
@Pointcut("cutController() && cutService()")
public void cutAll(){
}
Spring Aop的代理主要分为三个步骤:获取所有的Advisor,过滤可应用到当前bean的Adivsor和使用Advisor为当前bean生成代理对象
SOA(面向服务的架构)定义了一种可通过服务接口复用软件组件并实现其互操作的方法。 服务使用公共接口标准和架构模式,因此可以快速整合到新应用中。 这让应用开发人员无需像之前那样重新开发或复制现有功能,也不必了解如何连接现有功能或提供与现有功能的互操作性 。
WSDL 是基于 XML 的用于描述 Web Services 以及如何访问 Web Services 的语言。
Web Service也叫XML Web Service WebService是一种可以接收从Internet或者Intranet上的其它系统中传递过来的请求,轻量级的独立的通讯技术。是:通过SOAP在Web上提供的软件服务,使用WSDL文件进行说明,并通过UDDI进行注册。
最开始是应用于淘宝网,由阿里巴巴开源的一款优秀的高性能服务框架,由Java开发,后来贡献给了Apache组织
PROPAGATION_REQUIRED:支持当前事务,如果不存在就新建一个(默认) ;
PROPAGATION_REQUIRES_NEW:开启一个新的事务,如果一个事务已经存在,则将这个存在的事务挂起;
PROPAGATION_SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式执行。
PROPAGATION_NOT_SUPPORTED:以非事务方式运行,如果有事务存在,挂起当前事务;
PROPAGATION_MANDATORY:必须运行在一个事务中,如果当前没有事务正在发生,将抛出一个异常;
PROPAGATION_NEVER:以非事务方式运行,如果有事务存在,抛出异常;
PROPAGATION_NESTED:如果当前正有一个事务在进行中,则该方法应当运行在一个嵌套式事务中。被嵌套的事务可以独立于封装事务进行提交或回滚。如果封装事务不存在,行为就像PROPAGATION_REQUIRES一样。
关键字 LIMIT
explain select 投影列 FROM 表名 WHERE 条件
rownum:伪列。顾名思义:是数据库自己创建出来的字段。
字符大小写转换函数 UPPER LOWER INITCAP
去除空白及字符串函数 TRIM,LTRIM,RTRIM
substr 、 substrb截取字符函数
length、lengthb查询字符串长度
concat、||字符串连接
instr:字符查找函数
ASCII、CHR:ascii
lpad、rpad字符填充函数
regexp_replace、translate:替换函数
extract,to_char提取日期及获取时间差
redis缓存
1.缓存概述:
流程图:
代码逻辑
2.缓存方式
2.1 不设置过期时间
数据同步:
内存消耗:
2.2设置过期时间
内存资源
过期时间设置
3.名称解释
缓存穿透
缓存雪崩
缓存击穿
SELECT * FROM cliente with(ROWLOCK) where idCliente='850'
行锁
支持的存储引擎:Innodb;
InnoDB行锁是通过给索引上的索引项加锁来实现的,意味着:只有通过索引条件检索数据,InnoDB才使用行级锁,否则,InnoDB将使用表锁!
适用场景:有大量按索引条件并发更新少量不同数据,同时又有并发查询的应用
特点:开销大,加锁慢;会出现死锁;锁定粒度小,发生锁冲突的概率低,并发度高
分析:show status like ‘innodb_row_lock%’;分析系统上行锁的争夺情况如果发现锁争用比较严重,如InnoDB_row_lock_waits和InnoDB_row_lock_time_avg的值比较高,还可以通过设置InnoDB Monitors来进一步观察发生锁冲突的表、数据行等,并分析锁争用的原因。
表锁
支持的存储引擎:Innodb、MYIsam
适用场景:以查询为主,只有少量按索引条件更新数据的应用
特点:开销小,加锁快;不会出现死锁;锁定力度大,发生锁冲突概率高,并发度最低
两种模式:
对两张表显示加锁、解锁
Lock tables orders read local, order_detail read local;
Select sum(total) from orders;
Select sum(subtotal) from order_detail;
Unlock tables;
MyISAM在执行查询语句(SELECT)前,会自动给涉及的所有表加读锁,在执行更新操作(UPDATE、DELETE、INSERT等)前,会自动给涉及的表加写锁
要存储可变长度的字符串,可以使用Oracle VARCHAR2数据类型。 VARCHAR2列可以存储1到4000字节的值。 这意味着对于单字节字符集,最多可以在VARCHAR2列中存储4000个字符。
对于MySQL,InnoDB存储引擎的话,单表最多可以存储10亿级数据。但是的话,如果真的存储这么多,性能就会非常差。一般数据量千万级别,B+树索引高度就会到3层以上了,查询的时候会多查磁盘的次数,SQL就会变慢。
阿里巴巴的《Java开发手册》提出:
单表行数超过500万行或者单表容量超过2GB,才推荐进行分库分表。
那我们是不是等到数据量到达五百万,才开始分库分表呢?
不是这样的,我们应该提前规划分库分表,如果估算3年后,你的表都不会到达这个五百万,则不需要分库分表。
MySQL服务器如果配置更好,是不是可以超过这个500万这个量级,才考虑分库分表?
虽然配置更好,可能数据量大之后,性能还是不错,但是如果持续发展的话,还是要考虑分库分表
一般什么类型业务表需要才分库分表?
通用是一些流水表、用户表等才考虑分库分表,如果是一些配置类的表,则完全不用考虑,因为不太可能到达这个量级。
分库分表15道面试题
MyBatis应用程序根据XML配置文件创建SqlSessionFactory,SqlSessionFactory在根据配置,配置来源于两个地方,一处是配置文件,一处是Java代码的注解,获取一个SqlSession。SqlSession包含了执行sql所需要的所有方法,可以通过SqlSession实例直接运行映射的sql语句,完成对数据的增删改查和事务提交等,用完之后关闭SqlSession。
case when
foreach成多条sql
ON DUPLICATE KEY UPDATE (mysql)
replace into (mysql)
HashMap对象的key、value值均可为null。
HahTable对象的key、value值均不可为null。
且两者的的key值均不能重复,若添加key相同的键值对,后面的value会自动覆盖前面的value,但不会报错。
线性安全的
Vector:只要是关键性的操作,方法前面都加了synchronized关键字,来保证线程的安全性
Hashtable:使用了synchronized关键字,所以相较于Hashmap是线程安全的。
ConcurrentHashMap:使用锁分段技术确保线性安全,是一种高效但是线程安全的集合。
Stack:栈,也是线程安全的,继承于Vector。
线性不安全的
Hashmap
Arraylist
LinkedList
HashSet
TreeSet
TreeMap
值得注意的是:为了保证集合是线程安全的,相应的效率也比较低;线程不安全的集合效率相对会高一些。
Hashmap的底层原理
HashMap基于hashing原理,我们通过put()和get()方法储存和获取对象。当我们将键值对传递给put()方法时,它调用键对象的hashCode()方法来计算hashcode,让后找到bucket位置来储存值对象。当获取对象时,通过键对象的equals()方法找到正确的键值对,然后返回值对象。HashMap使用链表来解决碰撞问题,当发生碰撞了,对象将会储存在链表的下一个节点中。 HashMap在每个链表节点中储存键值对对象。
当两个不同的键对象的hashcode相同时会发生什么? 它们会储存在同一个bucket位置的链表中。键对象的equals()方法用来找到键值对。
18之后的底层数据结构
数组+单线链表+红黑树(1.8)
CurrentHashMap的实现原理
ConcurrentHashMap的出现主要为了解决hashmap在并发环境下不安全,JDK1.8ConcurrentHashMap的设计与实现非常精巧,大量的利用了volatile,CAS等乐观锁技术来减少锁竞争对于性能的影响,ConcurrentHashMap保证线程安全的方案是:
JDK1.8:synchronized+CAS+HashEntry+红黑树
;
JDK1.7:ReentrantLock+Segment+HashEntry。
FastJson GSON解析
Gson:https://github.com/google/gson 【谷歌开发的 JSON 库,功能十分全面】
FastJson:https://github.com/alibaba/fastjson 【阿里巴巴开发的 JSON 库,性能十分优秀】
Jackson:https://github.com/FasterXML/jackson 【社区十分活跃且更新速度很快】
相同点:
(1)都不能被实例化
(2)接口的实现类或抽象类的子类都只有实现了接口或抽象类中的方法后才能实例化。
不同点:
(1)接口只有定义,不能有方法的实现,java 1.8中可以定义default方法体,而抽象类可以有定义与实现,方法可在抽象类中实现。
(2)实现接口的关键字为implements,继承抽象类的关键字为extends。一个类可以实现多个接口,但一个类只能继承一个抽象类。所以,使用接口可以间接地实现多重继承。
(3)接口强调特定功能的实现,而抽象类强调所属关系。
(4)接口成员变量默认为public static final,必须赋初值,不能被修改;其所有的成员方法都是public、abstract的。抽象类中成员变量默认default,可在子类中被重新定义,也可被重新赋值;抽象方法被abstract修饰,不能被private、static、synchronized和native等修饰,必须以分号结尾,不带花括号。
(5)接口被用于常用的功能,便于日后维护和添加删除,而抽象类更倾向于充当公共类的角色,不适用于日后重新对立面的代码修改。功能需要累积时用抽象类,不需要累积时用接口。
不可以
可以,但是自己写的类是不可以的,不然就没办法new对象
可以的情况:API中的Math类
在单例模式构造函数是可以private的,用静态成员函数GetInstance来获得实例。
并发和并行之间的区别。
并发(concurrency):把任务在不同的时间点交给处理器进行处理。在同一时间点,任务并不会同时运行。
并行(parallelism):把每一个任务分配给每一个处理器独立完成。在同一时间点,任务一定是同时运行。
并发不是并行。并行是让不同的代码片段同时在不同的物理处理器上执行。并行的关键是同时做很多事情,而并发是指同时管理很多事情,这些事情可能只做了一半就被暂停去做别的事情了。
在很多情况下,并发的效果比并行好,因为操作系统和硬件的总资源一般很少,但能支持系统同时做很多事情。这种“使用较少的资源做更多的事情”的哲学,也是指导 Go语言设计的哲学。
方式一:通过break标签跳出多重循环
方式二:循环条件限制
方式三:内层循环抛出异常结束多重循环
1.M m是为了区分“月”与“分”,M:月,m:分
2.H h是为了区分12小时制与24小时制,H是24小时制,h是12小时制。
y
Week year意思是当天所在的周属于的年份,一周从周日开始,周六结束,只要本周跨年,那么这周就算入下一年。例如2017年12月31日,本周(2017年12月31日-2018年1月6日)本周跨年了。就进入了下一年。
private void testString(){
String string="0079527大白菜";
char foodName[]=string.toCharArray();
StringBuilder stringBuilder=new StringBuilder();
for (int i = 0; i < foodName.length; i++) {
char c=foodName[i];
boolean isDigit=Character.isDigit(c);
if (!isDigit) {
stringBuilder.append(c);
}
}
System.out.println("原来的字符串:"+string+",改后的字符串:"+stringBuilder.toString());
}
语法 :字符串名.charAt(值); 返回值为 char 类型。从字符串中取出指定位置的字符
代码如下(示例):
String str="淡忘_Java";
char c = str.charAt(3);
System.out.println("指定字符为:" + c);
运行结果:指定字符为:J
String substring(int beginIndex,int endIndex) 截取字符串
String str = "123淡忘_Java博客456";
System.out.println("截取后的字符为:" + str.substring(0, 3));// 截取0-3个位置的内容 不含3
System.out.println("截取后字符为:" + str.substring(2));// 从第3个位置开始截取 含2
运行结果:
截取后的字符为:123
截取后字符为:3淡忘_Java博客456
string.length
string.length()
实例化一个对象
97~122
int add(int a, int b) {
return a-(-b);
}
public int add(int a, int b) {
while (b != 0) {
int sum = a ^ b;
int carry = (a & b) << 1;
a = sum;
b = carry;
}
return a;
}
public ThreadPoolExecutor(
int corePoolSize,//线程池核心线程大小
int maximumPoolSize,//线程池最大线程数量
long keepAliveTime,//空闲线程存活时间
TimeUnit unit,//空闲线程存活时间单位,一共有七种静态属性(TimeUnit.DAYS天,TimeUnit.HOURS小时,TimeUnit.MINUTES分钟,TimeUnit.SECONDS秒,TimeUnit.MILLISECONDS毫秒,TimeUnit.MICROSECONDS微妙,TimeUnit.NANOSECONDS纳秒)
BlockingQueue<Runnable> workQueue,//工作队列
ThreadFactory threadFactory,//线程工厂,主要用来创建线程(默认的工厂方法是:Executors.defaultThreadFactory()对线程进行安全检查并命名)
RejectedExecutionHandler handler//拒绝策略(默认是:ThreadPoolExecutor.AbortPolicy不执行并抛出异常)
)
使用示例:
ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 20, 2, TimeUnit.SECONDS, new LinkedBlockingQueue<>(5));
final修饰类不可以被继承,但是可以继承其他类,使用方式跟其它类一样
date
查看