Java面试题总结

Java基础

你怎么理解面向对象、面向过程

面向对象,强调一切皆对象,我们现实生活中的实体都可以抽象为一个个对象,每个对象都有自己的属性和方法,通过对象之间的关系的组合来解决实际生活上的问题。
面向过程,将程序视为某个事件的一系列操作步骤。
两者的区别:面向对象以对象为中心,面向过程以过程为中心。对于简单问题而言,面向过程更加简单高效,面向对象反而更加抽象、复杂。但是对于复杂问题而言,由于面向对象不关注具体的过程,在问题的发展变化中,面向对象代码的拓展性和复用性更高。

面向对象的三大特征

封装、继承、多态。
我们在将实体抽象成对象时,会定义一些属性,并且会提供获取这些属性的方法以及这个对象的其他行为方法,这就是封装;
对象间有父子级关系,就会有继承;
在有继承的基础上,子类与子类之间、子类与父类之间方法不会完全一致,具有多样性,这就是多态。

Java数据类型

Java数据类型有两大类,基本数据类型(8种)和引用数据类型;八种基本数据类型其对应的包装类也属于是引用数据类型。
基本数据类型又可以继续分为四类,整数型(byte、short、int、long)、浮点型(float、double)、字符型(char)、布尔型(boolean)。

数据类型名称字节数默认值
byte10
short20
int40
long80
float40.0
double80.0

为什么要有包装类

Java是一门面向对象的语言,基本数据类型不是对象。
有包装类的好处是,包装类里面也封装了很多好用的方法,比如我们常用的值转换(Integer与String互转等等)。

==和equals区别

==是运算符号,用在基本数据类型之间是值比较,用在引用对象之间是内存地址比较;
equals是一个方法;Object也有equals方法,Object的equals是比较内存地址,由于Object是所有类的父类,所以equals的含义取决于当前比较的类有没重写equals方法,没重写就是比较内存地址,重写了就是重写了的逻辑。

“1”.equals(1)返回true还是false

false。因为String重写equals时候有类型判断(instanceof)。

public boolean equals(Object anObject) {
    if (this == anObject) {
        return true;
    }
    if (anObject instanceof String) {
        String anotherString = (String)anObject;
        int n = value.length;
        if (n == anotherString.value.length) {
            char v1[] = value;
            char v2[] = anotherString.value;
            int i = 0;
            while (n-- != 0) {
                if (v1[i] != v2[i])
                    return false;
                i++;
            }
            return true;
        }
    }
    return false;
}

并发编程

Java锁有几种

有两种,一种是使用synchronized关键字,一种是使用Lock的实现类。
两者的区别主要体现在用法上,性能上由于1.6(包含1.6)之后synchronized已经做了优化,性能两者差距不是很大。
synchronized是关键字,可以修饰方法和代码块,可以修饰静态方法,但不能修饰静态代码块。修饰代码块时可以对某个对象加锁也可以对某个类进行加锁。
使用Lock实现类加锁时是使用的一个类,需要我们new一个Lock并且自己加锁(lock)和释放锁(unlock),由于可以自己释放锁,所以比synchronized更灵活,但带来问题是如果代码编写有问题,可能导致锁一直没释放,所以一般要使用try-finally处理。

synchronized优化有哪些

锁升级(也叫锁膨胀)、锁消除、锁粗化、适应性自旋。
锁升级是指原来synchronized是重量级锁,后来优化成分了四种状态:无锁、偏向级锁、轻量级锁、重量级锁;
锁消除是JVM会对代码进行逃逸分析,假如某段代码不需要加锁(指没有线程竞争),就会移除掉这个锁;
锁粗化是将多个连续的加锁、解锁操作连接在一起,扩展成一个范围更大的锁;
适应性自旋是说多线程在竞争锁的时候是处于自旋式竞争,没优化之前自旋次数是固定的十次,若十次没获取到锁就处于阻塞状态,现优化成根据前一个获取到锁的自旋次数来改变。如果前一个线程正常获取到锁那说明当前线程也大概率能正常获取到锁,可增加次数来避免线程进入阻塞状态,如果前一个线程没获取到锁,说明当前线程可能也获取不到,次数可减小一点或直接跳过自旋,减少不必要自旋带来资源浪费。

synchronized锁升级的过程

