蚂蚁金服面试

一面

hashmap的实现原理,多线程并发操作hashmap会有什么问题?
原理简述:使用数组加链表的数据结构,根据给出的key -hash到数组的一个下标,如果当前下标有值建立一个链表 指向next, 注意的是新插入的值会在头链表上, 这样的设计思路是 新数据默认更热
发产生的问题:多线程put后可能导致get死循环

多线程put的时候可能导致元素丢失
主要问题出在addEntry方法的new Entry (hash, key, value, e),如果两个线程都同时取得了e,则他们下一个元素都是e,然后赋值给table元素的时候有一个成功有一个丢失。
put非null元素后get出来的却是null

泛型的反射擦除

  • 泛型只在编译期有效,在运行期会被擦除掉, 所以通过反射的反射往一个要求泛型的集合添加对象,逃过了编译器的检查,
    是可以正常在运行期使用的

乐观锁了解哪些

1、CAS(Compare And Swap) JAVA中实现了
AtomicBoolean、AtomicLong、AtomicReference, 缺点是
-在并发冲突概率大的高竞争环境下,如果CAS一直失败,会一直重试,CPU开销较大。针对这个问题的一个思路是引入退出机制,如重试次数超过一定阈值后失败退出。当然,更重要的是避免在高竞争环境下使用乐观锁。
2、版本号机制 如数据库加加入时间戳

严格来讲CAS不是一种锁 是一种概念上的锁

B+树和红黑树时间复杂度

二叉树的遍历
前序遍历:根左右
中序遍历:左根右
后续遍历:左右根
算法-java

 public  void  theFirstTraversal(Node  node){
       printNode(node);
       if(node.getLeftNode()!=null){
           theFirstTraversal(node.getLeftNode());
       }
       if(node.getRightNode()!=null){
           theFirstTraversal(node.getRightNode());
       }
    }
    
    public  void  thePostOrderTraversal(Node  node){
        if(node.getLeftNode()!=null){
            thePostOrderTraversal(node.getLeftNode());
        }
        if(node.getRightNode()!=null){
            thePostOrderTraversal(node.getRightNode());
        }
        printNode(node);
    }
    public  void  theInOrderTraversal(Node  node){
        if(node.getLeftNode()!=null){
            theInOrderTraversal(node.getLeftNode());
        }
        printNode(node);

        if(node.getRightNode()!=null){
            theInOrderTraversal(node.getRightNode());
        }
    }

快排的时间复杂度,冒泡时间复杂度,快排是否稳定,快排的过程

讲一下spring的启动流程
spring启动有几种方法,通过web.xml的监听器,或者ClassPathXmlApplicationContext,
FileSystemXmlApplicationContext,它启动的核心目标是构建spring容器,构建容器需要做以下几个工作 ,实例化对象,
加载配置,装配bean对象,
首先根据路径加载配置文件,也叫元数据 和pojo对象, 根据对应的模板表情进行初始化操作,通过元数据和反射的方式生成对象放入容器中,load的配置也进行初始化,后面会有bean的装配工作和回调工作,
比如实现了InitializingBean 会在容器所有需要设置属性的bean设置完以后调用afterPropertiesSet
this.postProcessBeanFactory(beanFactory);
this.invokeBeanFactoryPostProcessors(beanFactory);
this.registerBeanPostProcessors(beanFactory);
this.initMessageSource();
this.initApplicationEventMulticaster();
this.onRefresh();
this.registerListeners();
this.finishBeanFactoryInitialization(beanFactory);
this.finishRefresh();

AOP是怎么实现的?两种动态代理的应用场景?

通过动态生成字节码,增强代码业务功能,
JDK动态代理, 需要代理的类必须要实现接口
cglib 无需实现接口 速度快
javaassist 也无需实现接口

Java中的新生代和老年代的垃圾回收算法,对应的垃圾收集器
https://www.cnblogs.com/wrencai/p/5668621.html VC

谈谈 synchronized、ReenTrantLock、volatile 三者的区别
synchronized 互斥锁,
即操作互斥,并发线程过来,串行获得锁,串行执行代码。就像一个房间一把钥匙,一个人进去后,下一个人得等第一个人出来得到钥匙才能进入。如果代码写的不好(A),可能出现死锁!(A得到锁,B等待A释放锁,A不释放,B死锁).

ReenTrantLock 重入锁
在JDK优化之后 synchronized 和reentrantLCOK 锁的性能其实差不多
唯一的区别是

  1.  ReenTrantLock可以指定是公平锁还是非公平锁。而synchronized只能是非公平锁。所谓的公平锁就是先等待的线程先获得锁。
    
  2.  ReenTrantLock提供了一个Condition(条件)类,用来实现分组唤醒需要唤醒的线程们,而不是像synchronized要么随机唤醒一个线程要么唤醒全部线程。
    
  3.  ReenTrantLock提供了一种能够中断等待锁的线程的机制,通过lock.lockInterruptibly()来实现这个机制。
    

如果需要使用reentrantlock的这三种独立功能可以使用这个锁 并且ReenTrantLock的力度更细

volatile 是一个关键字 对虚拟机声明标识有该关键字的遍历 不允许重排序和修改马上刷新内存~

示例代码:

二面

[Linux]命令 统计,排序,前几问题等
wc、sort、uniq这三个命令都是用于排序。
wc命令很简单,在linux中用来统计文件中的字节数、字数、行数,并且将结果返回
格式:wc [-clmwL] file
-c:统计字节数
-l:统计行数
-m:统计字符数
-w:统计字数,一个字被定义为由空白、跳格或换行字符分隔的字符串
-L:打印最长行的长度
https://blog.csdn.net/feng973/article/details/73849586

