【奇安信】-Java岗-服务端开发一二面面经

一面

一开始网不太好

1、学习java的方式
面试官说他那里加载不出来我简历,先随便问了一下。

2、说一下HashMap
允许put空值,如果key为null,那么hash值为0.

底层数据结构:数组 + 链表 + 红黑树

loadFactor:负载因子默认为0.75,是均衡了时间和空间损耗计算出来的,较高的值会减少空间的开销,扩容减小,数组大小增加速度变慢,但是增加了查找的成本,hash冲突增加,链表变长

如果有很多需要储存到HashMap中的数据,要在一开始把它的容量设置为足够大,防止出现不断扩容

线程不安全

重要的字段

DEFAULT_INITIAL_CAPICITY = 1 << 4; 默认大小为16 MAXIMUM_CAPACITY = 1 << 30; 最大容量 DEFAULT_LOAD_FACTOR = 0.75f; 默认负载因子 TREEIFY_THRESHOLD = 8; UNTREEIFY_THRESHOLD = 6; 树化和退化为链表的阈值 MIN_TREEIFY_CAPACITY = 64; 链表转化为红黑树时需要的数组大小 threshold 表示扩容的阈值,大小为 数组大小*负载因子
3、ConcurrentHashMap怎么保证线程安全?
底层基于CAS + synchronized实现,所有操作都是线程安全的,允许多个线程同时进行put、remove等操作

在JDK1.7采用的是Segment分段锁,默认并发度为16

改变的原因:竞争同一个锁的概率低,浪费内存空间,容易造成长时间等待,1.8对synchronized做了很多的优化。

table数组被volatile修饰

如果再问的细一点,就是put方法了,没值CAS添加,有值synchronized加锁。

4、Synchronized做过哪些优化?
参考《深入理解JAVA虚拟机》从无锁状态到偏向锁再到轻量级锁,再到重量级锁的一个升级,自适应自旋等等这些。

5、类加载的过程?
加载—链接(验证、准备、解析)—-初始化

加载:生成一个代表类的Class对象,作为方法区中该类各种数据的访问入口。

验证:确保包含的信息符号当前虚拟机的要求,不会危害虚拟机自身的安全。

准备:为类变量分配内存,设置初始值

解析:将常量池的符号引用替换为直接引用的过程。

初始化:执行Java程序代码。

6、MySQL索引数据结构详细说一下
B+树

从二叉查找树到二叉平衡树再到B树再到B+树,分别说每个是否适合做索引,以及不同数据结构的区别

7、具体说一下查询的过程(聚集索引、非聚集索引、联合索引)
这里说了一下聚集索引查找和非聚集索引查找的过程

聚集索引:索引即数据

非聚集索引要回表查询。

联合索引:最左匹配原则:最左优先,以最左边为起点任何连续的索引都能匹配上。同时遇到范围查询就会停止匹配。

= in 可以乱序

