面试 题一

文章目录

一、Java扩展篇

1、红黑树的实现原理和应用场景

在这里插入图片描述
红黑树(一颗自平衡树的排序二叉树)五大特性:

  1. 每个节点要么是红的,要么是黑的
  2. 根节点都是黑的
  3. 每个叶节点,即空节点是黑的
  4. 如果一个节点是红的,则它的两个儿子都是黑的
  5. 对每个节点,从该节点到其子孙节点所有路径上包含相同数目的黑节点。

场景

  1. 广泛用于C++的STL中,map和set都是用红黑树实现的.
  2. 著名的linux进程调度Completely Fair Scheduler,用红黑树管理进程控制块,进程的虚拟内存 区域都存储在一颗红黑树上,每个虚拟地址区域都对应红黑树的一个节点,左指针指向相邻的地址 虚拟存储区域,右指针指向相邻的高地址虚拟地址空间.
  3. IO多路复用epoll的实现采用红黑树组织管理sockfd,以支持快速的增删改查.
  4. ngnix中,用红黑树管理timer,因为红黑树是有序的,可以很快的得到距离当前最小的定时器.
  5. java中的TreeSet,TreeMap

2、NIO是什么?适用于何种场景?

(New IO)为所有的原始类型(boolean类型除外)提供缓存支持的数据容器,使用它可以提供非阻塞式的高伸缩性网路
特性:I/O多路复用 + 非阻塞式I/O

适用场景

服务器需要支持超大量的长时间连接。比如10000个连接以上,并且每个客户端并不会频繁地发 送太多数据。例如总公司的一个中心服务器需要收集全国便利店各个收银机的交易信息,只需要 少量线程按需处理维护的大量长期连接。

Jetty、Mina、Netty、ZooKeeper等都是基于NIO方式实现。

3、HashMap内部结构是什么?底层是怎么实现的?

HashMap内部结构
jdk1.8以前:数组 + 链表
jdk8以后:数组 + 链表(当长度达到 8 时,转化为红黑树)

在并发情况下,发生扩容时,可能会产生循环链表,在执行get时候,会触发死循环,;引起CPU 100%的问题,所以一定要避免在并发情况下使用hashMap。
在这里插入图片描述

4、说说反射的用途及实现,反射是不是很慢,我们在项目中是否要避免使用反射?

  • 用途 反射被广泛的用于那些需要再运行时检测或修改程序行为的程序中

  • 实现方式: Foo foo = new Foo();
    第一种:通过object类的getClass方法 Class cla = foo.getClass();
    第二种:通过对象实例方法获取对象 Class cla = foo.class;
    第三种:通过Class.forName方式 Class cla = Class.forName(“xx.xx.Foo”);

  • 缺点
    1)影响性能 反射包括了一些动态类型,所以 JVM 无法对这些代码进行优化。因此,反射操作的效 率要比那些非反射操作低得多。我们应该避免在经常被执行的代码或对性能要求很高的程 序中使用反射。

    2)安全限制 使用反射技术要求程序必须在一个没有安全限制的环境中运行。

    3)内部暴露 由于反射允许代码执行一些在正常情况下不被允许的操作(比如访问私有的属性和方 法),所以 使用反射可能会导致意料之外的副作用--代码有功能上的错误,降低可移植性。 反射代码破坏 了抽象性,因此当平台发生改变的时候,代码的行为就有可能也随着变化。

5、 ArrayList与LinkedList区别,ArrayList与Vector的区别?

  • 数据结构Vector ,ArrayList内部使用数组,而LinkedList内部使用双向链表,由数组和链表的特性知:
    LinkedList适合指定位置插入,删除操作,不适合查找;ArrayList,Vector适合查找,不适合指定位置的插入删除操作。
  • 线程安全:Vector线程安全,ArrayList,LinkedList线程不安全。
  • 空间:ArrayList在元素填满元素时,会自动进行扩充容器大小的50%,而Vector则是100%,因此ArrayList更省空间。

二、Spring相关

1.Spring AOP的实现原理和场景?

AOP(Aspect Orient Programming),作为面向对象的一种补充,广泛应用于处理一些具有横切性质的系统服务。

  • 场景
    事务管理、安全检查、权限控制、数据校验、缓存、对象池管理等。

  • 实现技术
    AOP(这里的AOP指的是面向切面编程思想,而不是Spring AOP),主要实现的技术有 Spring AOP和Aspect

    1)Aspect底层技术。Aspect底层技术是静态代理,即用一种Aspect支持的特定语言编写切面,通过一个命令来编译,生成一个新的代理类,该代理类增强了业务类,这是在编译时增强,相对于运行是增强,编译时增强性能更好。
    2)Spring AOP 采用的是动态代理,在运行期间对业务进行增强,所以不会生成新类他,对于动态代理技术,Spring AOP提供了JDK动态代理,CGLib动态代理。

    JDK动态代理只能为接口创建动态代理实例,而不能对类创建动态代理。需要获得被目标类的接口信息(应用java反射),生成一个实现代理接口的动态代理类(字节码),在通过反射机制获得动态代理类的构造函数,利用构造函数生成动态代理类的实例对象,在调用具体方法前调用invokeHandler方法来处理。

    CGLib动态代理需要依赖asm包,把被代理对象类的class文件加载进来,修改器字节码生成子类。但是SpringAOP基于注解配置的情况下,需要依赖Aspectj包的标准注解。

