java面试题

数据库语句是如何优化的?
1.减少数据访问: 设置合理的字段类型,启用压缩,通过索引访问等减少磁盘IO
2.返回更少的数据: 只返回需要的字段和数据分页处理 减少磁盘io及网络io
3.减少交互次数: 批量DML操作,函数存储等减少数据连接次数
4.减少服务器CPU开销: 尽量减少数据库排序操作以及全表查询,减少cpu 内存占用
5.利用更多资源: 使用表分区,可以增加并行操作,更大限度利用cpu资源

使用SpringBoot的时候各种配置文件是怎么引入的
自动配置类是什么时候导入内存的 启动类上的注解:@SpringBootApplication

包含三个注解:

 1.@ComponentScan 包的扫描

 2.@SpringBootConfiguration 定义配置类

 3.@EnableAutoConfiguration 启动自动配置(将自动配置类加载到内存)

怎么加载类到内存中? Class.forName(“完整类名”)

@EnableAutoConfiguration --> AutoConfigurationImportSelector --> loadFactoryNames —>

loadSpringFactories --> classLoader.getResources(“META-INF/spring.factories”)

在spring-boot-autoconfigure包下保存大量的自动配置类

类名都保存 META-INFO/spring.factotiries文件下

自动配置类生效需要一定条件,如@ConditionalOnClass,引入某些类时(导入了对应的框架依赖)

说说你做过的项目和你主要负责的模块
伊顿在线教育平台为学习者提供便捷、实用性强的 IT 技能学习课程,同时支持学习者互动分享、采用分 布式的架构设计,包括后台管理、前台系统。前台主要包括:网关服务、授权服务、课程服务、用户服 务、广告服务、支付服务、订单服务、ES 服务、购物车服务、评论服务等。后台主要包括:用户管理、 角色管理、权限管理、课程管理、订单管理等模块。

项目职责:

  1. 课程搜索功能:将 ES 中查询到的数据分页显示到页面,包含基本信息、课程老师,课程方向,课程视频,课程 优惠等,也可以对数据进行一个多条件的分页查询,以及搜索关键字的高亮显示。添加课程信息或修改时,用 RabbitMQ 消息队列通知 ES 服务,实现 MySQL 和 ES 的数据同步。

  2. 单点登录:采用了 JWT 和 RSA 加密算法,用户登录成功后鉴权服务生成 token,用户每次访问携带 token, 网关服务解密 token。

  3. 微信扫码支付:用户点击课程详情购买课程后生成微信支付二维码,用户可以通过二维码进行课程的扫码支付。

讲讲Redis,项目中有用过Redis吗?

Redis是一个高性能的内存数据库,以key-value方式存储数据,可以作为缓存使用。

Redis的优点

    性能高(读的速度是110000次/s,写的速度是81000次/s,单机redis支撑万级并发)

    支持多种存储类型

    丰富的特性(发布订阅、事务、过期策略等)

    支持持久化

    单线程 (避免上下文切换,线程同步问题)

数据库建表的时候int(1)和int(2)的区别
在 integer 数据类型中,M 表示最大显示宽度。
在 int(M) 中,M 的值跟 int(M) 所占多少存储空间并无任何关系。 int(3)、int(4)、int(8) 在磁盘上都是占用 4 btyes 的存储空间。说白了,除了显示给用户的方式有点不同外,int(M) 跟 int 数据类型是相同的。

#{}和${}的区别
#{xx}应用PreparedStatement的占位符插入,能防止SQL注入

${xx}应用字符串的拼接,不能防止SQL注入

Springmvc的执行流程

1)用户发送请求

2)前端控制器获得用户请求的URL,发送URL给处理器映射

3)处理器映射将Handler(包装方法信息)返回给前端控制器

4)前端控制器发送Handler给处理器适配器,适配器执行Handler方法

5)执行Handler方法后,返回ModelAndView(逻辑视图)给前端控制器

6)前端控制器将ModelAndView发送给视图解析器,解析出物理视图返回给前端控制器

7)前端控制器渲染视图,发送视图给用户

讲讲ioc
控制反转:一种理论思想,原来的对象由使用者来进行控制,有了spring之后,可以吧对象交给容器进行管理。

DI:依赖注入,把对应的值注入到具体对象中,@Autowired,populateBean完成属性值的注入。

Jvm参数
一、jvm配置参数分为3大类:

1、跟踪参数:跟踪、监控JVM状态,用于程序员JVM调优及故障排查

2、堆分配参数:分配堆内存

3、栈分配参数:分配栈内存

二、各类配置参数常用参数:

1、常用跟踪监控参数:

①打印gc简要信息

第一个:-XX:+PrintGC

第二个:-verbose:gc

这2个参数效果一样,都是在发生gc时,打印gc简要信息的。以

1: [GC (Allocation Failure) 32686K->1648K(123904K), 0.0007230 secs] 2: [GC (Allocation Failure) 34034K->1600K(123904K), 0.0009652 secs]

这个查看结果为例,解释如下:

解释1:总共发生了2次gc,因为打印出的信息标记出了1与2

解释2:以第1次gc为例,32686K表示回收前,对象占用的空间。1648K表示回收后,对象占用的空间。123904K表示还有多少空间可用。0.0007230 secs表示这次垃圾回收花费的时间。

②打印gc详细信息及堆使用详细信息:-XX:+PrintGCDetails

解释1:堆分为新生代、老年代、元空间。

