Java面试题集六

1、SpringBoot启动过程

https://www.cnblogs.com/trgl/p/7353782.html

2、Spring启动类的注解

@SpringBootApplication包含了以下注解:

@SpringBootConfiguration  标注当前类是Java Cofig配置类,会被扫描并加在到IOC容器

@ComponentScan  扫描默认包和指定包下面的符合条件的组件并加在,如@Component 、@Controller

@EnableAutoConfiguration  从classpath中搜寻所有的META-INF/spring.factories配置文件,并将其中org.springframework.boot.autoconfigure.EnableAutoConfiguration对应的配置项通过反射(JavaRefletion)实例化为对应的标注了@Configuration的JavaConfig形式的IOC容器配置类,然后汇总为一个,并加载到IOC容器中

@AutoConfigurationPackages注册当前主程序类的同级以及子级的包中的符合条件(@Configuration)的Bean的定义

@Import(AutoConfigurationImportSelector.class) 扫描各个组件jarMETA-INF目录下的“spring.factories”文件,将下面的“包名.类名”中的工厂类全部进行加载到IOC容器中

比较重要的有三个注解:

1)@SpringBootConfiguration // 继承了Configuration,表示当前是注解类

2)@EnableAutoConfiguration  // 开启springboot的注解功能,springboot的四大神器之一,其借助@Import的帮助

@ComponentScan(excludeFilters = { // 扫描路径设置})


3、SpringBoot配置文件yml与properties的区别

yml拥有天然树形结构

yml支持中文,properties要输入中文只能用unicode编码

properties不能保证执行顺序,yml有执行顺序

4、怎么装配bean(xml文件或者注解)

使用xml文件来配置bean,使用bean标签,id为bean名,class为具体的Bean类

使用@Component注解时,表明该类会为组件类,Spring默认为这个类创建bean

在类上可以使用@ContextConfiguration包含class或者xml


5、MyBatis的依赖,需要引入哪些MyBatis start

org.mybatis.spring.boot-->mybatis-spring-boot-starter

6、MyBatis怎么找到Mapper接口去执行sql语句

Spring中启动Mybatis两个重要类:SqlSessionFactoryBean和MapperFactoryBean

在启动类上添加@MapperScan("地址")这里对应的是项目中的Mapper类的路径


7、Spring的IOC原理

IOC是指容器控制对象之间的关系,控制权由应用代码转到了外部容器,控制权的转移就是所谓的反转。在Spring中就是由Spring来控制对象的生命周期和对象之间的关系;IOC还有另外一个名字——“依赖注入”即组件之间的依赖关系由容器在运行期决定,即由容器动态地将某种依赖关系注入到组件之中。

所有类的创建和销毁都是由spring来控制,也就是说控制对象生命周期的不再是引用它的对象,而是spring。

在系统运行中,动态的向某个对象提供它所需要的其他对象

IOC的优点:降低了组件之间的耦合,降低了业务对象之间替换的复杂性,使之能够灵活的管理对象

依赖注入的思想是通过反射机制实现的。

8、MySQL的事物(原子性一致性隔离性持久性)原子性原理

在同一个事物里面的sql,要么全部成功,要么全部失败,来保证事物的原子性


9、MySQL的默认隔离级别(read uncommitted、read committed、repeatable read、serializable)

默认级别为:repeatable read

10、Mysql索引,实质上是一个数据结构(详细)

Mysql中索引最大的长度为255个字符

InnoDB数据表不支持全文索引

Mysql索引是B+树,只会在叶子节点上挂载数据,非叶子节点只存放索引列的数据。这样一个节点就可以存放很多个索引列数据,一次IO就可以拿到很多数据,MySQL默认一个节点是16k大小(每次IO能读到的)。

以索引列是bigInt类型为例,大小8字节,每一条数据还有一个指向下一层的指针6字节,16384/(8+6)=1170,一个节点就大约可以存1170条数据。


11、Vue.js父子组件(兄弟)是怎么通信的

父组件——>子组件

1)直接关系:属性传值(props)、$children(数组)、$refs

2)跨多层关系:provide、inject

子组件——>父组件

1)直接关系:事件传值、$parent

兄弟组件:使用实践中心,实例化一个空的vue

12、Vue的脚手架

13、前后端通信ajax

14、String的+和StringBuilder的区别

字符串连接,用+进行连接其实内部也是通过StringBuilder的append来实现的

String每次+都会划分一块新内存区域;StringBuilder只有一块内存区域

StringBuilder对象及其成员:

1)value[]:用来存储StringBuilder对象中的字符,也就是内容数组,其长度可在创建对象时通过构造函数初始化,若未初始化则默认初始长度为16