2.Spring bean的作用域和生命周期;

  1. singleton:在Spring IOC容器中仅存在一个Bean实例,bean以单利方式存在,默认值。
  2. prototype:每次从容器中调用bean时,都返回一个新的实例,每次调用getBean时,相当于执行new XxxBean();
  3. request:每次HTTP请求都会创建一个新的bean,该作用域仅适用于WebApplicationContext环境。
  4. session:同一个HTTP Session 共享一个Bean,不同Session使用不同的Bean,仅适用于WebApplicationContext环境。
  5. gloabSession:一般用于portlet环境,该作用域仅适用于WebApplicationContext环境。

生命周期
在这里插入图片描述

3.Spring Boot比Spring做了哪些改进?

  1. Spring Boot可以建立对立的Spring应用程序;
  2. 内嵌了如Tomcat,Jetty和Undertow这样的容器,也就是说可以直接跑起来,用不着在部署工作了。
  3. 无需向Spring那样搞一堆繁琐的xml配置文件。
  4. 可以自动配置Spring,SpringBoot将原有的XML配置改为Java配置,将bean注入改为使用注解注入的方式(@Autowire),并将多个XML,properties配置浓缩在一个application.yml配置文件中。
  5. 整合常用依赖(开发库,例如spring-webmvc,jackson-json、validation-api和tomcat等),提供的pom可以简化maven的配置,当我们引入核心依赖时,SpringBoot会引入其他依赖。

4.Spring IOC是什么?优点是什么?

IOC(Inversion of Control),控制反转,可以这样理解IOC容器:“把某些业务对象的控制权交给一个平台或者框架统一管理,这个统一管理的平台可以称之为IOC容器”。

  • IOC容器:最主要是完成了对象的创建和依赖管理注入。
    IOC的最核心的地方在于,资源不由使用资源的双方管理,而有不适用资源的第三方管理。
  • 好处
    1)资源集中管理,实现资源的可配置和易管理。
    2)降低了使用资源双方的依赖程度,也就是我们说的耦合度。

5.SpringMVC、动态代理、反射、AOP原理、事务隔离级别;

在这里插入图片描述

spring事务

脏读不可重复读幻读
Read uncommitted
Read committed×
Repeatable read××
Serializable×××

一、spring事务

事务逻辑上的一组操作,组成这个操作的各个逻辑单元,要么一起成功,要么一起失败。

二、事物特性(4种)

  • 原子性(atomicity):强调事务的不可分割
  • 一致性(consistency):事务执行前后的数据完整性保持一致
  • 隔离性(isolation):一个事务执行过程中,不应该受到其他事务的干扰
  • 持久性(durability):事物一旦结束,数据就持久到数据库

如果不考虑隔离性引发安全问题
脏读:一个事务读到了另一个事务未提交的数据
不可重复读:一个事务堵到了另一个事务已经提交的 update 的数据导致多次查询结果不一致。
虚幻读:一个事务读到了另一个事务已经提交的 insert 的数据导致多次查询结构不一致。

三、事务隔离级别
Default 是PlatfromTransactionManager,默认的隔离级别(可重复度),使用数据库默认的事务隔离级别。
未提交读(read uncommited):脏读,不可重复读,虚读都有可能发生。
已提交读(read commited):避免脏读,但是不可重复读和虚读都有可能发生。
可重复读(repeatable read): 避免脏读和不可重复读,虚读有可能发生。
串行化(serializable):避免以上所有问题。

MySQL 默认:可重复读
Oracle默认:读已提交

四、事务的传播行为

PROPAGION_XXX :事务的传播行为

  • 保证同一个事务中

    PROPAGATION_REQUIRED 支持当前事务,如果不存在 就新建一个(默认)

    PROPAGATION_SUPPORTS 支持当前事务,如果不存在,就不使用事务

    PROPAGATION_MANDATORY 支持当前事务,如果不存在,抛出异常

  • 保证没有在同一个事务中

    PROPAGATION_REQUIRES_NEW 如果有事务存在,挂起当前事务,创建一个新的事务

    PROPAGATION_NOT_SUPPORTED 以非事务方式运行,如果有事务存在,挂起当前事务

    PROPAGATION_NEVER 以非事务方式运行,如果有事务存在,抛出异常

    PROPAGATION_NESTED 如果当前事务存在,则嵌套事务执行