解释2:新生代中又分为伊甸区(eden)和幸存区(from和to)。

解释3:细心的同学可能会发现一种类似于这样的情况:

eden+from+to=65536K+5120K+5120K=75776 并不等于总大小70656K,这是为什么呢?这是因为新生代的垃圾回收算法是采用复制算法,简单的说,就是在from和to之间来回复制(复制过程中再把不可达的对象回收掉),所以必须保证其中一个区是空的,这样才能有预留空间存放复制过来的数据,所以新生代的总大小其实等于eden+from或eden+to=65536K+5120K=70656k。

③将gc日志记录到外部文件中去:-Xloggc:log/gc.log(参数中gc.log就是外部文件的名称)

当java程序出现OOM异常时,总是想查看当时gc的情况,那么使用这个参数记录下gc日志会非常便于故障排查。也可以进行日常JVM监控。

④监控类的加载情况:-XX:+TraceClassLoading

使用这个参数可以监控java程序加载的类。

2、常用堆分配参数

①最大堆:-Xmx,java程序最大能使用多少内存大小,如果超过这个大小,那么java程序会报:out of memory(OOM错误)

②最小堆:-Xms

③指定新生代的内存:-Xmn

④总的堆:目前程序已经配置到的内存大小。一般而言程序一启动,会按照-Xms5m先分配5M的空间,这时总的堆大小就是5M。

⑤空闲堆:程序已经分配的内存大小减去已经使用的内存大小

⑥新生代(eden+from+to)和老年代(不包含永久区)的比值:-XX:NewRatio

Survivor区与Eden区的比值:-XX:SurvivorRatio

这2个比值的计算规则如下:

若-XX:NewRatio=4,则表示新生代:老年代=1:4,那么新生代(eden+from+to)=3072+512+512=4096k,老年代=16384k,新生代:老年代=4096k:16384k=1:4。

若-XX:SurvivorRatio=6,则表示Survivor区:Eden区=2:6,那么Survivor区(from+to)=1024+1024=2048,Eden区=6144,Survivor区:Eden区=2048:6144=2:6,这样的话,一个幸存区占整个新生代区的1:(2+6)=1/8

⑦官方推荐:

新生代占堆的3/8

幸存代占新生代的1/10

⑧发生OOM异常时把堆栈信息打印到外部文件

第1个:-XX:+HeapDumpOnOutOfMemoryError

第2个:-XX:+HeapDumpPath

⑨将堆的最小值-Xms 参数与最大值-Xmx 参数设置为一样即可避免堆自动扩展。因为JVM初始分配的内存由-Xms指定,默认是物理内存的1/64;JVM最大分配的内存由-Xmx指 定,默认是物理内存的1/4。默认空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制;空余堆内存大于70%时,JVM会减少堆直到 -Xms的最小限制。因此服务器一般设置-Xms、-Xmx相等以避免在每次GC 后调整堆的大小。对象的堆内存由称为垃圾回收器的自动内存管理系统回收。

Arraylist和linklist的区别
1、ArrayList的底层结构数组,LinkedList的底层结构双向链表。

2、对于随机访问,ArrayList优于LinkedList

3、对于插入和删除操作,LinkedList优于ArrayList

4、LinkedList比ArrayList更占内存,因为LinkedList的节点除了存储数据,还存储了两个引用,一

个指向前一个元素,一个指向后一个元素。

Arraylist一次扩容多少
扩容1.5倍

Vector是如何实现的安全的
Vector与ArrayList容器的实现原理是一毛一样的,都是封装了一个数组,并且把数组的扩容、缩小交给容器自己管理。不过Vector支持多线程并发访问,因为修改容器的方法都加上了synchronized关键字修饰(this对象锁,锁住整个容器对象)。由于底层是数组,所以随机访问(通过下标访问)效率高,但是在删除节点、插入节点时比较麻烦,删除节点时需要进行大量元素的前移,插入节点时需要进行大量元素的后移,数组容量有限,还需要进行扩容(整个容器中的元素都要复制一遍),效率比较低。

讲讲你知道哪些排序方法,并说下他们的时间复杂度

StringBuild跟StringBuffer的区别
StringBuffer : 对字符串的操作的方法都加了synchronized,保证线程安全。

StringBuilder : 不保证线程安全,在方法体内需要进行字符串的修改操作,可以new StringBuilder

对象,调用StringBuilder对象的append、replace、delete等方法修改字符串。

首先说运行速度,或者说是执行速度,在这方面运行速度快慢为:StringBuilder > StringBuffer

在线程安全上,StringBuilder是线程不安全的,而StringBuffer是线程安全的

StringBuilder:适用于单线程下在字符缓冲区进行大量操作的情况

StringBuffer:适用多线程下在字符缓冲区进行大量操作的情况

HashMap跟HashTable区别
1.Hashtable是线程安全的,HashMap是非线程安全的

2.HashMap的性能高于Hashtable

3.Hashtable不能接收null作为键和值,HashMap可以

4.HashMap可以存null的键值对,hashtable不能,HashMap没有多线程机制,所以多线程不安

全,hashtable有线程锁,是线程安全的,hashtable多线程下,会锁住整个code表,效率很

低,为了提高效率,将code表分成了十二个桶,每次锁时只会锁一个桶,提高了效率

一些常见集合的区别
1.List继承了Collection接口 ,可以添加重复的数据,数据可以通过下标单独访问,数据可以排序