2)count:记录StringBuilder对象中所存字符的实际数量

流程:首先开始执行str,append(str),如果内容数组容量(count+str.length>char.length)不足,则扩张内容数组的长度,默认扩张为原来长度*2+2,判断默认方法增加的容量是否足够(char.length*2+2

如果内容数组长度足够,直接将数组str复制到内容数组,最后更新实际内容长度count+=len

如果扩容后容量足够,将str复制到内容数组中,此时内容数组长度为char.length*2+2,最后更新实际内容长度count+=len


15、StringBuilder内存空间多大,内存泄露的原因

StringBuilder默认容量为16,默认最大的容量为Int32.MaxValue

16、HashMap的怎么实现线程安全

1)通过collections.synchronizedMap()的接口,返回的是一个Map,这个map就是安全的,这个需要面向接口编程,返回的是一个Map

2)重写HashMap,通过java.util.Concurrent.ConcurrentHashMap(),把HashMap里面的方法进行拆分

(1)实现机制

1.使用collections.synchronizedMap方法封装所有不安全的方法,包括hashcode,toString(),通过synchronized来实现互斥。

​2.重写hashMap方法,采用新的锁是:Nonfairsync,将hashMap拆分成各个独立的块,减少锁之间的冲突

(2):锁机制不同:

方法一:使用的是synchronized,是一种悲观的,在进入之前必须获取锁,确保当前是独享状态,后面的都是在等待!

方法二:乐观锁;只有在需要修改对象的同时,比较和之前的值是否发生变化,如果被人修改了,就返回失败,而锁的实现是使用NonfairSync,这个特性是来保证原子性和互斥性,无法在jdk这个级别得到理解​,jdk调用jni方法,jni方法通过调用cas指令确保原子性和互斥性!

乐观锁的实现原理:当多个线程恰好操作到concurrentHashMap​同一个segment上面是,只会有一个线程得到运作,其他的都被LockSupport拦截,稍后执行以后,会自动挑选一个线程来执行LockSupport

3:优缺点:

1.方法简单,但是因为线程安全,造成大量线程阻塞问题,影响性能

2.互斥代码比较少,性能高,但是因为hashMap被分解了很多块,所以发生碰撞的机会大大降低了!!​

代码实现稍稍复杂些.

使用其他线程安全的Map,比如HashTable、concurrentHashMap、SynchronizedMap

其中concurrentHashMap性能最好

17、Synchronized和lock的区别


区别


18、实现多线程的方式,实现后要写什么方法

继承Thread类,重写run函数

实现Runnable接口,重写run函数

实现Callable接口,重写call函数

Callable和Runnable有几点不同:

①Callable规定的方法是call(),而Runnable规定的方法是run().

②Callable的任务执行后可返回值,而Runnable的任务是不能返回值的

③call()方法可抛出异常,而run()方法是不能抛出异常的。

④运行Callable任务可拿到一个Future对象,Future表示异步计算的结果。它提供了检查计算是否完成的方法,以等

待计算的完成,并检索计算的结果.通过Future对象可了解任务执行情况,可取消任务的执行,还可获取任务执行的结果


19、框架启动后最多可以有多少个多线程

https://www.cnblogs.com/magic-jiangtao/articles/9535604.html


B tree的数据结构详解

根节点(叶节点)和子节点的关系

2n

两个相同的数据表,一样的数据,但是A表查询速度比B表快是什么原因

索引为什么检索速度快

使用B+tree数据结构,通过事先排好序,在查找时可以应用二分查找等高效率的算法(O(log2n))

Disruputor的优势

环状队列

disruptor内部使用环形队列ringBuffer不会增加GC回收频率。

解决伪共享问题

伪共享是由于缓存一致性协议导致的。disruptor采用填充7个long型变量来保证cursor不会和其他数据处于同一个缓存行(多数计算机缓存行大小64字节),避免由于伪共享问题导致重新从主存读取数据。

位运算快速定位数组下标

设置环状数组的长度为2^n,这样可以采用seq & length的方式快速得到数组下标。

无锁设计

disruptor使用CAS保证线程安全,避免了锁带来的线程挂起/唤醒开销。

disruptor基本概念

RingBuffer:Ringbuffer是一个环状数组,用于存放数据,是disruptor的核心。

Sequencer:序号管理器,使得消费者和生产者可以正确读取、存储数据。

Sequence:消费者和生产者都会维护一份自己的序号,用于标记下一读写位置以及可读写区间。

Event:存储的数据是包装在Even中的,RingBuffer真正存的是Even。

EventHandler:自定义消费者接口,拿到消息后完成实际业务功能。

Producer:生产者接口,生成消息。

寻路算法

你可能感兴趣的:(Java面试题集六)