→ 注解

元注解、自定义注解、注解与反射的结合

元注解:

  • Documented——指明拥有这个注解的元素可以被javadoc此类的工具文档化。这种类型应该用于注解那些影响客户使用带注释的元素声明的类型。如果一种声明使用Documented进行注解,这种类型的注解被作为被标注的程序成员的公共API 。
  • Inherited——指明该注解类型被自动继承。如果用户在当前类中查询这个元注解类型并且当前类的声明中不包含这个元注解类型,那么也将自动查询当前类的父类是否存在Inherited元注解,这个动作将被重复执行知道这个标注类型被找到,或者是查询到顶层的父类。
  • Retention——指明在什么级别显示此注解
  • Target——指明该类型的注解可以注解的程序元素的范围

Target主要的参数类型包括以下几种

  • ElementType.TYPE 用于类,接口,枚举但不能是注解
  • ElementType.FIELD 作用于字段,包含枚举值
  • ElementType.METHOD 作用于方法,不包含构造方法
  • ElementType.PARAMETER 作用于方法的参数
  • ElementType.CONSTRUCTOR 作用于构造方法
  • ElementType.LOCAL_VERIABLE 作用于本地变量或者catch语句
  • ElementType.ANNOTATION_TYPE 作用于注解
  • ElementType.PACKAGE 作用于包

Retention主要的参数类型包括以下几种

  • RetentionPolicy.SOURCE 注解存在于源代码中,编译时会被抛弃
  • RetentionPolicy.CLASS 注解会被编译到class文件中,但是JVM会忽略
  • RetentionPolicy.RUNTIME JVM会读取注解,同时会保存到class文件中

自定义注解:
注解其实就是一种标记,可以在程序代码中的关键节点(类、方法、变量、参数、包)上打上这些标记,然后程序在编译时或运行时可以检测到这些标记从而执行一些特殊操作。

  • 一,定义注解——相当于定义标记; 定义一个@interface类型,加上元注解,定义属性
  • 二,配置注解——把标记打在需要用到的程序代码中;
  • 三,定义AOP,解析注解——在编译期或运行期利用反射获取注解,并进行特殊操作。

注解与反射的结合 :
首先反射注解,那么保留策略必须是Runtime,也就是@Retention(RetentionPolicy.RUNTIME) 。在Java中,通过反射,我们可以知道每一个类的详细信息,比如有什么字段,有什么方法,类名等等,我们通过注解和反射配合,使用反射调用类中的方法,然后读取注解的参数来进行方法的执行。
Java常用注解
JDK自带注解有: @Override @Deprecated @Suppvisewarnings
Spring注解: @Repository @Service @Transactional @Controller @Component @Autowired @RequestMapping @ResponseBody @RequestParam @PathVariable @RequestBody @Method @Configuration @Scope @Lazy @PostConstruct @PreDestory @Qualifier @Resource @ModelAttribute @SessionAttributes @DependsOn @Primary @Async
Mybatis注解: @InsertProvider @DeleteProvider @UpdateProvider @SelectProvider @Options @Insert @Select @Update @Delete @Param @Result @Results
Java 注解 JMS JMX 异常 时间 语法糖 - 图1

→ JMS

什么是 Java 消息服务、JMS 消息传送模型

