恒生电子暑期实习面试

1.自我介绍

大家好,我叫王建,目前就读于东南大学,是计算机学院的一名学生,专业是人工智能。平日里我敢于挑战困难问题,对于不懂的知识追根究底,也可以短期内适应对新知识的学习。同时我也对软件开发有浓厚兴趣,喜欢学习技术,真诚的希望能有展示自己的机会,用技术创造价值。

2.问了下项目里用到的分布式技术
3.京东JSF对比dubbo做了哪些变动,面试官说纯dubbo做不到我说的功能
4.Spring中的IOC和AOP介绍一下

Sring拥有两大特性:IoC和AOP。IoC,英文全称Inversion of Control,意为控制反转(或者叫依赖注入)。AOP,英文全称Aspect-Oriented Programming,意为面向切面编程。

Spring核心容器的主要组件是Bean工厂(BeanFactory),Bean工厂使用控制反转(IoC)模式来降低程序代码之间的耦合度,并提供了面向切面编程(AOP)的实现。

5.IOC要解决什么问题,AOP要解决什么问题

  • IoC解决对象之间的耦合问题,例如当service层调用dao层时,传统方式下我们需要在service中new出dao层的具体实现类,这时当我们实现类需要改变时,service层也需要做相应的改变,这就造成了service层和dao层的强耦合。而使用IOC实例化对像时,我们只需要关注调用的dao层的接口,在service中声明接口属性,具体的实现类在IOC容器中进行切换,因此也不会产生对象中强耦合的情况。
  • AOP是OOP的延续,opp思想是一种垂直纵向的继承体系,解决了代码开发中的大多数代码重复问题。AOP提出了横向抽取机制,将横切逻辑代码和业务逻辑代码分离,在不改变原有业务逻辑情况下,增强横切逻辑代码,根本上解耦合,避免横切逻辑代码重复

6.说说反射,反射的底层原理

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的反射机制。

底层原理是在运行时通过反射API 获取类或对象的元数据,并使用此元数据动态创建类或对象的实例、调用方法、访问字段等

7. AOP动态代理实现的方式

Spring AOP中动态代理的两种实现方式分别是JDK动态代理和CGLIB动态代理JDK动态代理是通过反射机制来实现的CGLIB动态代理则是通过继承目标类来实现的,它不要求目标类实现接口,代理类继承了目标类并在代理类中重写了目标类的方法。

8.并发包,JUC

关于java并发包 JUC就是java.util .concurrent 工具包的简称。 这是一个处理线程的工具包, JDK1.5 开始出现的。 它加了一些在并发编程中常用的工具类,用于定义类似线程的自定义子系统,包括线程池,异步io,轻量级任务框架等。

9.synchronized原理,reentrantlock原理

  • synchronized属于独占式悲观锁,是通过JVM隐式实现的,synchronized只允许同一时刻只有一个线程操作资源。在java中每个对象都隐式包含了一个monitor(监视器) 对象,加锁的过程其实就是竞争monitor的过程,当线程进入字节码monitorenter指令后,线程将持有monitor对象,执行monitorexit时释放monitor对象,当其他线程没有拿到monitor对象时,则需要阻塞等待获取该对象.
  • ReentrantLock是Lock的默认实现方式之一,它是基于AQS(Abstract Queued Synchronizer,队列同步器) 实现的,它默认是通过非公平锁实现的,在它的内部都有一个state的状态字段用于表示锁被占用的,如果是0 则标识锁未被占用,此时线程就可以把state改为1,并成功获取,而其他未获得锁的线程只能去排队等待获取锁资源。

10.如何判断一段代码是线程安全还是不安全

我们可以通过以下三个条件来判断一个程序是否是线程安全的

  • 是否是多线程
  • 是否存在共享资源
  • 是否存在有多个线程同时访问共享资源

如果上述三个条件都存在,那么这个程序就存在线程安全的问题。为了保证线程安全,我们可以采用加锁机制来保护共享资源。

11.聊并发包的类,CountDownlaunch,AtomicStampReference底层实现

CountDownLatch是一个java.util.concurrent包中的类,可以设置一个初始数值,在数值大于0之前让调用await()方法的线程堵塞住,数值为0是则会放开所有阻塞住的线程底层基于AQS实现

AtomicStampReference是一个原子更新带有版本号的引用类型。这个类将整数值与引用关联起来,可用于原子的更新数据和数据的版本号,可以解决CAS中的ABA问题.

12.说一下乐观锁和悲观锁

悲观锁:悲观锁总是假设最坏的情况,认为共享资源每次被访问的时候就会出现问题(比如共享数据被修改),所以每次在获取资源操作的时候都会上锁,这样其他线程想拿到这个资源就会阻塞直到锁被上一个持有者释放。也就是说,共享资源每次只给一个线程使用,其它线程阻塞,用完后再把资源转让给其它线程。像 Java 中synchronizedReentrantLock等独占锁就是悲观锁思想的实现。

