JAVA面经复习(二十八)面试难度:☆☆☆☆

面试难度:☆☆☆☆

推荐指数:☆☆☆☆☆

推荐原因:总体来说本篇面经难度不高,存在较深的知识点但不多,知识整体来说更基础,适宜新手复习使用。

声明:答案均为网上搜索汇总得到的参考答案,如有不妥或意见相左之处欢迎指出!

问:集合体系有哪些?分别有什么实现类? List和Set的区别?

答: set有hashset和TreeSet。List是有序的数组实现,而Set则是无序的元素存放。

问:ArrayList底层有了解吗?大概讲一下流程?

答:ArrayList底层是动态数组,默认长度为10,每次扩容长度变为1.5倍。采用Arrays.copyOf()将旧数据快速的复制到新数组中。

问:ArrayList是线程安全的吗?如何保证线程安全?

答:ArrayList不是线程安全的,可以采用Vector、synchronizedList、CopyOnWriteArrayList等线程安全的数据结构,或者自己手动加锁同步。

问:原子类、CAS有了解吗?说一下CAS是什么?

答:CAS是典型的乐观锁,原子类几乎都采用乐观锁实现。CAS全称是Compare And Swap,其通过取两次临界资源来比较两次的内容是否一致,如果一致则表明当前没有人在操作该对象,否则证明当前对象在被别的线程使用,自动进入自旋状态,即不断获取锁的过程。

问:Socket通信了解吗?说一下TCP和UDP的特点?

答:Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。

TCP是全双工的可靠连接,需要三次握手四次挥手建立连接,期间会采用滑动窗口进行流量的控制,采用慢启动,拥塞避免,快重传,快恢复的方法。

而UDP则是尽全力传输,其不需要进行连接的建立,因此传输的速度很快。

问:如何编写一个服务端程序? 如何实现非阻塞通信?----

答:可以采用ServerSocket、accept进行通信,其采用TCP的方式与对应的客户端建立对应的连接。

非阻塞:线程执行方法时,如果操作没有就绪,就立即返回,不会一直等待操作就绪,即不采用accept()函数进行等待。java.nio提供非阻塞通信的类:1)ServerSocketChannel:代替Server;2)SocketChannel:代替Socket;3)Selector:监控就绪事件;4)SelectionKey:注册事件的句柄

问:反射机制了解吗?大概如何操作,有哪些方法?

答:JVM在类加载的过程中,会将对应类名的.class文件加载到本地方法区中,并生成对应的class类。通过对这个类对象进行反编译可以得到类中的变量和方法。

实现反射的方法主要有三种:1.Object的.getClass方法。2、最常用的Class.forName()方法。3、任何类都有一个静态的class属性,可以根据这个去获取。

问:Spring是什么?怎么进行AOP操作? jdk中动态代理如何实现的?

答:Spring是一个用于WEB应用开发的框架。AOP操作为面向切面编程,其可以在不改动原本类代码的情况下,对类代码进行业务上的增强。其实现的原理是动态代理,进行动态代理一般需要一个代理类和被代理类继承同一个类或接口,以JDK的动态代理为例子,代理类和被代理类需要继承同一个接口,同时通过代理类的Object对象利用反射获取被代理类,实现对应被代理类的方法,此为动态代理。

问:Spring有哪些常用注解?

答:@Component、@Service、@Controller、@Repository、@Autowired等

问:Mybatis大致是如何配置(xml)的?

答:通过字节流读入XML文件,建立对应的configuration类,采用configuration类对具体的类对象进行配置。

问:为什么只需要写Mapper接口和Mapper配置文件就能实现操作数据库?

答:(待补充)

问:看你写了高并发,那么ConcurrentHashMap底层是什么?如何加锁的?

答:ConcurrentHashMap在1.7中跟采用segment和hashEntry的结构,对每个Segment进行上锁。

而在jdk1.8中采用Node数组+链表的方式,对Node数组进行上锁。

加锁采用先尝试采用CAS操作,如果超出了自旋的次数,再转换为重量级别的锁synchronized。

问:为什么要使用线程池? 线程池有哪些配置参数?

答:线程池可以回收一些不再使用的线程,减少在线程创建上的消耗。线程池主要有七大配置参数:

1、corePoolSize,核心线程数

2、maximumPoolSize,最大线程数

3、keepAliveTime ,线程存活时间

4、unit,线程存活时间单位

5、workQueue,工作队列

工作队列又分为:①ArrayBlockingQueue,基于数组的有界阻塞队列。②LinkedBlockingQuene,基于链表的无界阻塞队列;③SynchronousQuene,一个不缓存任务的阻塞队列,生产者放入一个任务必须等到消费者取出这个任务。④PriorityBlockingQueue,具有优先级的无界阻塞队列。

6、threadFactory 线程工厂。

7、handler 拒绝策略。①CallerRunsPolicy,该策略下,在调用者线程中直接执行被拒绝任务的run方法,除非线程池已经shutdown,则直接抛弃任务。②AbortPolicy,直接抛弃任务。③DiscardPolicy。该策略下,直接丢弃任务,什么都不做。④DiscardOldestPolicy,该策略下,抛弃进入队列最早的那个任务,然后尝试把这次拒绝的任务放入队列

问:阻塞队列存放的是什么?说一下工作流程吧?

答:阻塞队列主要是存放客户端发来的业务任务吧。

线程池的工作流程主要有

1、一个任务进来如果当前核心线程数没满则分配给该任务一个核心线程。

2、如果当前核心线程满了则进入阻塞队列。

3、如果阻塞队列满了,则创建一个新的线程。

4、如果超过了最大的线程数,那么这个时候执行相应的拒绝策略。

问:索引原理是什么?索引失效有哪些情况?如何进行sql优化?

答:索引的原理是在底层采用一些多叉的平衡树来减少搜索的次数从而达到。

索引失效的七种情况:

1、模糊匹配like 以%开头,会导致索引失效。

2、索引上元素为空或在索引列上使用 IS NULL 或 IS NOT NULL操作,会导致索引失效。

3、or语句前后没有同时使用索引。

4、组合索引,不是使用第一列索引,索引失效。

5、数据类型出现隐式转化。如varchar不加单引号的话可能会自动转换为int型,使索引无效,产生全表扫描。

6、在索引字段上使用not,<>,!=。不等于操作符是永远不会用到索引的,因此对它的处理只会产生全表扫描。

7、对索引字段进行计算操作、字段上使用函数。

SQL优化:

1、Explain可以查看对应的SQL语句的执行情况,是否使用索引等信息。type:这列最重要,显示了连接使用了哪种类别,有无使用索引,是使用Explain命令分析性能瓶颈的关键项之一。

2、MySQL的慢查询日志是MySQL提供的一种日志记录,它用来记录在MySQL中响应时间超过阀值的语句,具体指运行时间超过long_query_time值的SQL,则会被记录到慢查询日志中。进而可以对相应的查询进行优化。

问:如何对一个记录进行加锁?

答:1. 默认 select 操作不加锁,通过 MVCC 来实现事务的隔离

2. 通过在 select 语句后面加 lock in share mode 为查询结果集添加共享锁

3. 通过在 select 语句后面加 for update 为查询结果集添加排他锁

参考资料:

恒生电子Java一面面经