== 与 equals 的区别
== 直接比较栈内存引用的数据,对于基础数据类型栈内存直接引用的就是值,所以可以直接使用。常量字符串由于保存在字符串常量池,所以可以常量字符串直接比较也会返回 true
。
equals 定义在 Object对象里面,Object 源码里面 equals 方法调用的就是 ==。所有包装类都有对 equals 方法的覆盖。
自己定义的类需要覆盖equals 方法,必须要覆盖 hashCode
方法
以下内容摘自<> 覆盖equals时总要覆盖hashCode,一个很常见的错误根源在没有覆盖hashCode方法。在每个覆盖了equals方法的类中,也必须覆盖hashCode方法。如果不这样做的话,就会违反Object.hashCode的通用约定,从而导致该类无法结合所有基于散列的集合一起正常工作,这样的集合包括HashMap、HashSet和Hashtable。
同时equals 需要满足下面几条定义:
说下 String, StringBuffer和StringBuilder
String 为了安全性和效率问题所以设计成了 final
,所以在没有StringBuffer 和 StringBuilder 的情况下。字符串的每次拼接都会生成多个对象还要将字符串推到字符常量池。String更多细节点击
为了解决字符串拼接的效率问题,推出了 StringBuffer
。StringBuffer 是一个线程安全类。可能是因为StringBuffer 底层是字符数组,考虑到数组扩容的情况会导致脏数据。所以采用线程安全的方式。 但是StringBuffer 基本没有用到的场景,在多线程还是单线程的情况下都是用 StringBuilder
,因为在多线程的情况下我们需要自己控制线程流程,而且StringBuffer 也只是保证 append
等操作是线程安全的,多线程情况下也保证不了数据的完整性
1.5 之后java 就推出了 StringBuilder
是一个线程不安全的类 , StringBuilder 和 buffer 的区别就是方法上没有加 synchronized
关键字。StringBuilder 出现之后, String str = "Hello, " + "World";
这种代码编译的时候都会替换成用StringBuilder拼接。
多线程
主要说出四个类:Runnable(1.8 之后是变成函数式接口了),Thread,Callable(1.8 之后是变成函数式接口了),FutureTask
Runnable
:只是一个标识性的接口,里面有个 run
方法 Thread
:构造函数负责接收 Runnable
的, start()
方法通过 JNI
调用不同系统的底层生成一个线程,并让线程处于就绪状态。由 CPU
线程的什么时候运行什么时候切换。 Callable
:和 Runnable 差不多的一个接口,只是带有返回值。 FutureTask
:间接继承 Runnable,两个构造函数,一个可以接收 Runnable和一个固定值,一个接收Callable。执行也是传递给Thread 然后执行start 方法。FutureTask 还有一些API 方法可自行查阅。 线程池
手动写线程会造成浪费,所以实际编程中我们都是使用线程池来操作线程。
用 ExecutorService
来接收 Executors
线程工厂里面的不同线程池策略,线程池里面又包含很多参数可以设置。详情参阅这里
Spring 框架还有对线程池的进一步的封装。
IO
IO 主要分类两大类: 字节流
(对 byte 进行操作)和 字符流
(对 char 进行操作)。两者的根本区别在于 字符流
有个缓冲区对字节进行处理。
常用的有:
buffer:使用了缓存区操作,提高效率 Piped:管道流,多线程的情况下使用的
IO 牵扯的东西太多了,能力有限不多写了,除去传统的 BIO
还有 NIO
和 AIO
。具体的大家多看看别人具体对IO 写的文章吧
Spring 的IOC
Spring 实现IOC 的方式是通过DI(依赖注入),通过配置的方式将bean 保存到Spring 的容器(BeanFactory)。当我们需要某个类的时候都是通过Spring 去获取。
Spring 的AOP
AOP 是通过动态代理来实现的,Spring 有两种动态代理的方式(JDK自带的和CGLIB),动态代理主要应用到了反射机制。主要应用在日志和事务上面。
SpringMVC
Spring MVC 流程分析
掘金里面已经有很多对 redis
写的很好的文章了。
MQ 推荐这一篇: 90%的Java程序员,都扛不住这波消息中间件的面试四连炮!
还有很多内容没有写到,首先因为自己也没有理解透彻,再次已经有了很好的文章了就不在这里东施效颦了