2.Set继承了Collection接口,不能添加重复的数据,数据不能单独访问

3.Map数据以键值对保存,键不能重复,数据可以通过键访问

vue子父项目怎么实现请求同步
父组件通过 props 传入状态给子组件,子组件通过 props 来初始化另外一个内部的状态,子组件每

次更改状态之后都通知父组件,然后由父组件来更改自己的状态,就是 props on emit 的应用

css类选择器
类选择器允许以一种独立于文档元素的方式来指定样式。

该选择器可以单独使用,也可以与其他元素结合使用。

只有适当地标记文档后,才能使用选择器,所以使用这两种选择器通常需要先做一些构想和计划。

要应用样式而不考虑具体设计的元素,最常用的方法就是使用类选择器。

es的使用,为什么要用
Elasticsearch具备以下优点:

    分布式,无需人工搭建集群

    Restful风格,一切API都遵循Rest原则,容易上手

    近实时搜索,数据更新在Elasticsearch中几乎是完全同步的。

正排索引

    通过key找到value,如通过id找到文章

    查询内容时,需要逐条遍历,速度比较慢

倒排索引

    通过value找到key

    对内容进行分词,生成倒排索引

Redis的几种问题跟解决方案
1)缓存击穿

高并发的情况下,短时间内缓存会被穿过,请求直接打到数据库上,可能导致数据库压力过大。

解决方案:对代码上锁(双重检查锁)

2)缓存穿透

高并发的情况下,如果查询不存在的数据,因为缓存和数据库都不存在,请求都会打到数据库上,可能导致系统崩溃。

解决方案:

​ 1) 保存不存在的数据到缓存中,设置一定过期时间

​ 2) 布隆过滤器(直接过滤掉不存在数据的请求) 不能准确判断是否存在数据,能准确判断数据不存在

3)缓存雪崩

高并发的情况下,缓存服务器重启或热点数据同时过期,全部访问数据库,导致数据库宕机

解决方案:

​ 1)配置缓存集群

​ 2)尽量给热点数据设置不一样的过期时间,相对均匀

消息队列的用法
一对一模型:一个生产者发送消息到一个队列,一个消费者从队列中取消息。

工作队列:工作队列,生产者将消息分发给多个消费者,如果生产者生产了100条消息,消费者1消费50条,消费者2消费50条。 生产者

发布/订阅:发布/订阅模式和Work模式的区别是:Work模式只存在一个队列,多个消费者共同消费一个队列中的消息;而发布订阅模式存在多个队列,不同的消费者可以从各自的队列中处理完全相同的消息。

路由:路由模式的消息队列可以给队列绑定不同的key,生产者发送消息时,给消息设置不同的key,这样交换机在分发消息时,可以让消息路由到key匹配的队列中。

主题:主题模式和路由模式差不多,在key中可以加入通配符:

  • * 匹配任意一个单词 com.* ----> com.hopu com.blb com.baidu
  • # 匹配.号隔开的多个单词 com.* —> com.hopu.net com.hopu com.163.xxx.xxx.xxx

常见的设计模式知道几种
装饰者设计模式
开闭原则:程序开发过程中,对功能的扩展开放,对功能的修改关闭,提高程序的稳定性

目的:在不修改原有类的代码基础上,对类的功能进行扩展

在Java的IO包下,大量应用了装饰者模式

实现

    1.装饰者和被装饰者都要实现相同的接口或继承相同的父类

    2.装饰者中定义一个被装饰者的对象

    3.给装饰者传入被装饰者对象

    4.调用装饰者的方法时,也调用被装饰者的方法,同时进行功能的扩展

单例设计模式
目的:保证一个类只有一个实例(对象)

应用场景:

对于某些大的对象,单例模式能节省系统资源

应用某些特定业务需求,如:保证公司只有一个CEO

实现 PS : Runtime类就是单例模式的

将所有构造方法定义为private

在类中创建一个静态的对象

在类中定义一个静态方法来返回该对象

两种单例模式

饿汉式:类中一开始就创建对象,不管后面是否使用对象,都消耗了内存。

懒汉式:类中一开始不创建对象,调用返回对象方法时再创建对象。

代理模式
代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。

代理模式的作用

代理模式的作用

1)中介的作用,当调用者不能或不方便调用某个对象时,代理起到中介的作用,帮助调用者间接

的调用对象。

2)符合开闭原则,在不修改原有类代码的前提下,对类的功能进行增强。

代理模式的分类

代理模式分为两种:

1) 静态代理,在运行前,通过编写代码的方式生成代理类

2) 动态代理,在运行后,通过反射机制生成代理类

静态代理

1)代理者和被代理者都实现相同的接口

2)代理者包含被代理者的对象

3)创建代理对象时传入被代理对象

4)代理者执行方法时,会调用被代理者的方法,同时扩展新的功能

静态代理的问题:一个代理类只能代理一种业务,如果有多种业务,就必须创建大量的代理类。

动态代理

和静态代理不同,动态代理是在运行时,通过反射机制动态生成代理类。开发者不需要手动编写新

的代理类。

动态代理分类

JDK动态代理

JDK自带的,前提是:被代理类必须实现过接口。

实现步骤

1) 实现InvocationHandler接口

2)实现invoke方法

3)通过Proxy.newProxyInstance方法返回代理对象

CGLib动态代理

需要引入CGLib依赖,它的原理是:通过反射+继承机制动态生成被代理类的子类,所以被代理类

不能是final的。