乐观锁:乐观锁总是假设最好的情况,认为共享资源每次被访问的时候不会出现问题,线程可以不停地执行,无需加锁也无需等待,只是在提交修改的时候去验证对应的资源(也就是数据)是否被其它线程修改了(具体方法可以使用版本号机制或 CAS 算法

13.ZooKeeper有什么特点,选举机制说一下,什么时候会出现选举问题,他是AP的还是CP的,为什么

(1)ZooKeeper的特点有以下几点

  • 高可用性:ZooKeeper集群中只要有一台机器存活,就能对外提供服务。
  • 严格顺序访问:所有的更新请求都会按照其发送顺序被逐个执行。
  • 数据一致性:ZooKeeper保证数据的最终一致性,即在一定时间内,所有客户端能够读取到同样的数据。
  • 可靠性:ZooKeeper保证在分布式环境下数据的可靠性。

(2)ZooKeeper的选举机制是基于Paxos算法当集群中的Leader节点挂掉时,ZooKeeper会自动进行Leader选举。选举过程分为两个阶段:选举和投票。选举阶段是为了选出一个唯一的Leader,投票阶段是为了让其他节点知道谁是Leader。在选举过程中,每个节点都可以成为候选人,然后通过投票来决定哪个候选人成为Leader。

当出现网络分区或者节点故障时,就会出现选举问题。如果出现网络分区,那么可能会出现多个Leader,这时需要手动干预解决。如果出现节点故障,那么ZooKeeper会自动进行Leader选举。

ZooKeeper是CP系统。它保证了数据的一致性和分区容错性,但不保证可用性。因此,在网络分区或者节点故障时,可能会导致部分客户端无法访问。

14.ZooKeeper做分布式锁说一下

ZooKeeper分布式锁的实现方式是:首先需要创建一个父节点,尽量是持久节点(PERSISTENT类型),然后每个要获得锁的线程,都在这个节点下创建个临时顺序节点。当一个线程需要获得锁时,它会在父节点下创建一个临时顺序节点,然后获取父节点下所有子节点的列表,判断自己创建的节点是否是最小的那个。如果是,则表示该线程获得了锁;否则,该线程就需要监听比自己小的那个节点的删除事件,当该节点被删除时,该线程再次判断自己创建的节点是否是最小的那个。如果是,则表示该线程获得了锁。

15.redis底层用了什么数据结构(我答了zset用的跳跃表,面试官不满意)

Redis的5种常见数据结构:字符串(String)、列表(List)、散列(Hash)、集合(Set)、有序集合(Sorted Set),这些都是Redis对外暴露的数据结构。

Redis底层数据结构有六种:简单动态字符串(SDS)、列表、字典、整数集合、跳跃表、压缩列表、快速列表。

16.redis设计的核心思想是什么,集群通信用了什么(这个我之前面试也被问到过,答了gossip协议)

  • Redis的设计思想是:最大限度的“以时间换空间”,从而最大限度地节省内存。Redis的核心流程包括Redis事件机制与命令执行过程
  • Redis集群采用P2P的Gossip(流言)协议,跟集中式不同,不是将集群元数据(节点信息、hashslot->node之间的映射表关系,还有master->slave之间关系,故障的信息等)集中存储在某个节点上,Gossip协议工作原理就是节点彼此不断通信交换信息,一段时间后集群的所有的节点都会有完整的(集群)信息,这种方式类似流言传播。

17、面对对象和面向过程的区别?

  • 面向过程把解决问题的过程拆成一个个方法,通过一个个方法的执行解决问题。
  • 面向对象会先抽象出对象,然后用对象执行方法的方式解决问题。

18、ArrayList 和 LinkedList 的区别?

  • 是否保证线程安全: ArrayListLinkedList 都是不同步的,也就是不保证线程安全
  • 底层数据结构: ArrayList 底层使用的是 Object 数组LinkedList 底层使用的是 双向链表 数据结构(JDK1.6 之前为循环链表,JDK1.7 取消了循环。注意双向链表和双向循环链表的区别,下面有介绍到!)
  • 插入和删除是否受元素位置的影响:
    • ArrayList 采用数组存储,所以插入和删除元素的时间复杂度受元素位置的影响。 比如:执行add(E e)方法的时候, ArrayList 会默认在将指定的元素追加到此列表的末尾,这种情况时间复杂度就是 O(1)。但是如果要在指定位置 i 插入和删除元素的话(add(int index, E element))时间复杂度就为 O(n-i)。因为在进行上述操作的时候集合中第 i 和第 i 个元素之后的(n-i)个元素都要执行向后位/向前移一位的操作。
    • LinkedList 采用链表存储,所以,如果是在头尾插入或者删除元素不受元素位置的影响add(E e)addFirst(E e)addLast(E e)removeFirst()removeLast()),时间复杂度为 O(1),如果是要在指定位置 i 插入和删除元素的话(add(int index, E element)remove(Object o)), 时间复杂度为 O(n) ,因为需要先移动到指定位置再插入。
  • 是否支持快速随机访问: LinkedList 不支持高效的随机元素访问,而 ArrayList(实现了 RandomAccess 接口) 支持。快速随机访问就是通过元素的序号快速获取元素对象(对应于get(int index)方法)。
  • 内存空间占用: ArrayList 的空 间浪费主要体现在在 list 列表的结尾会预留一定的容量空间,而 LinkedList 的空间花费则体现在它的每一个元素都需要消耗比 ArrayList 更多的空间(因为要存放直接后继和直接前驱以及数据)。

19、Spring 的 bean 生命周期?

Bean 的生命周期指的是 Bean 在 Spring(IoC)中从创建到销毁的整个过程。Bean 的生命周期主要包含以下 5 个流程:

(1)实例化:为 Bean 分配内存空间;

(2)设置属性:将当前类依赖的 Bean 属性,进行注入和装配;

(3)初始化:

  • 执行各种通知。
  • 执行初始化的前置方法。
  • 执行初始化方法。
  • 执行初始化的后置方法。

(4)使用 Bean:在程序中使用 Bean 对象;

(5)销毁 Bean:将 Bean 对象进行销毁操作。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

金州饿霸

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值