2

Fan Lu's Blog

 2 years ago
source link: https://fanlumaster.github.io/2022/03/19/%E9%9D%A2%E8%AF%95%E9%A2%98%E6%95%B4%E7%90%86/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Spring 的 AOP 和 IOC?

AOP(Aspect-Oriented Programming), 即 面向切面编程, 它与 OOP( Object-Oriented Programming, 面向对象编程) 相辅相成, 提供了与 OOP 不同的抽象软件结构的视角. 在 OOP 中, 我们以类(class)作为我们的基本单元, 而 AOP 中的基本单元是 Aspect(切面)。

IOC 就是控制反转。Spring 框架的核心是 Spring 容器。容器创建对象,将它们装配在一起,配置它们并管理它们的完整生命周期。Spring 容器使用依赖注入来管理组成应用程序的组件。容器通过读取提供的配置元数据来接收对象进行实例化,配置和组装的指令。该元数据可以通过 XML,Java 注解或 Java 代码提供。

AOP 有哪些实现方式?

实现 AOP 的技术,主要分为两大类:

  • 静态代理 - 指使用 AOP 框架提供的命令进行编译,从而在编译阶段就可生成 AOP 代理类,因此也称为编译时增强;
    • 编译时编织(特殊编译器实现)
    • 类加载时编织(特殊的类加载器实现)。
  • 动态代理 - 在运行时在内存中“临时”生成 AOP 动态代理类,因此也被称为运行时增强。
    • JDK 动态代理:通过反射来接收被代理的类,并且要求被代理的类必须实现一个接口 。JDK 动态代理的核心是 InvocationHandler 接口和 Proxy 类 。
    • CGLIB动态代理: 如果目标类没有实现接口,那么 Spring AOP 会选择使用 CGLIB 来动态代理目标类 。CGLIB ( Code Generation Library ),是一个代码生成的类库,可以在运行时动态的生成某个类的子类,注意, CGLIB 是通过继承的方式做的动态代理,因此如果某个类被标记为 final ,那么它是无法使用 CGLIB 做动态代理的。

Spring AOP 和 AspectJ AOP 有什么区别?

Spring AOP是属于运行时增强,而AspectJ是编译时增强。Spring AOP基于代理 (Proxying),而AspectJ基于字节码操作(Bytecode Manipulation)。

Spring AOP已经集成了AspectJ,AspectJ应该算得上是Java生态系统中最完整的AOP框架 了。AspectJ相比于Spring AOP功能更加强大,但是Spring AOP相对来说更简单。

如果我们的切面比较少,那么两者性能差异不大。但是,当切面太多的话,最好选择 AspectJ,它比SpringAOP快很多。

IOC 如何解决循环依赖?

最后来描述下就上面那个循环依赖 Spring 解决的过程(A为person,B为car,C为money):首先 A 完成初始化第一步并将自己提前曝光出来(通过 ObjectFactory 将自己提前曝光),在初始化的时候,发现自己依赖对象 B,此时就会去尝试 get(B),这个时候发现 B 还没有被创建出来,然后 B 就走创建流程,在 B 初始化的时候,同样发现自己依赖 C,C 也没有被创建出来,这个时候 C 又开始初始化进程,但是在初始化的过程中发现自己依赖 A,于是尝试 get(A),这个时候由于 A 已经添加至缓存中(一般都是添加至三级缓存 singletonFactories ),通过 ObjectFactory 提前曝光,所以可以通过 ObjectFactory.getObject() 拿到 A 对象,C 拿到 A 对象后顺利完成初始化,然后将自己添加到一级缓存中,回到 B ,B 也可以拿到 C 对象,完成初始化,A 可以顺利拿到 B 完成初始化。到这里整个链路就已经完成了初始化过程了。

了解 fastJson 吗?区别是什么?用到了什么?

Fastjson是一个Java语言编写的高性能功能完善的JSON库。它采用一种“假定有序快速匹配”的算法,把JSON Parse的性能提升到极致,是目前Java语言中最快的JSON库。Fastjson接口简单易用,已经被广泛使用在缓存序列化、协议交互、Web输出、Android客户端等多种应用场景。

fastjson 的兼容性比 jackson 要差一些。

前后端分离如何约束参数?

前端通过Ajax请求来访问后端的数据接口,将Model展示到View中即可。