full gc的发生有哪几种情况?

触发MinorGC(Young GC)

虚拟机在进行minorGC之前会判断老年代最大的可用连续空间是否大于新生代的所有对象总空间
1、如果大于的话,直接执行minorGC
2、如果小于,判断是否开启HandlerPromotionFailure,没有开启直接FullGC
3、如果开启了HanlerPromotionFailure, JVM会判断老年代的最大连续内存空间是否大于历次晋升的大小,如果小于直接执行FullGC
4、如果大于的话,执行minorGC

触发FullGC

  • 老年代空间不足 如果创建一个大对象,Eden区域当中放不下这个大对象,会直接保存在老年代当中,如果老年代空间也不足,就会触发Full GC。为了避免这种情况,最好就是不要创建太大的对象。
  • 持久代空间不足
    如果有持久代空间的话,系统当中需要加载的类,调用的方法很多,同时持久代当中没有足够的空间,就出触发一次Full GC
  • YGC出现promotion failure
    promotion failure发生在Young GC, 如果Survivor区当中存活对象的年龄达到了设定值,会就将Survivor区当中的对象拷贝到老年代,如果老年代的空间不足,就会发生promotion failure, 接下去就会发生Full GC.
  • 统计YGC发生时晋升到老年代的平均总大小大于老年代的空闲空间
    在发生YGC是会判断,是否安全,这里的安全指的是,当前老年代空间可以容纳YGC晋升的对象的平均大小,如果不安全,就不会执行YGC,转而执行Full GC。
  • 显示调用System.gc

Netty内部结构

mysql有几种引擎,区别?

1.常用的3种
2.InnoDB Myisam Memory
3.InnoDB跟Myisam的默认索引是B+tree,Memory的默认索引是hash

区别:
1.InnoDB支持事务,支持外键,支持行锁,写入数据时操作快,MySQL5.6版本以上才支持全文索引
2.Myisam不支持事务。不支持外键,支持表锁,支持全文索引,读取数据快
3.Memory所有的数据都保留在内存中,不需要进行磁盘的IO所以读取的速度很快, 、
但是一旦关机的话表的结构会保留但是数据就会丢失,表支持Hash索引,因此查找速度很快
innodb中聚集索引,非聚集索引

MySQL、Redis、MongoDB各自的应用场景

分布式下redis如何保证线程安全

Redis的存储数据结构,以及持久化区别

https://www.cnblogs.com/neooelric/p/9621736.html
Redis 提供了多种不同级别的持久化方式:
RDB 持久化可以在指定的时间间隔内生成数据集的时间点快照(point-in-time snapshot)。
AOF 持久化记录服务器执行的所有写操作命令,并在服务器启动时,通过重新执行这些命令来还原数据集。AOF 文件中的命令全部以 Redis 协议的格式来保存,新命令会被追加到文件的末尾。Redis 还可以在后台对 AOF 文件进行重写(rewrite),使得 AOF 文件的体积不会超出保存数据集状态所需的实际大小。
Redis 还可以同时使用 AOF 持久化和 RDB 持久化。在这种情况下,当 Redis 重启时,它会优先使用 AOF 文件来还原数据集,因为 AOF 文件保存的数据集通常比 RDB 文件所保存的数据集更完整。
你甚至可以关闭持久化功能,让数据只在服务器运行时存在。
了解 RDB 持久化和 AOF 持久化之间的异同是非常重要的,以下几个小节将详细地介绍这这两种持久化功能,并对它们的相同和

三面

什么情况索引不会命中,会造成全表扫描

1.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如:

  1. 应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。
    3.应尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描,如:
    4.in 和 not in 也要慎用,否则会导致全表扫描
    5.'%abc%' like全匹配查询也会导致
    6.应尽量避免在where子句中对字段进行函数操作,这将导致引擎放弃使用索引而进行全表扫描

JVM性能调优会涉及哪些参数?

Restful、SOAP、RPC、SOA、微服务之间的区别

SpringClound与Dubbo的比较,优劣势

kafka和rockMQ区别
https://www.cnblogs.com/ynyhl/p/11320797.html 详情
rockMq4个组成部门
name servers- 一个轻量级路由和发现服务,类似于zookpeer,提供了通信读写服务 支持快速纯粹和扩张
brokers-是用来存储消息数据,通过topic和queue机制,同时支持拉和推模式,支持故障容忍机制(数据复制多份)支持万亿级别的数据聚合和有序队列,同时支持灾难恢复,强大的数据统计和警功能这都是传统的消息队列缺少的
producers- 支持分布式部署,producers通过负载均衡机制发送消息给broken,低延迟
consumers- 支持分布式部署(推和拉两种拉取数据模式),同时支持集群消费和消息广播功能 -(广播就是向一个主题的所有订阅者发送同一条消息。在发送消息的时候和普通的消息并与不同之处,只是在消费端做一些配置即可)

mysql如何实现如何实现分库分表+动态数据源+读写分离

什么是缓存雪崩?服务器雪崩的场景与解决方案

分布式锁的方案,redis和zookeeper哪个好,如果是集群部署,高并发情况下哪个性能更好。

请画一个大型网站分布式集群部署图

秒杀系统的架构设计

你可能感兴趣的:(蚂蚁金服面试)