当一个对象没有任何线程竞争就是无锁状态;
假如只有一个线程在获取锁,若开启了偏向锁(偏向锁默认开启),那此时该对象锁标志就是偏向锁,表示锁属于这个线程;
假如有另一个线程也要获取锁,那就产生了竞争行为,当它使用CAS自旋去获取锁时偏向锁也升级为轻量级锁;
当竞争进一步加剧时,轻量级锁就会升级为重量级锁。

CAS的ABA问题

CAS意思是比较并交换。我们在修改数据之前先拿旧数据去和当前值比较,如果一样说明没有线程改变数据,可以更新,如果有变化说明有其他线程更新,不能更新,那需要进行新一轮计算并判断。
ABA问题的意思是其他线程先将值更新为B,再更新回A,这个时候我们原值拿A去判断是感知不到其他线程有做修改的,所有就会有问题。解决办法是加一个版本号,juc包下的AtomicReference已经实现了。

JVM

讲一下JMM

JMM即Java内存模型,它把内存分为了主内存跟工作内存,主内存是所有线程共享,工作内存是每个线程私有,当我们对一个变量进行运算时,要先把变量从主内存拷贝到工作内存,运算完之后再把最新的值从工作内存刷新到主内存。

数据库

MySQL

索引有哪些分类

按照索引结构来分,有BTREE索引、HASH索引。这里的BTREE索引实际就是用的B+树。
按照索引字段数量来分,有单列索引、联合索引。
按照索引功能来分,有唯一索引、普通索引、空间索引、全文索引。

空间索引是干嘛的

空间索引是用来提升空间数据字段查询效率的,空间数据字段一般只有做地图的才会使用到。

全文索引和普通索引有什么区别

SQL优化有哪些

首先是优化SQL写法:
1.去掉不需要的字段查询;
2.尽量关联查询而不是子查询;
3.DISTINCT、GROUP BY、排序都比较耗性能,要理性使用;
4.LIMIT优化,数据量太大情况下,尽量先加上主键id作为WHERE条件进行过滤;
5.EXISTS适合小表驱动,因为是先查主SQL,然后把结果带入子查询,也就是查询结果1000条就会走1000个子查询;
6.查询条件尽量精确,不要啊出现查了很多不要数据情况。
然后是索引优化,索引优化就是看执行计划:
EXPLAIN加SQL,执行完之后看结果,重点需要看id、type、key、rows这几列。id代表了SQL片段的执行顺序,id越大越先执行,id相同则从上往下一次执行。type是访问类型,从好到坏一次是const > ref > range > index > ALL,当然也还有其他类型,这几个是最常见的。key表示使用到的索引名称。rows表示找到数据大概要读取的行数,越小越好,当然大也不一定就真的很差。

联合索引什么情况下失效

1.不符合最左匹配原则时索引失效;
比如有索引n1 (a,b,c),那单独使用b或者c字段查询就不会走索引,使用b和c一起查询也不会走。但假如使用了三个字段,即使顺序不是abc,也还是会走索引的,MySQL有优化。
2.多个查询字段使用or连接而不是and。

Mybatis

$与#区别

$会直接将参数原封不动的传到SQL里面去;
#会先用?占位然后根据数据类型做转换,要是字符串的话会自动加上引号。

什么情况下需要使用$

当我们需要传入表名或者字段名时候。

如果使用$怎么解决SQL注入问题

使用枚举或者是常量进行转换,不将前端传参直接传入数据库,这样参数永远是预期内的值。

缓存中间件

Redis

数据结构

首先,对于Redis来说,key都是String,一般说数据结构讨论的都是value。

基础数据结构

String(字符串)、Hash(哈希)、List(列表)、Set(集合)、Zset(有序集合)。
String通常来存普通字符串及数字;
Hash用来存储键值对,可以用来存储对象,比如我们可以用一个键为lisi,value为Hash的形式来存储李四这个人的信息,而不是一个属性一个key;
List是一个有序链表,可用来做消息队列,或者是其他需要使用有序特性的场景;
Set是一个无序且不允许重复的集合;
Zset是一个有序且不允许重复的集合,每一个元素要求有一个score,通过score进行排序,score可以重复。可以用来做延时队列。

其他特殊数据结构

Bitmap,可用来做布隆过滤器,但是offset与业务含义的对应关系需要我们自己维护。
Bitmap对应的命令

消息中间件

Spring、Spring Boot

Spring Cloud

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值