实现步骤

1)引入cglib

2)实现MethodInterceptor接口

3)实现intercept方法

4)通过Ehancer返回代理对象

Spring跟SpringCloud区别
Spring 框架就像一个家族,有众多衍生产品例如 boot、security、jpa等等。但他们的基础都

是Spring的ioc、aop等. ioc 提供了依赖注入的容器, aop解决了面向横切面编程,然后在此两者的

基础上实现了其他延伸产品的高级功能;

    Spring 框架就像一个家族,有众多衍生产品例如 boot、security、jpa等等。但他们的基础都

是Spring的ioc、aop等. ioc 提供了依赖注入的容器, aop解决了面向横切面编程,然后在此两者的

基础上实现了其他延伸产品的高级功能;

vue的生命周期
Vue 的生命周期总共分为8个阶段:创建前/后,载入前/后,更新前/后,销毁前/后。

1、beforeCreate(创建前)

表示实例完全被创建出来之前,vue 实例的挂载元素$el和数据对象 data 都为 undefined,还未初

始化。

2、created(创建后)

数据对象 data 已存在,可以调用 methods 中的方法,操作 data 中的数据,但 dom 未生成,$el

未存在 。

3、beforeMount(挂载前)

vue 实例的 $el 和 data 都已初始化,挂载之前为虚拟的 dom节点,模板已经在内存中编辑完成

了,但是尚未把模板渲染到页面中。data.message 未替换。

4、mounted(挂载后)

vue 实例挂载完成,data.message 成功渲染。内存中的模板,已经真实的挂载到了页面中,用户

已经可以看到渲染好的页面了。实例创建期间的最后一个生命周期函数,当执行完 mounted 就表

示,实例已经被完全创建好了,DOM 渲染在 mounted 中就已经完成了。

5、beforeUpdate(更新前)

当 data 变化时,会触发beforeUpdate方法 。data 数据尚未和最新的数据保持同步。

6、updated(更新后)

当 data 变化时,会触发 updated 方法。页面和 data 数据已经保持同步了。

7、beforeDestory(销毁前)

组件销毁之前调用 ,在这一步,实例仍然完全可用。

8、destoryed(销毁后)

组件销毁之后调用,对 data 的改变不会再触发周期函数,vue 实例已解除事件监听和 dom绑定,

但 dom 结构依然存在。

List去重,返回去重结果
使用java8新特性stream进行List去重
双重for循环去重
set集合判断去重,不打乱顺序
遍历后判断赋给另一个list集合
set和list转换去重

jq选择器,如何选中元素
JQuery特有的过滤选择器

1) 基本过滤选择器 2)内容过滤选择器 3)可见过滤选择器 4) 属性过滤选择器

5) 子标签过滤选择器 6) 表单属性过滤选择器 7) 表单元素过滤选择器

Spring事务配置的具体流程
(1)事务的传播性:@Transactional(propagation=Propagation.REQUIRED)

  如果有事务, 那么加入事务, 没有的话新建一个(默认情况下)

(2)事务的超时性:@Transactional(timeout=30) //默认是30秒

  注意这里说的是事务的超时性而不是Connection的超时性,这两个是有区别的

(3)事务的隔离级别:@Transactional(isolation = Isolation.READ_UNCOMMITTED) ,未提交

读,就是一个事务可以读取另一个未提交事务的数据。读取未提交数据(会出现脏读, 不可重复读)

基本不使用;

@Transactional(isolation = Isolation.READ_COMMITTED),已提交读,就是一个事务要等另

一个事务提交后才能读取数据。可以解决脏读,可能会出现不可重复读问题;

@Transactional(isolation = Isolation.REPEATABLE_READ),重复读,就是在开始读取数据

(事务开启)时,不再允许修改操作,重复读可以解决不可重复读问题。不可重复读对应的是修

改,即UPDATE操作。但是可能还会有幻读问题。因为幻读问题对应的是插入INSERT操作,而不

是UPDATE操作。

@Transactional(isolation = Isolation.SERIALIZABLE) ,是最高的事务隔离级别,在该级别下,

事务串行化顺序执行,可以避免脏读、不可重复读与幻读。但是这种事务隔离级别效率低下,比较

耗数据库性能,一般不使用。

面向对象6大原则
1)单一职责原则,一个合理的类,应该仅有一个引起它变化的原因,即单一职责,就是设计的这个类

功能应该只有一个;

优点:消除耦合,减小因需求变化引起代码僵化。

  1. 开-闭原则,讲的是设计要对扩展有好的支持,而对修改要严格限制。即对扩展开放,对修改封

闭。

优点:降低了程序各部分之间的耦合性,其适应性、灵活性、稳定性都比较好。当已有软件系

统需要增加新的功能时,不需要对作为系统基础的抽象层进行修改,只需要在原有基础上附加新的

模块就能实现所需要添加的功能。增加的新模块对原有的模块完全没有影响或影响很小,这样就无

须为原有模块进行重新测试。

  1. 里氏代换原则,很严格的原则,规则是“子类必须能够替换基类,否则不应当设计为其子类。”也

就是说,一个软件实体如果使用的是一个父类的话,那么一定适用于其子类,而且它察觉不出父类

对象和子类对象的区别。也就是说,在软件里面,把父类都替换成它的子类,程序的行为没有变

化。

优点:可以很容易的实现同一父类下各个子类的互换,而客户端可以毫不察觉。

  1. 依赖倒换原则,“设计要依赖于抽象而不是具体化”。换句话说就是设计的时候我们要用抽象来思