前后端开发者只需要提前约定好接口文档(URL、参数、数据类型.….),然后分别独立开发即可,前端可以造假数据进行测试,完全不需要依赖于后端,最后完成前后端集成即可,真正实现了前后端应用的解耦合,极大地提升了开发效率。

MVVM 是什么?

Model View View-Model.

把Model和View关联起来的就是ViewModel。ViewModel负责把Model的数据同步到View显示出来,还负责把View的修改同步回Model。

如何设计接口?

单一职责。

开放封闭原则。对扩展开放,对修改封闭。

里氏替换原则。子类型可以替换掉父类型。

依赖倒置原则。抽象不应该依赖于细节。细节应该依赖抽象。

https://zhuanlan.zhihu.com/p/193058932

接口的安全性设计?基于序列化?

总的就是说安全性问题,假如没有一个接口(即没有Serializable来标记是否可以序列化),让所有对象都可以序列化。那么所有对象通过序列化存储到硬盘上后,都可以在序列化得到的文件中看到属性对应的值(后面将会通过代码展示)。所以最后为了安全性(即不让一些对象中私有属性的值被外露),不能让所有对象都可以序列化。要让用户自己来选择是否可以序列化,因此需要一个接口来标记该类是否可序列化。

对于集合类的了解?

Java 集合类主要是由两个根接口 Collection 和 Map 派生出来的。

Collection 派生出了三个子接口:List、Set、Queue(Java5新增的队列),因此Java集合大致可以分为 List、Set、Queue四种接口体系。

注意:Collections 是一个工具类。

讲一下 ArrayList?

不保证线程安全。

ArrayList 只能包含对象类型。

ArrayList 的底层使用了数组。

ArrayList 可以动态扩容。

ArrayList 扩容的本质就是计算出新的扩容数组的 size 后进行实例化,并将原有数组内容复制到新数组中去。默认情况下,新的容量会是原容量的 1.5 倍。

ArrayList 和 Vector 的区别?

  • Vector 是线程安全的。
  • ArrayList 是线程不安全的。

讲下 HashMap?

jdk1.8 中,由“数组+链表+红黑树”组成。

hash冲突时,会链表处理。

  • 当链表超过8且数据总量超过64时才会转红黑树。
  • 将链表转换成红黑树前会判断,如果当前数组的长度小于 64,那么会选择先进行数组扩容,而不是转换成红黑树,以减少搜索时间。

为什么不直接用红黑树?

因为红黑树要进行左旋、右旋、变色这些操作来保持平衡,而单链表不需要。

当元素小于 8 个的时候,此时做查询操作,链表结构已经能够保证查询性能。当元素大于8个的时候,红黑树搜索时间复杂度是O(logN),而链表是O(N),此时需要红黑树来加快查询速度。但是新增节点的效率变慢了。

因此,如果一开始就用红黑树结构,元素太少,新增效率又比较慢,无疑这是浪费性能的。

不用红黑树,用二叉查找树可以吗?

可以。但是二叉查找树在特殊情况下会变成一条线性结构。

为什么链表改为红黑树的阈值是8?

因为泊松分布。

lambda 表达式用过吗?举个例子:for 循环和 foreach 的区别?

Lambda 表达式,也可称为闭包,它是推动 Java 8 发布的最重要新特性。

Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中)。

使用 Lambda 表达式可以使代码变的更加简洁紧凑。

for 循环和 foreach 的区别:

  • 1)for循环是基于下标(偏移量)来定位的循环。
  • 2)foreach是基于指针直接移动(地址运算)的循环。
  • 3)foreach与for循环的明显差别在于foreach循环时循环对象(数组、集合)被锁定,不能对循环对象中的内容进行增删改操作

二、两者效率比较 对于通过下标访问的数据结构。例如数组,ArrayList 使用下标访问的for循环效率本身就很高。所以foreach这种指针直接移动的效率可能甚至不如通过下标访问,但差别不会太大,但对于链式结构LinkedList,for基于下标访问会每次从头查询,最好不要使用for。foreach循环使用指针直接偏移的高效的地址运算,效率会高非常多,差距也很大。链表循环超过10万次for循环可能会直接卡死,而foreach仍然只需要几毫秒。

数据库的设计应该遵循什么原则?

一致性原则。

完整性原则。

安全性原则。

可伸缩性与可扩展性。

规范性原则。

volatile

只能保证可见性。

不能保证原子性。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK