面试5.29
目录
- equals和==的区别
- 八大基本数据类型
- Integer与int的区别
- jdk1.8新特性
- String Stringbuilder StringBUffer
- run和start的区别
- 面向对象三大特征
- 常用数据结构(集合)以及hashmap的put原理
- Java是如何实现多线程的?
- sleep和wait的区别
- 说说常用的设计模式
- 说一说对于 synchronized 关键字的了解
- mysql怎么实现批量插入
- 四大特性
- 说说隔离级别,分别解决什么问题?
- 幻读不可重复读的区别?
- 了解索引吗?什么情况下需要建索引?
- 索引失效?
- 索引有什么缺点?为什么会造成(底层原理)
- 索引的分类
- 说一说MVC三层架构
- IOC和AOP的理解
- Spring Bean的生命周期
- springboot启动类需要加什么注解?
- 使用rabbitmq的场景(优点)
- MQ的工作模式
- redis基本数据类型
- 缓存穿透,击穿,雪崩以及应对方法
- MVCC了解过吗
- 项目中发短信用到mq,发短信的流程是什么?使用mq短信异步处理怎么做的?
- 项目中用到了redis缓存,下单功能缓存哪个数据?
- 下单库存怎么保证redis和数据库数据的一致性?场景模拟:一件物品200块,我要修改它,是先改数据库还是先改redis缓存?
- 平时建mysql表的时候会考虑一些什么
- 写sql语句的时候where会考虑什么?
- 数组和链表的区别是什么?
equals和==的区别
==:
- 基本数据类型:比较的是值是否相等
- 引用数据类型:比较的是地址是否相等,即两个引用是否指向同一个地址值
equals:
- 没有重写,比较的是两个对象的地址是否相等,此时等价于 == 重写,按重写的方式进行比较,一般比较内容是否相等
八大基本数据类型
- byte,short,int,long,都为整型,分别1248字节
- boolean,char,float,double,分别1248字节
Integer与int的区别
- 包装类型可以为 null,而基本类型不可以
- int默认0,integer默认null
- integer可以区分0和null
- integer可以用于泛型
- integer在栈中存的是堆中对象的引用,int存的是具体数值
jdk1.8新特性
- hashmap底层加入了红黑树
- Lambda表达式
- 函数式接口(有且仅有一个抽象方法的接口)
- 接口中允许有默认方法与静态方法
String Stringbuilder StringBUffer
- string:不可变字符序列,效率低,复用率高
- stringbuffer:可变,效率高(增删),线程安全
- stringbuilder:可变,效率最高,线程不安全
run和start的区别
调用 start() 方法是用来启动线程的,轮到该线程执行时,会自动调用 run();直接调用 run() 方法,无法达到启动多线程的目的,相当于主线程线性执行 Thread 对象的 run() 方法
面向对象三大特征
- 封装:将类的属性私有化,不再为外界提供直接访问属性的方式,而是提供对应的getter和setter方法来访问和设置属性,实现高内聚低耦合。提高数据的安全性
- 继承:(1)子类继承了所有的方法和属性(2)子类必须调用父类的构造器完成父类的初始化(3)默认情况调用父类的无参构造器,如果父类没有提供无参构造器,则必须在子类的构造器中用super去指定(4)单继承
- 多态:实现三要素:继承,重写,父类引用指向子类对象(向上转型)
常用数据结构(集合)以及hashmap的put原理
略
Java是如何实现多线程的?
- 继承Thread类
- 实现Runable接口
- 通过 Callable 和 FutureTask 创建线程
sleep和wait的区别
- sleep:属于Thread类,在任何场景都能调用,不会释放锁
- wait:属于Object类,必须在同步代码块或同步方法中,释放锁,需要手动唤醒(notify方法)
说说常用的设计模式
- 单例模式(懒汉式、饿汉式)
- 工厂模式(IOC)
- 代理模式(AOP)
- 策略模式
- 模板方法模式
说一说对于 synchronized 关键字的了解
synchronized 关键字解决的是多个线程之间访问资源的同步性,synchronized关键字可以保证被它修饰的方法或者代码块在任意时刻只能有一个线程执行
- synchronized 关键字加到 static 静态方法和 synchronized(class) 代码块上都是是给 Class 类上锁
- synchronized 关键字加到实例方法上是给对象实例上锁。
- 尽量不要使用 synchronized(String a) 因为 JVM 中,字符串常量池具有缓存功能
mysql怎么实现批量插入
使用
insert into table ([列名],[列名])
VALUES
([列值],[列值])),
([列值],[列值])),
批量插入,这种效率比较高效
四大特性
- A:侧重事务的完整,操作要么全部成功要么全部失败
- C:DML语句同时成功或失败,事务执行前后保证数据一致性
- I:隔离级别相关
- D:事务的保证和结束的标志,将数据持久化到磁盘
说说隔离级别,分别解决什么问题?
- ru:读未提交,一个事务在执行的过程中读取到另一个没有提交的的数据,形成脏读现象
- rc:读已提交,读到了另一个事务提交的数据,造成不可重复读取,解决脏读
- rr:可重复读,事务A提交之后的数据,事务B读取不到,可能造成幻读,解决不可重复读取
- s:事务A和事务B,事务A在操作数据库时,事务B只能排队等待
幻读不可重复读的区别?
幻读和不可重复读都是读取了另一条已经提交的事务,不同的是不可重复读的重点是修改,幻读的重点在于新增或者删除
了解索引吗?什么情况下需要建索引?
- 数据量庞大
- 经常用于查询的字段,即该字段出现在where的后面以条件的形式存在
- 很少的DML操作(增删改),DML后索引需要重新排序
索引失效?
- 模糊查询的时候以%开头
- 如果使用or,要求两边的条件字段都要有索引才会走索引
- 使用复合索引(两个字段或者多个字段联合起来添加一个索引)没有使用左侧的列查找,用右边的会失效
- where中索引列参加了运算
- where中索引列使用了函数
索引有什么缺点?为什么会造成(底层原理)
降低表的增删改的效率,因为每次对表记录进行增删改,需要进行动态维护索引
索引的分类
聚簇索引:
- 使用表的主键构造主键索引树,叶子节点存的是整行数据,使用双向链表连接,按照主键的顺序排序
二级索引:
- 普通索引:即一个索引只包含单个列,一个表可以有多个单列索引
- 唯一索引:索引列的值必须唯一,但允许有空值
- 复合索引:多列值组成一个索引,专门用于组合搜索,其效率大于索引合并
说一说MVC三层架构
Model(模型):数据模型,提供要展示的数据,一般分离为dao层(数据处理)和service层(调用dao层完成业务处理)
View(视图):负责进行模型的展示
Controller(控制器):接收用户请求,委托给模型进行处理(状态改变),处理完毕后把返回的模型数据返回给视图,由视图负责展示
IOC和AOP的理解
IOC:
- 将对象的控制权转移给Spring框架,由 Spring 来负责控制对象的生命周期,用到了工厂模式
AOP:
- 程序重复的代码抽取并封装为一个可重用的模块,这个模块被命名为“切面”(Aspect),是OOP的一种延续,用于权限认证、日志、事务处理
Spring Bean的生命周期
实例化 Instantiation --> 属性赋值 Populate --> 初始化 Initialization --> 销毁 Destruction
springboot启动类需要加什么注解?
@SpringbootApplication,包含以下三个子注解:
- SpringBootConfiguration 将Application启动类作为Bean类注入到Spring容器中
- EnableAutoConfiguration 实现自动配置功能
- ComponentScan 实现自动扫描的功能,具体来说:就是告诉Spring容器注册"一些"Bean后处理器,从而能够支持各种注解
使用rabbitmq的场景(优点)
- 流量消峰:订单系统使用消息队列做缓冲,把一秒内下的订单分散成一段时间来处理,这时有些用户可能在下单十几秒后才能收到下单成功的操作
- 应用解耦:比如物流系统因为发生故障,需要几分钟来修复。在这几分钟的时间里,物流系统要处理的内存被缓存在消息队列中,用户的下单操作可以正常完成
- 异步处理
MQ的工作模式
- 发布/订阅模式(交换器类型为fanout): 当发送一条消息到fanout交换器上时,它会把消息投放到所有附加在此交换器上的队列
- 路由模式(交换器类型为direct):如果路由键完全匹配的话,消息才会被投放到相应的队列
- 主题模式(交换器类型为topic):模糊匹配的绑定方式
redis基本数据类型
String,List,Set,Hash,Zset
缓存穿透,击穿,雪崩以及应对方法
穿透:对不存在的key进行高并发访问,导致数据库压力瞬间增大
- 对空值缓存,设置白名单,实时监控
击穿:热点数据被超高并发地访问
- 缓存预热,使用锁,实时调整
雪崩:缓存中数据大批量到过期时间,而查询数据量巨大,引起数据库压力过大甚至down机
- 使用锁,构建多级缓存架构
MVCC了解过吗
项目中发短信用到mq,发短信的流程是什么?使用mq短信异步处理怎么做的?
前台调用发短信接口,后台控制器调用service层的方法,将短信放入mq,再由mq通过rabbitTemplate的convertAndSend方法发送短信给用户
项目中用到了redis缓存,下单功能缓存哪个数据?
缓存库存
下单库存怎么保证redis和数据库数据的一致性?场景模拟:一件物品200块,我要修改它,是先改数据库还是先改redis缓存?
- 方案一:先删缓存,再更新数据库,采用延时双删策略
平时建mysql表的时候会考虑一些什么
表名,字段,数据类型,长度,是否为空,主键
写sql语句的时候where会考虑什么?
- 应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描
- 应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描
- 尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描
数组和链表的区别是什么?
区别:
- 数组长度固定,链表动态分配空间
- 数组,查询效率高O(1),插入和删除效率差O(N),链表相反
- 数组的空间是从栈分配的,链表的空间是从堆中分配的