考,而不是一上来就开始划分我需要哪些哪些类,因为这些是具体。

高层模块不应该依赖低层模块,它们都应该依赖抽象。抽象不应该依赖于细节,细节应该依赖于抽象。

另一种表述为: 要针对接口编程,不要针对实现编程。

优点:人的思维本身实际上就是很抽象的,我们分析问题的时候不是一下子就考虑到细节,而

是很抽象的将整个问题都构思出来,所以面向抽象设计是符合人的思维的。另外这个原则会很好的

支持(开闭原则)OCP,面向抽象的设计使我们能够不必太多依赖于实现,这样扩展就成为了可

能,这个原则也是另一篇文章《Design by Contract》的基石。

  1. 接口隔离原则,“将大的接口打散成多个小接口”,让系统解耦,从而容易重构,更改和重新部

署。

优点:会使一个软件系统功能扩展时,修改的压力不会传到别的对象那里。

  1. 迪米特法则或最少知识原则,这个原则首次在Demeter系统中得到正式运用,所以定义为迪米特

法则。它讲的是“一个对象应当尽可能少的去了解其他对象”。

优点:消除耦合。

RabbitMQ的用途
1)解耦

服务之间进行解耦,A服务调用B服务时,需要编写相关的代码,调用情况发生改变时,需要修改

调用的代码

2)异步

传统的同步调用方式,需要等待调用完成,才能进行其它业务

异步调用方法,将消息发送到队列中,就可以返回,执行其它业务,速度大大提升

3)削峰

出现流量激增的情况时,消息队列可以设置消息的最大数量,处理一部分消息,其它消息交给队列

排队处理

创建线程的三种方式
1.继承Thread类

2.实现Runnable接口

3.实现Callable接口

线程中常用的方法
start() 启动
stop() 停止(禁用,可能导致线程死锁等问题),停止线程可以让run执行结束
String getName() 获得线程的名字
setName(String) 设置线程名字
sleep(long) 进入睡眠,毫秒
setPriority(int) 设置线程的优先级(1~10从低到高)越高抢CPU几率更高
setDaemon(boolean) 设置为后台线程 true ,后台线程是为其它线程服务的,如果没有其它线程存在,就自动死亡;使用案例:GC就是一种后台线程
join() 线程的加入(合并)让其它线程先执行完,再执行自己的指令

Jdk8比以前有什么新特性
函数式接口,Lambda表达式,方法引用,Stream接口, Optional类等。

Elasticsearch用的什么查询
1 term查询(精准查询)

term是ES中的精准查询,不会参与ES分词查询。

2 math查询(分词匹配查询)

match查询是按ES分词的倒排表进行查询,而keyword不会被分词,match的需要跟keyword的完全匹配可以。可以用于一般性的匹配查询。

3 fuzzy查询(模糊查询)

fuzzy查询可以用于纠正去拼写的问题,fuzziness是可以允许纠正错误拼写的个数

4 wildcard(通配符查询)

通配符查询允许我们指定一个模式来匹配,而不需要指定完整的trem,匹配的方式类似于match的

分词匹配查询。

?将会匹配如何字符;*将会匹配零个或者多个字符。

5 bool查询(布尔查询)

bool查询本身没有查询功能,而是基于逻辑值使用前面几种查询方式进行组合查询。

SpringBoot有什么注解
1、@SpringBootApplication

替代 @SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan

2、@ImportAutoConfiguration

导入配置类,一般做测试的时候使用,正常优先使用@EnableAutoConfiguration

3、@SpringBootConfiguration

替代@Configuration

4、@ImportResource

将资源导入容器

5、@PropertySource

导入properties文件

6、PropertySources

@PropertySource 的集合

7、@Role

bean角色定义为ROLE_APPLICATION(默认值)、ROLE_SUPPORT(辅助角色)、ROLE_INFRASTRUCTURE(后台角色,用户无感)
8、@Scope

指定bean的作用域,默认singleton,其它包括prototype、request、session、globalSession

9、@Lazy

使bean懒加载,取消bean预初始化。

10、@Primary

自动装配时当出现多个Bean候选者时,被注解为@Primary的Bean将作为首选者,否者将抛出异常。

11、@Profile

指定Bean在哪个环境下被激活

12、@DependsOn

依赖的bean注册完成,才注册当前类,依赖bean不存在会报错。用于控制bean加载顺序

13、@PostConstruct

bean的属性都注入完毕后,执行注解标注的方式进行初始化工作

14、@Autowired

默认按类型装配,如果我们想使用按名称装配,可以结合@Qualifier注解一起使用。

15、@Lookup

根据方法返回的类型,去容器中捞出对应

16、@Qualifier

申明bean名字,且可以按bean名字加载bean

17、@Required

检查bean的属性setXXX()方法,要求属性砸死配置阶段必须已配置

18、@Description

添加bean的文字描述

19、@EnableAspectConfiguration

启动AspectJ自动配置

20、EnableLoadTimeWeaving

启动类加载器动态增强功能,使用instrumentation实现

21、@AutoConfigurationPackage

包含该注解的package会被AutoConfigurationPackages注册

22、@AutoConfigureBefore

在指定配置类初始化前加载

23、@AutoConfigureAfter

在指定配置类初始化后加载

24、@AutoConfigureOrder

指定配置类初始化顺序,越小初始化越早

