java-高级面试题2023

1、ArrayList 和 Vector 的区别。

        Vector 是线程安全的,而 ArrayList 是线程序不安全的,如果只有一个线程会访问到集合,那最好是使用 ArrayList,因为它不考虑线程安全,效率会高些;如果有多个线程会访问到集合,那最好是使用 Vector,因为不需要我们自己再去考虑和编写线程安全的代码;

2、Hashmap 实际上是一个数组和链表的结合体(在数据结构中,一般称之为 “链表散列 “)

3、Set 里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用 == 还是equals()? 它们有何区别?

        Set 里的元素是不能重复的,元素重复与否是使用 equals() 方法进行判断的

4、两个对象值相同 (x.equals(y) == true),但却可有不同的 hash code,这句话对不对?

        不对。如果对象要保存在 HashSet 或 HashMap 中,它们的 equals 相等,那么,它们的 hashcode 值就必须相等。

5、HashSet 的底层实现是什么?

        HashSet 的实现是依赖于 HashMap 的,HashSet 的值都是存储在 HashMap 中的。在 HashSet 的构造法中会初始化一个 HashMap 对象,HashSet 不允许值重复,因此,HashSet 的值是作为 HashMap 的 key 存储在HashMap 中的,当存储的值已经存在时返回 false。

6、数组 (Array)和列表(ArrayList)有什么区别?什么时候应该使用 Array 而不是ArrayList?

        Array 可以包含基本类型和对象类型,ArrayList 只能包含对象类型。

        Array 大小是固定的,ArrayList 的大小是动态变化的。

        ArrayList 处理固定大小的基本数据类型的时候,这种方式相对比较慢。

7、简述 synchronized 和 java.util.concurrent.locks.Lock 的异同?

        主要相同点:Lock 能完成 synchronized 所实现的所有功能。

        主要不同点:Lock 有比 synchronized 更精确的线程语义和更好的性能。

        synchronized 会自动释放锁,而 Lock 一定要求程序员手工释放,并且必须在 finally从句中释放。Lock 还有更强大的功能,例如,它的 tryLock 方法可以非阻塞方式去拿锁

8. run() 和 start() 区别。

        run( ):只是调用普通 run 方法

        start( ):启动了线程, 由 Jvm 调用 run 方法

        启动一个线程是调用 start() 方法,使线程所代表的虚拟处理机处于可运行状态,这意味着它可以由 JVM 调度并执行。这并不意味着线程就会立即运行。

9、spring的bean加载流程,循环依赖

        一: 实例化一个applicationContext的对象创建一个beanFactory工厂对象

        二: beanFactory的后置处理器对当前的所有类进行扫描

        三: 使用for循环将所有的类通过一个beanDefintion对象进行解析和初始化默认参数, 并 且将实例化后的对象缓存到beanDefintionMap中

        四: 再次调用beanFactory的后置处理器对beanDefintion对象进行一些额外的扩展, 比方 说用户自定义实现的一些参数属性方法

        五: Spring首先从singletonObjects (一 级缓存)中尝试获取,如果获取到了直接return

        六: 如果获取不到并且对象在创建中,则尝试从earlySingletonObjects(二级缓存)中获 取,如果获取到了直接return

        七: 如果还是获取不到并且允许从singletonFactories通过getObject获取,则通过 singletonFactory.getObject()(三级缓存)获取,如果获取到了就从singletonFactories中移 除,并且放进earlySingletonObjects (二级缓存)中

        八: 如果三个缓存中都拿不到对象, spring会经过一 系列的验证并且 确定类的构造方法 后,调用类的构造方法通过反射实例化一个对象, 也就是createBean

        九: 中间会经过非常多的判断,其中最关键的两个点是 是否需要注入属性,是否需 要生成代理对象

        十: spring将创建好的bean存入到一级缓存singletonObject中, 此时一个bean的初始化 完成,随时可以被引用,根据用户业务做一些相关的操作

        十一: 最后是销毁,在上下文初始化失败时,所有已经创建好的bean会销毁,或者当用 户关闭容器时,bean也会被销毁。除此之外,用户也可以自行调用destroy-类的方法手 动销毁一个bean

10、解释不同方式的自动装配 。

        有五种自动装配的方式,可以用来指导 Spring 容器用自动装配方式来进行依赖注入。

        · no:默认的方式是不进行自动装配,通过显式设置 ref属性来进行装配。

        · byName:通过参数名 自动装配,Spring 容器在配置文件中发现 bean 的 autowire 属性被设置成 byname,之后容器试图匹配、装配和该 bean 的属性具有相同名字的 bean。

        · byType::通过参数类型自动装配,Spring 容器在配置文件中发现 bean 的 autowire 属性被设置成 byType,之后容器试图匹配、装配和该 bean 的属性具有相同类型的 bean。如果有多个 bean 符合条件,则抛出错误。

        · constructor:这个方式类似于 byType, 但是要提供给构造器参数,如果没有确定的带参数的构造器参数类型,将会抛出异常。

        · autodetect:首先尝试使用 constructor 来自动装配,如果无法工作,则使用 byType 方式

Spring Cloud之Ribbon与Nginx区别

Ribbon与Nginx区别

1.服务器端负载均衡Nginx

 nginx是客户端所有请求统一交给nginx,由nginx进行实现负载均衡请求转发,属于服务器端负载均衡。

 既请求由nginx服务器端进行转发。

2.客户端负载均衡Ribbon

 Ribbon是从eureka注册中心服务器端上获取服务注册信息列表,缓存到本地,然后在本地实现轮训负载均衡策略。

 既在客户端实现负载均衡。

 应用场景的区别:

Nginx适合于服务器端实现负载均衡 比如Tomcat ,Ribbon适合与在微服务中RPC远程调用实现本地服务负载均衡,比如Dubbo、SpringCloud中都是采用本地负载均衡。

jdk 动态代理:

代理定义:

代理模式是指,为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户类和目标对象之间起到中介的作用。
 

动态代理基于反射,

比如a要访问c,但是c拒绝a访问,
在a和c直接建立一个代理对象b,c是让b访问 的

a  访问 b   然后b再访问c,(b作为代理对象,类似于中介)

代理分为动态代理和静态代理

1、静态代理

定义一个接口

定义一个目标类,实现上面的接口

定义一个代理类

定义一个访问类

2、动态代理

动态代理:使用反射机制。在程序执行中。创建代理类对象。特点,不用创建类文件,代理的目标类是动态的,可设置的
动态代理的实现方式常用的有两种:使用JDK代理代理,通过CGLIB动态代理。

创建一个接口

接口的实现类

通过反射调用

核心地方

创建第二个实现类

调用第二个实现类方法

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值