Java消息服务(Java Message Service)指的是两个应用程序之间进行异步通信的API,它为标准消息协议和消息服务提供了一组通用接口,包括创建、发送、读取消息等,用于支持JAVA应用程序开发。在J2EE中,当两个应用程序使用JMS进行通信时,它们之间并不是直接相连的,而是通过一个共同的消息收发服务连接起来,可以达到解耦的效果。Java消息服务是一个与具体平台无关的API,绝大多数消息中间件提供商都对JMS提供支持。
JMS 消息传送模型 :
点对点消息模型( Point-to-Point(P2P) )

  • 消息通过一个名为消息队列的虚拟通道来交换消息。队列即是消息生产者发送消息的目的地,也是消息消费者获取消息的消息源。
  • 每一条消息只能传送给一个接受者,可能会有多个接收者在一个队列侦听,但是每个消息队列中的消息只能被一个接受者所消费。
  • 消息队列中的消息是由先后顺序的。先进入队列的会优先被消费,除非使用了消息优先级。
  • 消费者和生产者之间没有耦合。消费者和生产者可以在运行时动态的添加,这使得系统的发杂性可以随着时间的增长而降低。
    Java 注解 JMS JMX 异常 时间 语法糖 - 图2
    发布/订阅消息模型( Publish/Subscribe(Pub/Sub) )
  • 信息通过一个成为主题(topic)的虚拟通道交换。
  • 每条消息都会传送给多个称为订阅者的消费者。订阅者有许多类型,包括持久订阅者、非持久订阅者、动态订阅者。
  • 发布者通常不会意识到有多少个订阅者在接收主题消息。
  • 消息被推送给消费者,这意味着消息会传给消费者,而无需消费者去请求。
  • 生产者和消费者之间没有耦合,订阅者和发布者可以动态的添加。
  • 订阅一个主题的每个客户端都会受到发布该主题的副本。发布者生产的一条消息可以被复制并分发给成千上万的订阅者。

Java 注解 JMS JMX 异常 时间 语法糖 - 图3

→ JMX

java.lang.management. 、 javax.management.

所谓JMX,是Java Management Extensions的缩写, 是一个为应用程序植入管理功能的框架 。 和JPA、JMS是一样的,和我们平时使用的Spring、Hibernate也没有什么区别。就是通过将监控和管理涉及到的各个方面的问题和解决办法放到一起,统一设计,以便向外提供服务,以供使用者调用,它的API在以下两个地方:

  • java.lang.management:
  • javax.management.*:包括javax.management.loading、javax.management.modelmbean等;
    Java 注解 JMS JMX 异常 时间 语法糖 - 图4
    JMX结构总共分为三层:

1、基础层:主要是Mbean,被管理的Java bean 。分为 standard MBean、 dynamic MBean 、 model MBean 。
2、代理层:MbeanServer,提供对资源的注册和管理。
3、接入层:提供远程访问的入口, Adapter和Connector 。

→ 泛型

泛型与继承、类型擦除、泛型中 KTVE ? object 等的含义、泛型各种用法

泛型与继承:泛型是参数化类型,把运行时期可能产生的问题,提前到了编译时期,用来保证代码安全性。父类为泛型,子类继承时:范围大于或等于。
类型擦除: Java的泛型基本上都是在编译器这个层次上实现的,在生成的字节码中是不包含泛型中的类型信息的,使用泛型的时候加上类型参数,在编译器编译的时候会去掉,这个过程成为类型擦除。 如在代码中定义List< Object>和List< String>等类型,在编译后都会变成List,JVM看到的只是List,而由泛型附加的类型信息对JVM是看不到的。
常见的类型参数:

  1. T 代表一般的任何类。
  2. E 代表 Element 的意思,或者 Exception 异常的意思。
  3. K 代表 Key 的意思。
  4. V 代表 Value 的意思,通常与 K 一起配合使用。
  5. ?通配符, 代表某种确定的类型,但是又有不确定性。 比如<? extends Collection> 不确定类型,确定实现了Collection接口。能确定上限,或确定下限。
  6. object:超类,需要强制类型转换,编译时可能类型不一致导致报错。

泛型的用法:泛型类、泛型接口、泛型方法
【参考链接】https://blog.csdn.net/briblue/article/details/76736356
限定通配符和非限定通配符、上下界限定符 extends 和 super
通配符有 3 种形式。

  1. <?>被称作无限定的通配符。
  2. <? extends T>被称作有上限的通配符。
  3. <? super T>被称作有下限的通配符。

    List< Object> 、 List<?> 和原始类型 List 之间的区别?

    原始List 没有类型限制,add 或者 get 的时候,接收或返回的对象类型是Object,所以在add时任何类型的对象均可,get时返回值类型为Object。List也没有赋值限定,即任何只要是集合类的对象均可,包括有类型限定的集合。
    List<?>,即通配符类型,其引用变量,同样可以接受任何对应List的参数化类型,包括List,但是一旦赋值了,就只能remove、clear,不能add,保证了安全性和表述性。但不具有表述性,从中取出的元素时Object类型,要通过手动转换才能得到原本的类型。
    List< Object> 有类型限制,类型限制为Object,但由于Object是所有类型的父类,所以在add时任何类型的对象均可,get时返回值类型也为Object。List< Object>也有赋值限定,只有类型是Object的集合对象才能赋值给List< Object>。
    【参考链接】https://blog.csdn.net/qq_28411869/article/details/87880039

    → 单元测试

    junit、mock、mockito、内存数据库(h2)

    【参考链接】: https://blog.csdn.net/ZYC88888/article/details/88839714

    → 正则表达式

    java.lang.util.regex.*

    正则表达式(regular expression)描述了一种字符串匹配的模式(pattern),可以用来检查一个串是否含有某种子串、将匹配的子串替换或者从某个串中取出符合某个条件的子串等。
    Java 注解 JMS JMX 异常 时间 语法糖 - 图5

    → 常用的 Java 工具库

    commons.lang3、commons.*…、 guava-libraries、 netty

    commons-lang3: StringUtils
    common-beanutils: BeanUtils
    commons-io: IOUtils
    Guava-Libraries是google对java的一个扩展,主要涵盖集合、缓存、并发、I/O、反射等等。
    netty参考: https://www.cnblogs.com/imstudy/p/9908791.html

    → API & SPI

    API 和 SPI 的关系和区别

    API( Application Programming Interface ):描述的是可以直接使用的方法,达到某种功能的实现。可以简单的理解为服务方暴露自己的服务供客户方调用。比如Java的api文档,服务方是JDK,客户方就是Java开发人员。
    SPI( Service Provider Interface ):服务方提供的不在提供具体的方法,而是提供对象的接口,客户方需要实现接口, 然后服务方调用客户方的接口实现类,再来实现客户的某种功能。SPI一般是给框架开发人员用的。比如Java定义了连接数据库的接口Driver,我们需要实现接口,但是mysql需要mysql的驱动包,Oracle需要Oracle的驱动包。我们需要提供对应的驱动包,然后服务方调用客户方的驱动,来为开发人员实现mysql的连接功能。
    Java 注解 JMS JMX 异常 时间 语法糖 - 图6

    如何定义 SPI、SPI 的实现原理

    SPI的全名为Service Provider Interface.大多数开发人员可能不熟悉,因为这个是针对厂商或者插件的。我们系统里抽象的各个模块,往往有很多不同的实现方案。 为了实现在模块装配的时候动态指定具体实现类,这就需要一种服务发现机制。 java spi就是提供这种功能的机制:为某个接口寻找服务实现的机制。有点类似IOC的思想,将装配的控制权移到程序之外,在模块化设计中这个机制尤其重要。
    要使用Java SPI,需要遵循如下约定:
  • 1、当服务提供者提供了接口的一种具体实现后,在jar包的META-INF/services目录下创建一个以“接口全限定名”为命名的文件,内容为实现类的全限定名;
  • 2、接口实现类所在的jar包放在主程序的classpath中;
  • 3、主程序通过java.util.ServiceLoder动态装载实现模块,它通过扫描META-INF/services目录下的配置文件找到实现类的全限定名,把类加载到JVM;
  • 4、SPI的实现类必须携带一个不带参数的构造方法;

【参考链接】 https://www.cnblogs.com/oskyhg/p/10800051.html

→ 异常

异常类型、正确处理异常、自定义异常