25、@ModelAttribute

@ModelAttribute注解可被应用在方法和方法参数上。

HashMap+List什么时候触发红黑树
情况一:链表长度到满足8,先尝试转红黑树

情况二:校验数组长度满足64

MIN_TREEIFY_CAPACITY:64

调用treeifyBin()的方法,先判断数组长度是否小于64,小于则进行扩容;否则,转红黑树。

面向对象的理解
万物皆对象,对象是一类事物的抽象。

封装性:封装是一种信息隐蔽技术,它体现于类的说明,是对象的重要特性。封装使数据和加工该

数据的方法(函数)封装为一个整体,以实现独立性很强的模块,使得用户只能见到对象的外特性

(对象能接受哪些消息,具有那些处理能力),而对象的内特性(保存内部状态的私有数据和实现

加工能力的算法)对用户是隐蔽的。封装的目的在于把对象的设计者和对象者的使用分开,使用者

不必知晓行为实现的细节,只须用设计者提供的消息来访问该对象。

继承性:继承性是子类自动共享父类之间数据和方法的机制。它由类的派生功能体现。一个类直接

继承其它类的全部描述,同时可修改和扩充。继承具有传递性。继承分为单继承(一个子类只有一

父类)和多重继承(一个类有多个父类)。类的对象是各自封闭的,如果没继承性机制,则类对象

中数据、方法就会出现大量重复。继承不仅支持系统的可重用性,而且还促进系统的可扩充性。

可以将子类的对象赋值给父类的引用,可以将子类对象当做父类来使用,从而屏蔽不同对象之间的

差异,可以写出更加通用和灵活的代码,以适应不同的业务需求。

多态性:对象根据所接收的消息而做出动作。同一消息为不同的对象接受时可产生完全不同的行

动,这种现象称为多态性。利用多态性用户可发送一个通用的信息,而将所有的实现细节都留给接

受消息的对象自行决定,如是,同一消息即可调用不同的方法。例如:Print消息被发送给一图或表

时调用的打印方法与将同样的Print消息发送给一正文文件而调用的打印方法会完全不同。多态性的

实现受到继承性的支持,利用类继承的层次关系,把具有通用功能的协议存放在类层次中尽可能高

的地方,而将实现这一功能的不同方法置于较低层次,这样,在这些低层次上生成的对象就能给通

用消息以不同的响应。在OOPL中可通过在派生类中重定义基类函数(定义为重载函数或虚函数)

来实现多态性。

Linux常用命令
切换目录
cd 目录名
查看目录
ls 目录名(不写就是查看当前目录)
-l 详细列表
-a 所有文件
查看目录详情
ll 目录名

创建目录
mkdir 目录名
删除目录
rm 目录名
-r 遍历所有子目录
-f 强制删除

创建\打开文件
vi 文件名
三种模式:
命令模式 能删除、复制、粘贴,无法编辑
输入模式 编辑内容
命令行模式 退出、保存文件
操作方式:默认进入命令模式,按i进入输入模式,按esc回到命令模式,按:进入命令行模式
命令模式
x 删除一个字符
dd 删除一行
yy 复制一行
p 粘贴
u 撤销
命令行模式
wq 保存退出
q 退出 (如果有修改,此方式退出会出错)
q! 强制退出

cat 显示整个文件内容(不支持分页)
more 分页显示(只能向前分页查询)
less 分页显示,功能比more强大。(支持前后分页查询)
支持文本查找,/查找内容 向下查询 ; ?查找内容 向上查找内容
退出less模式,点击q

对比vi命令:cat、more、less仅仅是用来进行文本阅读命令,vi用来进行文本编辑的命令。

查询当前文件中是否包含有java单词,如果包含有Java单词的所有行全部显示出来。
cat 文件名 | grep 查询文字

find 查找目录 -name 文件名称
find 查找目录 | grep 名称

which 命令名称

移动文件
mv 原文件 目标文件
复制文件
cp 原文件 目标文件

解压指令:tar -zxvf
压缩指令:tar -zcvf
-z:表示压缩和解压缩的格式为gz压缩文件(gzip)
-c::表示压缩
-x:表示解压缩
-v:表示显示压缩或者解压缩的详细过程。
-f:表示指定压缩或者解压缩的文件,只能放在命令的最后
tar -zcvf demo.tar.gz demo2.txt
tar -cvf 压缩后的文件名称 待压缩的文件
tar -xvf 待解压的解压包名

通过端口查看进程:netstat –apn | grep 8080
通过端口查看进程:lsof -i:3306
通过进程名称查询进程:ps -ef | grep redis
杀死进程:kill -9 PID(进程ID,-9表示强制杀死)

CSS有哪些选择器
1、标签选择器 以标签名开头,选择所有div元素

2、类选择器 给标签取class名,以点(.)加class名开头,选择所有该class名的元素

3、id选择器 给标签取id名,以#加id名开头,具有唯一性,选择”id = ‘wrap’”的元素

4、子选择器 以>隔开父子级元素,(模块名>模块名,修饰>前模块内的子模块)

5、包含选择器 以空格隔开包含关系的元素,(模块名模块名,修饰空格前模块内所有该模块)

6、兄弟选择器 以隔开兄弟关系的元素(模块名模块名 修饰~前模块往下的所有兄弟模块)

7、相邻选择器 以+隔开相邻关系的元素(模块名+模块名 修饰加号前模块往下的相邻的模块 只一个)