6、Spring中用到了哪些设计模式?

  1. 工厂模式:在各种BeanFactory以及ApplicationContext创建中都用到了
  2. 模板模式:在各种BeanFactory以及ApplicationContext实现中都用到了
  3. 代理模式:在AOP实现中用到了JDK动态代理
  4. 单例模式:这个比如在创建Bean的时候
  5. 外观模式:Tomcat中有很多场景都是用到了外观模式,因为在tomcat中有很多不同的组件,每个组件都需要通信,但又不能将自己内部数据过多的暴露给其他组件,用外观模式隔离数据是个很好的方法。
  6. 策略模式:在Java中,Comparator这个接口简直就是为策略模式而生,Comparable和Comparator的区别,比方说Collections里面有一个sort方法,因为集合里面的元素有可能是复合对象,符合对象并不像基本数据类型,可以根据大小排序,复合对象怎么排序呢,自行实现Comparable接口或Comparator接口。
  7. 原型模式:使用原型模式创建对象比直接new一个对象在性能上好很多,因为Object类的clone()方法是一个ntive方法,他直接操作内存中的二进制流,特别是复制大对象时,性能的差异非常明显。
  8. 迭代器模式:It而able接口和Iterator接口,这两个都是迭代相关的接口,可以这么认为,实现了Iterable接口,则表示这个对象是可被迭代的;Iterator接口相当于是一个迭代器,实现了Iterator接口,等于具体定义了这个可被迭代的对象是如何进行迭代的。

三、数据库篇

1.锁机制介绍:行锁、表锁、排他锁、共享锁;

2.乐观锁的业务场景及实现方式;

3.事务介绍,分布式事物的理解,常见的解决方案有哪些,什么是两阶段提交、三阶段提交;

4.MySQL记录binlog的方式主要包括三种模式?每种模式的优缺点是什么?

5.MySQL锁,悲观锁、乐观锁、排它锁、共享锁、表级锁、行级锁;

  • 乐观锁

    用数据版本(version)记录机制实现,这是乐观锁最常用的一种实现方式。何为数据库版本?即为数据增加一个版本标识,一般是通过为数据库表增加一个数字类型的“version”字段来实现,当读取数据时,将version字段的值一同读出,数据每更新一次,对此version值加一,当我们提交更新的时候,判断数据库表对应记录的当前版本信息与第一次取出来的version值进行比较,如果数据库表当前版本号与第一次取出来时的version值相等,则给予更新,否则认为是过期数据

  • 悲观锁
    在进行每次操作时都要通过获取锁才能进行对相同数据的操作,这点跟Java中synchronized很相似,共享锁(读锁)和排它锁(写锁)是悲观锁的不同实现。

  • 共享锁(读锁)
    共享锁又叫做读锁,所有的事务只能对其进行读操作不能写操作加上共享锁后在事物结束之前其他事务只能在加共享锁,除此之外其它任何类型的锁都不能在加了。

  • 排它锁(写锁)
    若某个事物对某一行加上了排它锁,只能这个事务对其进行读写,在此事物结束之前,其他事物不能对其加任和锁,其他进程可以读取,不能进行写操作,需要等待其释放。

  • 表级锁
    innodb的行锁是在有所有的情况下,没有索引的表是锁定全表的

  • 行级锁
    行锁又分为共享锁和排它锁,就是给某一行加上锁,也就是一条记录加上锁,注意:行级锁都是基于索引的,如果一条SQL语句用不到索引是不会使用行级锁的,会使用表级锁。

6.分布式事务的原理2阶段提交,同步异步阻塞非阻塞;

7.数据库事务隔离级别,MySQL默认的隔离级别、Spring如何实现事务、JDBC如何实现事务、

8.嵌 套事务实现、分布式事务实现;

9.SQL的整个解析、执行过程原理、SQL行转列;

四、Redis

1.Redis为什么这么快?

  1. 绝大部分请求是纯粹内存操作(非常快速)
  2. 采用单线程,避免了不必要的上线文切换和竞争条件
  3. 非阻塞IO-IO多路复用

2.Redis支持哪几种数据结构;

String 、List、Set、Hash、ZSet

3.Redis跳跃表的问题;

参考:

4.Redis单进程单线程的Redis如何能够高并发?

采用多路I/O复用技术可以让单个线程高效处理多个连接请求(尽量减少网络IO、的时间消耗)

5.Redis如何使用Redis实现分布式锁?

Redis分布式锁的正确实现方式

6.Redis分布式锁操作的原子性,Redis内部是如何实现的?

setnx
Incrby\Decrby

7、redis采用多线程会有哪些问题?

1)单线程的问题
无法发挥多核CPU性能,单进程单线程只能跑满一个CPU核
可以在单机开多个Redis实例来完善
可以通过数据分片来增加吞吐量,问题(不支持批量操作,扩容复杂。)

2)多线程的问题
多线程处理可能涉及到锁
多线程处理会涉及到线程切换而消耗CPU

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值