运行时异常: 算数异常类:ArithmeticExecption 空指针异常类型:NullPointerException
类未找到异常:ClassNotFoundException 参数不合法异常: IllegalArgumentException
类型强制转换类型:ClassCastException 数组下标越界异常:ArrayIndexOutOfBoundsException
数组负下标异常:NegativeArraySizeException 违背安全原则异常:SecturityException
文件未找到异常:FileNotFoundException 数据格式异常:NumberFormatException
字符串转换为数字异常:NumberFormatException 方法未找到异常:NoSuchMethodException
系统异常:SystemException
非运行时异常:输入输出异常:IOException 数据库异常:SQLException 文件已结束异常:EOFException
Java 注解 JMS JMX 异常 时间 语法糖 - 图7
正确处理异常:使用finally块释放资源、优先使用明确的异常、记录异常、将异常与描述信息一起抛出、优先捕获明确的异常、不要捕获Throwable、不要忽略异常、不要在打印日志时将其抛出。
自定义异常: 在Java中要想创建自定义异常,需要继承Throwable或者他的子类Exception。

总结下 throw 和throws 关键字的区别

1、写法上 : throw 在方法体内使用,throws 函数名后或者参数列表后方法体前
2、意义 : throw 强调动作,而throws 表示一种倾向、可能但不一定实际发生
3、throws 后面跟的是异常类,可以一个,可以多个,多个用逗号隔开。throw 后跟的是异常对象,或者异常对象的引用。
4、throws 用户抛出异常,当在当前方法中抛出异常后,当前方法执行结束(throws 后,如果有finally语句的话,会执行到finally语句后再结束。)。可以理解成return一样。

Error 和 Exception

Exception是java程序运行中可预料的异常情况,咱们可以获取到这种异常,并且对这种异常进行业务外的处理。
Error是java程序运行中不可预料的异常情况,这种异常发生以后,会直接导致JVM不可处理或者不可恢复的情况。所以这种异常不可能抓取到,比如OutOfMemoryError、NoClassDefFoundError等。

异常链、try-with-resources