8、全局选择器 以*开头(星号标在大括号前,修饰了包含body所有的标签)

9、群选择器 以,分隔(逗号分隔开需要修饰的模块名)

10、属性选择器 [] ([type=text]修饰属性为type=text的模块)

11、伪类选择器

(1) li:first-child{} (修饰第一个li)        修饰第一个li元素

(2) li:last-child{} (修饰最后一个li)        修饰最后一个li元素

(3) li:nth-child{} (修饰第()个li)        修饰第二个li元素

(4) li:not(){} (不修饰第()个li,括号里面可以填以上的选择器)

Radis怎么实现数据同步
Redis的主从同步机制可以确保redis的master和slave之间的数据同步。按照同步内容的多少可以分

为全同步和部分同步;按照同步的时机可以分为slave刚启动时的初始化同步和正常运行过程中的

数据修改同步;本文将对这两种机制的流程进行分析。
全备份过程中,在slave启动时,会向其master发送一条SYNC消息,master收到slave的这条消息

之后,将可能启动后台进程进行备份,备份完成之后就将备份的数据发送给slave,初始时的全同

步机制是这样的:
(1)slave启动后向master发送同步指令SYNC,master接收到SYNC指令之后将调用该命令的处

理函数syncCommand()进行同步处理;
(2)在函数syncCommand中,将调用函数rdbSaveBackground启动一个备份进程用于数据同

步,如果已经有一个备份进程在运行了,就不会再重新启动了。
(3)备份进程将执行函数rdbSave() 完成将redis的全部数据保存为rdb文件。
(4)在redis的时间事件函数serverCron(redis的时间处理函数是指它会定时被redis进行操作的函

数)中,将对备份后的数据进行处理,在serverCron函数中将会检查备份进程是否已经执行完毕,

如果备份进程已经完成备份,则调用函数backgroundSaveDoneHandler完成后续处理。
(5)在函数backgroundSaveDoneHandler中,首先更新master的各种状态,例如,备份成功还是

失败,备份的时间等等。然后调用函数updateSlavesWaitingBgsave,将备份的rdb数据发送给等

待的slave。
(6)在函数updateSlavesWaitingBgsave中,将遍历所有的等待此次备份的slave,将备份的rdb文

件发送给每一个slave。另外,这里并不是立即就把数据发送过去,而是将为每个等待的slave注册

写事件,并注册写事件的响应函数sendBulkToSlave,即当slave对应的socket能够发送数据时就调

用函数sendBulkToSlave(),实际发送rdb文件的操作都在函数sendBulkToSlave中完成。
(7)sendBulkToSlave函数将把备份的rdb文件发送给slave。

Vue怎么实现中英文切换,用什么实现
一、安装 vue-i18n插件

二、main.js文件的配置

三、定义两套中英文的 js 文件,并通过 require 的形式引入到 main.js。
在 main.js 中的代码中,可以看到,当 locale 的值为‘zh-CN’时,版本为中文;当 locale 的值为‘en-

US’,版本为英文。当然你也可以换成 zh 和 en,这个自定义就好,对应上就可以。
四、绑定点击事件,来修改 locale 的值去调用对应的语言包实现语种切换。

五、vue-i18n 数据渲染的模板语法

我们知道 vue 中对于文字数据的渲染,有以‘’{{}}‘’或者 v-text、v-html等的形式,同样的使用国际化

后,依旧可以沿用,但需要一点修改。

MySQL跟Oracle的区别
一、宏观上:
1、Oracle是大型的数据库而Mysql是中小型数据库;Mysql是开源的,Oracle是收费的,且价格昂贵。

2、Oracle支持大并发,大访问量,是OLTP的最好的工具。

3、安装占用的内存也是有差别,Mysql安装完成之后占用的内存远远小于Oracle所占用的内存,并且Oracle越用所占内存也会变多。

二、微观上:
1、对于事务的支持

Mysql对于事务默认是不支持的,只是有某些存储引擎中如:innodb可以支持;而Oracle对于事物

是完全支持的。

2、并发性

什么是并发性?并发性是OLTP(On-Line Transaction Processing联机事务处理过程)数据库最重要

的特性,并发性涉及到资源的获取、共享与锁定。

Mysql,既支持表锁,也支持行级锁。表锁,对资源锁定的力度很大,如果一个session对一个表加

锁时间过长,会让其他session无法更新此表的数据。

Oracle使用行级锁,对资源锁定的力度要小很多,只是锁定sql需要的资源,并且加锁是在数据库

中的数据行上,不依赖于索引。所以oracle对并发性的支持要好很多。

3、数据的持久性

Oracle保证提交的事务均可以恢复,因为Oracle把提交的sql操作线写入了在线联机日志文件中,

保存到磁盘上,如果出现数据库或者主机异常重启,重启Oracle可以靠联机在线日志恢复客户提交

的数据。

Mysql默认提交sql语句,但是如果更新过程中出现db或者主机重启的问题,也可能会丢失数据。

4、事务隔离级别

MySQL是repeatable read的隔离级别,而Oracle是read commited的隔离级别,同时二者都支持

serializable串行化事务隔离级别,可以实现最高级别的。

读一致性。每个session提交后其他session才能看到提交的更改。Oracle通过在undo表空间中构造

多版本数据块来实现读一致性,每个session 查询时,如果对应的数据块发生变化,Oracle会在

undo表空间中为这个session构造它查询时的旧的数据块。

MySQL没有类似Oracle的构造多版本数据块的机制,只支持read commited的隔离级别。一个

session读取数据时,其他session不能更改数据,但可以在表最后插入数据。session更新数据

时,要加上排它锁,其他session无法访问数据

5、提交方式

Oracle默认不自动提交,需要手动提交。Mysql默认自动提交。

6、逻辑备份

Mysql逻辑备份是要锁定数据,才能保证备份的数据是一致的,影响业务正常的DML(数据操纵语言

Data Manipulation Language)使用;Oracle逻辑备份时不锁定数据,且备份的数据是一致的。

7、sql语句的灵活性

mysql对sql语句有很多非常实用而方便的扩展,比如limit功能(分页),insert可以一次插入多行数

据;Oracle在这方面感觉更加稳重传统一些,Oracle的分页是通过伪列和子查询完成的,插入数据

只能一行行的插入数据。

8、数据复制

MySQL:复制服务器配置简单,但主库出问题时,丛库有可能丢失一定的数据。且需要手工切换

丛库到主库。

Oracle:既有推或拉式的传统数据复制,也有dataguard的双机或多机容灾机制,主库出现问题

是,可以自动切换备库到主库,但配置管理较复杂。

9、分区表和分区索引

MySQL的分区表还不太成熟稳定;Oracle的分区表和分区索引功能很成熟,可以提高用户访问db

的体验。

10、售后与费用

Oracle是收费的,出问题找客服;Mysql是免费的的,开源的,出问题自己解决。

11、权限与安全

Oracle的权限与安全概念比较传统,中规中矩;MySQL的用户与主机有关,感觉没有什么意义,

另外更容易被仿冒主机及ip有可乘之机。

12、性能诊断方面

Oracle有各种成熟的性能诊断调优工具,能实现很多自动分析、诊断功能。比如awr、addm、

sqltrace、tkproof等 ;MySQL的诊断调优方法较少,主要有慢查询日志。

在jdbc中是使用什么实现占位符
Statement和PreparedStatement

Statement 接口的两个问题:
  第一个问题: 使用 Statement 接口 对象发送的 sql 语句需要再数据库进行一次编译之后成为指令才能执行,
       每条 sql 语句都需要编译一次, 这样是很慢的.
  第二个问题: 使用 Statement 接口 操作的 sql 语句需要使用字符串的拼接方式实现,
        这样的方式可能存在 sql 注入的安全风险并且拼接字符串比较麻烦.

对比 Statement 接口, PreparedStatement 接口的优点:
  1.使用该接口操作的 sql 语句会先预先编译成指令在发送给数据库, 数据库就执行指令即可, 这样就提高了一定速度,
  2.该接口可以避开 sql 需要使用字符串拼接的方式, 从而解决 sql 注入的安全风险,
  而是使用占位符 (?) 来代替原来的字符串拼接.

MyBaits常用注解
@Insert : 实现新增
@Update: 实现更新
@Delete:实现删除
@Select:实现查询
@Result:
实现结果集封装
@Results:
可以与@Result 一起使用,封装多个结果集
@ResultMap:
实现引用@Results 定义的封装
@One:
实现一对一结果集封装
@Many:
实现一对多结果集封装

@CacheNamespace:
实现注解二级缓存的使用
复杂关系映射的注解说明
@Results 注解
代替的是标签
@Resutl 注解
代替了 标签和 标签
@One 注解(一对一)
代替了 标签,是多表查询的关键,在注解中用来指定子查询返回单一对象
@Many 注解(多对一)
代替了 标签,是多表查询的关键,在注解中用来指定子查询返回单一对象

Redis的执行原理
redis服务器对命令的处理都是单线程的,但是I/O层面却面向多个客户端并发地提供服务,并发到

内部单线程的转化通过多路复用框架来实现
首先从多路服用框架(epoll、evport、kqueue)中select出已经ready的文件描述符

(fileDescriptor)
ready的标准是已有数据到达内核(kernel)、已准备好写入数据
对于上一步已经ready的fd,redis会分别对每个fd上已ready的事件进行处理,处理完相同fd上的所

有事件后,再处理下一个ready的fd。有3中事件类型
acceptTcpHandler:连接请求事件
readQueryFromClient:客户端的请求命令事件
sendReplyToClient:将暂存的执行结果写回客户端
对来自客户端的命令执行结束后,接下来处理定时任务(TimeEvent)
aeApiPoll的等待时间取决于定时任务处理(TimeEvent)逻辑
本次主循环完毕,进入下一次主循环的beforeSleep逻辑,后者负责处理数据过期、增量持久化

索引的作用
优点:加快查询速度,用户查询时,先找索引,通过索引找到实际数据的位置,再直接定位到实际数据上,极大提高查询速度

缺点: 1. 也是数据,需要占存储空间
2. 降低增删改的速度
3. 创建索引也需要一定的时间

sleep和wait的区别
调用对象不同

wait() 由锁对象调用

sleep() 由线程调用

锁使用不同

执行wait后,自动释放锁

执行sleep后,不会释放锁

唤醒机制不同

执行wait后,可以被通知唤醒

执行sleep后,只能等待时间结束后,自动唤醒

深复制和浅复制的区别
浅复制:复制出来的对象,能复制所有基本类型以及String的属性,对于引用类型的属性只能复制地址

深复制:复制出来的对象,基本类型和引用类型的属性,都完全是不同的对象

实现方式:序列化和反序列化

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值