(a,b,c) 可以用到索引的情况(a,b (a,c) (b,a) (c,a) 三个一起的都可以用到,不管顺序如何

8、MySQL的架构,分几层?

9、Innodb事务?
ACID老八股了

10、介绍下MCVV
多版本并发控制,新增两个字段,最后一次修改的事务ID,指向回滚的undolog指针

这里我有个疑问,到底RR解决幻读了吗?网上文章很多,说什么的都有。

11、计算机网络7层架构
物理层、数据链路层、网络层、传输层、会话层、表示层、应用层。

12、 HTTPS协议?详细介绍
简洁的说,就是有公钥和密钥,加密用公钥解密用密钥,这是非对称加密。

HTTPS为了兼顾安全与效率,同时使用了对称加密和非对称加密。数据是被对称加密传输的,对称加密过程需要客户端的一个密钥,为了确保能把该密钥安全传输到服务器端,采用非对称加密对该密钥进行加密传输,总的来说,对数据进行对称加密,对称加密所要使用的密钥通过非对称加密传输。

答完这个,面试官说没问题,很棒😂,感觉问的都还挺简单的,都是八股。而且全部按照简历上写的来问。

13、SpringBoot的自动装配原理?
@EnableAutoConfiguration 注解,深入进去说一下springboot怎么扫描怎么装配就行了。

14、Redis持久化机制
rdb

aof

15、Redis主从复制
一般面试都没问过这个,因为这次全是按照简历里面写的问,我简历里面写了,但还是第一次被问到,好久没复习了。

主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器,前者称为主节点(master/leader),后者称为从节点(slave/follower)Master以写为主,Slave以读为主。

16、哨兵机制
哨兵是一个独立的进程,作为进程,它会独立运行,其原理是哨兵通过发送命令,等待Redis服务器响应,从而监控运行多个Redis实例。

17、对分布式的理解?
将大的项目拆分成不同的模块,部署到不同的机器上,就是把单体架构拆分成不同的微服务,

分布式系统的优点:

提升服务可用性 / 稳定性

提升系统并发能力

提升系统容错能力

低延迟

分布式系统缺点:

依赖网络,会因为网络问题导致系统数据丢失或不一致性;

系统复杂化,系统监控维护,版本迭代发布变得相对复杂,成本高;

一致性,可用性,分区容错性无法同时满足。

二面

1、自我介绍
2、项目讨论
一般面试环节,提到项目上的问题,我很乐意和面试官去讨论项目上的一些实现,如果面试官也去深入分析项目上的细节,去分析项目可以优化的点,我感觉面试体验是很好的,因为这样不仅能让自己对项目更加熟悉,也可以知道自己有哪些不足,这是很重要的。但是如果提到项目,面试官脱离项目,直接问一些使用的技术上的问题,那我感觉就会比较不太好回答。

3、Java封装、继承、多态、谈谈你对封装的理解?
将一个对象的属性私有化,行为公开化,同时提供对外的接口来访问对象,数据被保护在抽象数据类型的内部,尽可能的隐藏内部的细节,只保留一些对外的接口使其与外部发生联系。用户无需关心对象内部的细节。优点是减少了耦合。

4、Java集合
ArrayList和LinkedList

分别从底层数据结构和使用场景上分析

ArrayList底层是数组,适合快速的匹配,不适合频繁的增删

LinkedList底层是链表,适合增删,不适合频繁的匹配,一般用它可以实现栈或者队列

5、创建线程的几种方式
1、继承Thread类,

2、实现Runnable接口;

3、实现Callable接口;可以有返回值,返回值通过FutureTask进行封装。

4、线程池实现

6、线程池参数+(拒绝策略)
1、corePoolSize:线程池核心线程大小。

2、maximumPoolSize:线程池最大线程数量。

3、keepAliveTime:空闲线程存活时间。

4、unit:空闲线程存活时间单位。

5、workQueue:工作队列

6、threadFactory 线程工厂 (指定优先级,指定线程名称,方便监控,指定是否是守护线程)

7、handler 拒绝策略

 1、CallerRunsPolicy:哪来的去哪里

    2、AbortPolicy:直接丢弃任务,并抛出RejectedExecutionException异常。

    3、DiscardPolicy:直接丢弃任务,什么都不做。

    4、DiscardOlddestPolicy:抛弃进入队列最早的那个任务,然后尝试把这次拒绝的任务放入队列。(LRU)

7、核心线程数和最大线程数平时使用的时候怎么设置?
这里我答了一下线程池的执行流程,然后分析了CPU密集型和IO密集型的线程数设置。

CPU密集 :N+1

IO密集:2N+1

最佳线程数目 = ((线程等待时间+线程CPU时间)/线程CPU时间 )* CPU数目

这里面试官说了,一些资料或者博客上面都是这样整理的,实际上在真实的开发中,CPU密集型也有,IO密集型也有,往往是混合使用的,真正怎么设置,还要实际去操作过才可以。

(这种讨论式的面试,体验很好,八股都会背,但是面试官可能会跟你延申一下其他的,面试过程中,自己也能学到不少思想和知识。)

8、异步编排,好几个线程协同的完成任务
这个问题出现概率很高,其实就是变相的问,线程之间同步。可以参考生产者消费者来延申回答。

9、Synchronized和Lock区别
直接每个锁深入底层和面试官讨论,这样能加很多分。

1、Synchronized 是内置的Java关键字,Lock是一个Java类。

2、Synchronized 无法判断获取锁的状态,Lock可以判断是否获取到了锁。

3、Synchronized 会自动释放锁,Lock必须要手动释放锁,如果不释放锁会造成死锁。

4、Synchronized 线程1(获得锁,阻塞)线程2(等待,傻傻的等)Lock锁不会一直等待下去。

5、Synchronized 可重入锁,不可中断,非公平,Lock可重入锁,可以中断锁,可以自己设置非公平。

6、Synchronized 适合锁少量代码同步问题,Lock 适合锁大量的同步代码!

10、公平锁和非公平锁的效率那种效率更高?
在我印象中,肯定是非公平锁的效率更高啊,因为它是采用了cas去争夺锁的,公平的话,是直接放在队列尾部的。

然后面试官说,其实实际的话,如果非公平竞争也是有开销的,公平的话,就去队列中取出其中的一个。具体情况还要具体分析。

11、刚刚你有谈到对象有个MarkWord,java对象在内存中的组成部分?
从new开始讲起来

1、类加载

2、分配内存

3、初始化

4、设置对象头

5、执行init方法

12、Java反射Class对象,存在那个区域?
堆中,堆中都是放对象的。

13、方法区放什么东西?
存储已被虚拟机加载的类型的信息,常量,静态变量,即时编译器编译后的代码缓存。会发生OutOfMemoryError.

14、Java是编译型语言还是解释型语言?
其实Java是混合型的

Java代码在执行时,先通过Javac编译为字节码,在运行时,通过JVM内的解释器转换为目标机器的可执行机器码。

但是常见JVM、比如Hotspot JVM都提供JIT(just in time) 动态编译器 ,能够在运行时将热点代码直接翻译成机器码,这部分属于编译执行

15、Java编译型语言,实现多态
继承和接口

编译时多态 指的是重载,运行时指的是对象引用所指向的具体类型在运行期间才确定。一个变量到底指向哪个实例类,该引用变量发出的方法调用是由哪个类实现的,必须程序运行时才能确定,

16、InnoDB主键索引的数据结构?
B+树

17、B+树相对B树的优势?
更矮更胖

18、UUID B+树的效率
肯定不会高,因为索引是占内存空间的,键越多,效率就越低,而且uuid排序不太友好。

19、UUID B+树的效率不高,那我们可以选取那种数据结构呢?
这里我一开始想到Trie树,uuid,trie树,面试官说也是一种方法。

后面说了hash,但是我想hash的话,没办法范围查找,范围查找是问题,不过面试官就是想要这个答案,然后引申出,java的hashmap,我恍然大悟,哈哈哈。

hash来建索引的话,是不错的选择,但是前提是没有范围查找。

20、最左匹配原则
如果a范围,后面还会用到索引吗?

肯定不会,最左匹配遇到范围就会终止的。

Like查询呢?

like xx%会走索引

like %xx不会走索引

反问

发表评论

后才能评论