当A方法调用B方法,B方法抛出异常。那么A方法是抛出B方法的异常,还是抛出新异常,如果抛出新异常,旧异常就会丢失,那么如何解决这样的问题,java引进了异常链概念,新旧异常都存在。 把捕获一个异常,然后接着抛出另一个异常,并把原始信息保存下来是一种典型的链式处理,也被成为”异常链”。
try-with-resources语句是一个声明一个或多个资源的 try 语句。 try-with-resources语句确保在语句的最后每个资源都被关闭 。 try (FileInputStream input = new FileInputStream("file.txt")) { 这就是try-with-resource 结构的用法。 当try语句块运行结束时,FileInputStream 会被自动关闭。

finally 和 return 的执行顺序

finally块中的语句,在try或catch中的return语句执行之后、返回之前执行。
而且finally语句中的“干扰”可能或不可能影响try、catch中return已经确定的返回值。
若finally中也有return则覆盖try、catch中的return语句直接返回。

→ 时间处理

时区、冬令时和夏令时、时间戳、Java 中时间 API

参考 https://blog.csdn.net/qq_39823114/article/details/83026934

格林威治时间、CET、UTC、GMT、CST 几种常见时间的含义和关系

UTC( Universal Time Coordinated ): 协调世界时,又称世界标准时间
CET( Central European Time ): 欧洲中部时间是比世界标准时间(UTC)早一个小时的时区名称之一。它被大部分欧洲国家和部分北非国家采用。冬季时间为UTC+1,夏季欧洲夏令时为UTC+2。
GMT( Greenwich Mean Time ):格林威治时间, UTC和GMT都与英国伦敦的本地时相同,所以程序中UTC与GMT没什么不同。意思UTC=GMT是相等的
CST(China Standard Time):北京时间,又名中国标准时间。

SimpleDateFormat 的线程安全性问题

在SimpleDateFormat转换日期是通过Calendar对象来操作的,SimpleDateFormat继承DateFormat类,DateFormat类中维护一个Calendar对象, Calendar实例被用来进行日期-时间计算,既被用于format方法也被用于parse方法!
在parse方法的最后,会调用CalendarBuilder的establish方法,入参就是SimpleDateFormat维护的Calendar实例,在establish方法中会调用calendar的clear方法 ,可知SimpleDateFormat维护的用于format和parse方法计算日期-时间的calendar被清空了,如果此时线程A将calendar清空且没有设置新值,线程B也进入parse方法用到了SimpleDateFormat对象中的calendar对象,此时就会产生线程安全问题!
解决方案: 每一个使用SimpleDateFormat对象进行日期-时间进行format和parse方法的时候就创建一个新的SimpleDateFormat对象,用完就销毁即可!
【原文链接】https://blog.csdn.net/weixin_38810239/article/details/79941964

Java 8 中的时间处理

【参考】https://blog.csdn.net/zmx729618/article/details/80523764

如何在东八区的计算机上获取美国时间

【参考】https://blog.csdn.net/zhaohong_bo/article/details/89194274

→ 编码方式

Unicode、有了 Unicode 为啥还需要 UTF-8

Unicode 只是一个符号集,它只规定了符号的二进制代码,却没有规定这个二进制代码应该如何存储。 UTF-8 是一种变长的编码方式, 对每个字符没有固定的字节数限制,有的一个字节,有的占两个字节,有的占三个字节, UTF-8的好处就是能做到的是最大程度的利用了计算机的空间,加快了网络的传输速率

GBK、GB2312、GB18030 之间的区别

GBK:共收录了21003个汉字,883个符号,共21886个字符。 支持简体中文和繁体中文。
GB2312:基本集,共收入汉字6763个和非汉字图形字符682个。 只支持简体中文。
GB18030 :32位字符集,共收录汉字70244个。 支持简体中文、繁体中文 藏文、蒙文、维吾尔文等主要的少数民族文字。

UTF8、UTF16、UTF32 区别

UTF8:存在单字节编码,兼容ASCII;当编码为一个字节,则设最高比特位为0;当编码超过一个字节,则需要几个字节,就在第一个字节从最高位开始令连续的几个比特位为1,之后的字节最高位为10。
UTF16:使用2或4个字节进行存储。对于Unicode编号范围在0~FFFF之间的字符,统一用两个字节存储,无需字符转换,直接存储Unicode编号。对于Unicode字符编号在10000-10FFFF之间的字符,UTF16用四个字节存储
UTF32:用固定长度的字节存储字符编码,不管Unicode字符编号需要几个字节,全部都用4个字节存储,直接存储Unicode编号。无需经过字符编号向字符编码的转换步骤,提高效率,用空间换时间。

URL 编解码、Big Endian 和 Little Endian

【参考】 https://blog.csdn.net/zhaohong_bo/article/details/89197190

→ 语法糖

Java 中语法糖原理、解语法糖

语法糖(Syntactic Sugar),也称糖衣语法,是由英国计算机学家 Peter.J.Landin 发明的一个术语,指在计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使用。简而言之,语法糖让程序更加简洁,有更高的可读性。
解语法糖
前面提到过,语法糖的存在主要是方便开发人员使用。但其实,Java虚拟机并不支持这些语法糖。这些语法糖在编译阶段就会被还原成简单的基础语法结构,这个过程就是解语法糖。
Java语法糖:
糖块一:switch 支持 String 与枚举、
糖块二:泛型、
糖块三:自动装箱与拆箱、
糖块四:方法变长参数、
糖块五:枚举、
糖块六:内部类、
糖块七:条件编译、
糖块八:断言、
糖块九:数值字面量、
糖块十:for-each、
糖块十一:try-with-resource、
糖块十二:Lambda 表达式
【参考链接】https://blog.csdn.net/u013452337/article/details/90171881

3、阅读源代码

String、Integer、Long、Enum、BigDecimal、
ArrayList & LinkedList、
HashSet & LinkedHashSet & TreeSet
HashMap & LinkedHashMap & TreeMap & CouncurrentHashMap、
ThreadLocal、
ClassLoader & URLClassLoader、