java面试补充
instanceof关键字的使用
instanceof严格来说是java中的一个双目运算符,用来测试一个对象是否是一个类的实例。
什么是隐式转换,什么是显示转换
显示转换就是类型强转,把一个大类型的数据强制赋值给小类型的数据,隐式转换就是大范围的变量能够接受小范围的数据;隐式和显示其实就是自动类型转换和强制类型转换。
那些浮点型数据运算出现的误差的问题,怎么解决
使用bigdecimal类进行浮点型数据的运算
Java中有没有指针?
有指针,但是隐藏了,开发人员无法直接操作指针,由jvm来操作指针。
构造方法能不能显示调用
不能,构造方法只有在创建对象时才会被系统调用。
final在java中的作用,有哪些用法?
(1)被fianl修饰的类不可以被继承
(2)被final修饰的方法不可以被重写
(3)被final修饰的变量不可以被改变,如果修饰的是引用,不可能改变引用,只能改变引用的内容。
(4)被final修饰的常量,在编译期间就会被存入常量池中。
有没有可能两个不相等的对象拥有相同的hashcode
有可能,在产生hash冲突时,两个不相等的对象就会有相同的hashcode,解决方式有:
(1)拉链法:每个哈希表节点都拥有一个next指针,因此可以形成一个单向链表。
(2)开放地址法:只要发生哈希冲突,就是寻找下一个空的散列地址。
(3)再哈希法:使用多个不同的哈希函数,发生冲突时,使用另一个函数。
JDBC操作的步骤
(1)加载数据库驱动类
(2)打开数据库连接
(3)执行sql语句
(4)返回结果
(5)关闭资源
在使用jdbc的时候,如果防止sql注入的问题
使用PreparedStatement类,而不是Statement类
静态内部类
(1)静态内部类可以访问外部类的所有静态成员和静态方法
(2)静态内部类与一般类一致,可以定义静态变量、方法、构造方法
(3)其他类使用静态内部类需要使用外部类.静态内部类的方式
(4)Java集合类HashMap内部就有一个静态内部类Entry。
什么是java序列化,如何实现java序列化
序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化。可以对流化的对象进行读写操作,也可以对流化的独享传输于网络之间。序列化是为了解决在对对象流化进行读写时所引发的问题。序列化的实现:将需要被序列化的类实现Serializable接口。
sleep和wait的区别
(1)对于sleep()方法,我们首先应该知道该方法是属于Thread类中的,而wait()方法则是属于Object类中的。
(2)sleep()方法导致了程序暂停执行指定的时间,让出cpu给其他线程,但是它的监控状态依然保持,当指定时间到了后又自动恢复到运行状态。
(3)在调用sleep()方法的过程中,线程不会释放对象锁。
(4)当调用wait()方法的时候,线程会放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象调用notify()方法后本线程才进入对象锁定池准备获取对象锁进入状态。
简述对于线程池的理解
(1)降低资源消耗,通过重复利用已经创建的线程降低线程创建和销毁所造成的损耗。
(2)提高响应速度,当任务到达时,任务可以不需要等待线程创建就能立即执行。
(3)提高线程的可管理性。使用线程池可以对线程进行统一的分配,避免系统崩溃。
什么是自旋锁
如果持有锁的线程能够在很短的时间内释放锁资源,那么等待竞争锁的线程就不需要做内核态和用户态之间的切换进入阻塞,只需要等一等(自旋),等待持有锁的线程释放锁后立刻获取锁,这样就避免了内核切换的消耗。
线程自旋是需要消耗cpu的,说白了就是让cpu做无用功,如果一直获取不到锁,需要设定一个自旋等待的最大时间。
上下文
CPU寄存器和程序计数器的内容。
线程池的组成
(1)线程池管理器:用于创建并且管理线程池
(2)工作线程:线程池中的线程
(3)任务接口:每个任务必须实现的接口,用于工作线程调度其运行
(4)任务队列:用于存放待处理的任务,提供一种缓冲装置
进程与线程的区别
进程是操作系统分配资源的最小单位,线程是操作系统任务调度的最小单位
两种线程调度算法
(1)分时调度模型指的是让所有的线程轮流获取cpu的使用权,并且平均分配给每个线程占用的cpu的时间片。
(2)java虚拟机采用抢占式调度模型,指的是先让可运行池中优先级高的线程占用cpu,如果可运行池中的线程优先级相同,那么随机选择。运行状态的线程会一直运行,直到其不得不放弃cpu。
如何判断对象可以被回收
(1)引用计数:每个对象有一个引用计数属性,新增一个引用计数+1,释放时减1,计数为0时被回收。此方法无法解决对象相互循环引用的问题。
(2)可达性分析:从GC Roots开始向下搜索,搜索过的路径称为引用链。当一个对象到GC Roots没有任何引用链相连时,则证明此对象是不可达的。
大表如何优化
(1)限定数据的范围:务必禁止不带任何限制数据范围条件的查询语句,比如将时间控制在一个月内。
(2)读写分离:经典的数据库拆分方案,主库负责写,从库负责读
(3)垂直分区:根据数据表的相关性进行拆分。将一张表拆分为多张表。
(4)水平分区:保持表结构不变,根据某种策略存储数据分片。
存储过程
一组为了完成特定功能的SQL语句集合,存储在数据库中,经过第一次编译后不需要再次编译,用户通过存储过程的名字并给出参数来执行它。存储过程是数据库一个重要的对象。
触发器
触发器是一段能自动执行的代码,是一种特殊的存储过程。
Mysql中有几种锁
(1)表级锁:开销小,加锁块,不会出现死锁,发生锁冲突概率最高,并发性能最低。
(2)页面锁:开销和加锁时间中等,会出现死锁,并发性能一般。
(3)行级别锁:开销大、加锁满,会出现死锁,发生冲突概率最低,并发度最高。
Redis为什么这么快
(1)纯内存操作
(2)单线程操作,避免了频繁的上下文切换
(3)采用了非阻塞I/O多路复用机制
redis过期键的删除策略
(1)定时删除:在设置键的过期时间的同时,创建一个timer,使用定时器删除键。
(2)惰性删除:放任过期键不管,但是每次从键空间获取键时,都会检查取得的键是否过期,如果过期就删除;没有则返回。
(3)定期删除:每隔一段时间就对数据库进行检查,删除里面的过期键。至于要删除多少过期键,以及要检查多少个数据库,则由算法决定。
Redis如何做内存优化
尽可能地使用散列表,散列表使用的内存非常小,所以应该尽可能的将你的数据模型抽象到一个散列表里。比如你的web系统中有一个用户对象,不要为整个用户的名称,形式,邮箱,密码设置单独的key,而是把这个用户的所有信息存储到一张散列表里。
什么是IOC
就是控制反转,把对象创建和对象之间的调用过程,交给Spring进行管理,使用IOC是为了降低耦合度。