0
点赞
收藏
分享

微信扫一扫

面试题整理1

伢赞 2022-01-26 阅读 90
java

数据库语句是如何优化的?

1.查询 SQL 尽量不要使用 select *,而是 select 具体字

2.如果知道查询结果只有一条或者只要最大/最小一条记录,建议用 limit 1

3.应尽量避免在 where 子句中使用 or 来连接条件

4.优化 limit 分页

5.优化 like 语句

6.使用 where 条件限定要查询的数据,避免返回多余的行

7.尽量避免在索引列上使用 MySQL 的内置函数

8.应尽量避免在 where 子句中对字段进行表达式操作,这将导致系统放弃使用索引而进行全表扫

9.Inner join 、left join、right join,优先使用 Inner join,如果是 left join,左边表结果尽量小

10.应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描

11.使用联合索引时,注意索引列的顺序,一般遵循最左匹配原则

12.对查询进行优化,应考虑在 where 及 order by 涉及的列上建立索引,尽量避免全表扫描

13.如果插入数据过多,考虑批量插入

14.在适当的时候,使用覆盖索引

15.慎用 distinct 关键字

16.删除冗余和重复索引

17.如果数据量较大,优化你的修改/删除语句

18.where 子句中考虑使用默认值代替 null

19.不要有超过 5 个以上的表连接

20.exist&in 的合理利用

21.尽量用 union all 替换 union

22.索引不宜太多,一般 5 个以内

23.尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型

24.索引不适合建在有大量重复数据的字段上,如性别这类型数据库字段

25.尽量避免向客户端返回过多数据量

26.当在 SQL 语句中连接多个表时,请使用表的别名,并把别名前缀于每一列上,这样语义更加清晰

27.尽可能使用 varchar/nvarchar 代替 char/nchar

28.为了提高 group by 语句的效率,可以在执行到该语句前,把不需要的记录过滤掉

29.如果字段类型是字符串,where 时一定用引号括起来,否则索引失效

30.使用 explain 分析你 SQL 的计划

使用SpringBoot的时候各种配置文件是怎么引入的

自动配置类是什么时候导入内存的     启动类上的注解:@SpringBootApplication

包含三个注解:

     1.@ComponentScan 包的扫描

     2.@SpringBootConfiguration 定义配置类

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

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

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

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

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

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

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

说说你做过的项目和你主要负责的模块

聪优课堂是迎合当今互联网教育市场,让相关专业学生系统的学习知识体系,系统采用分布式架构

设计,主要模块有搜索,广告、登录、课程、订单、支付、评论等模块。

项目职责:

1.搜索功能:调用课程服务查询到数据库的信息导入到Elasticsearch中,通过用户选择的过滤条件

和当前参数,通过布尔查询对多个条件进行过滤,处理结果查询。

2.解决数据同步问题:当对数据库进行增删改操作,使用RabbitMQ消息队列同步到Elasticsearch

3.登录模块:用户认证通过后,采用JWT和RSA加密算法,生成token,做到每次请求都携带JWT token,实现单点登录。

4.订单模块:使用Sharding-Sphere进行分库分表,通过Seata解决分库分表带来分布式事务问题。

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

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

高并发        MySQL的连接数存在瓶颈,连接过大可能导致MySQL宕机

解决方法        部署多个MySQL服务,主从复制        部署缓存,承担一部分的并发

高性能         基于内存,内存IO效率远远高于磁盘

Redis的特点

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

        支持多种存储类型

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

        支持持久化

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

查询数据和解决消息幂等性时使用

数据库建表的时候int(1)和int(2)的区别

这个int(M)我们可以简单的理解为:

这个长度是为了告诉MYSQL数据库,我们这个字段的存储的数据的宽度为M位数, 当然如果你不是

M位数(只要在该类型的存储范围之内)MYSQL也能正常存储。

设置这个属性后往表时插入数据,系统会自动把uid字段M不够3位的在左侧用0来填充。

#和$的区别

#{xx}应用PreparedStatement的占位符?插入,能防止SQL注入

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

Springmvc的执行流程

1)用户发送请求

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

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

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

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

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

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

讲讲ioc

IOC(Inverse of Control)控制反转是一种程序设计思想

控制是什么        JavaBean(Java对象)的创建和管理

反转是什么        一般情况下对象的创建和管理由开发者控制,反转是把对象的创建和管理交给容器完成,然后再交给开发者。

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]

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

③将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

⑦官方推荐:

新生代占堆的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 后调整堆的大小。对象的堆内存由称为垃圾回收器的自动内存管理系统回收。

3、常用栈分配参数

①栈大小参数为-Xss

栈大小通常只有几百k,决定于函数调用的深度。每个线程都有自己独立的栈空间(私有栈空间,

不共享)。如果函数调用太深,超过了栈的大小,则会抛出java.lang.StackOverflowError。遇到这

种错误,通常情况下,不是去调整-Xss参数,而是应该去检查是否是函数调用太深导致的,是否使

用了递归,能不能保证递归出口等。

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和set是实现了collection接口的。

2、list可以允许重复的对象。可以插入多个null元素。是一个有序容器,保持了每个元素的插入顺

序,输出的顺序就是插入的顺序。Set不允许重复对象,无序容器,你无法保证每个元素的存储顺

序,TreeSet通过 Comparator 或者 Comparable 维护了一个排序顺序。只允许一个 null 元素。

3、Map不是collection的子接口或者实现类。Map是一个接口。Map 的 每个 Entry 都持有两个对

象,也就是一个键一个值,Map 可能会持有相同的值对象但键对象必须是唯一的。TreeMap 也通

过 Comparator 或者 Comparable 维护了一个排序顺序。Map 里你可以拥有随意个 null 值但最多

只能有一个 null 键。

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条。

实现能者多劳:

  1. channel.basicQos(1);限制队列一次发一个消息给消费者,等消费者有了反馈,再发下一条

  2. channel.basicAck 消费完消息后手动反馈,处理快的消费者就能处理更多消息

  3. basicConsume 中的参数改为false

发布/订阅模式和Work模式的区别是:Work模式只存在一个队列,多个消费者共同消费一个队列中

的消息;而发布订阅模式存在多个队列,不同的消费者可以从各自的队列中处理完全相同的消息。

1) 创建交换机(Exchange)类型是fanout(扇出)

2) 交换机需要绑定不同的队列

3) 不同的消费者从不同的队列中获得消息

4) 生产者发送消息到交换机

5) 再由交换机将消息分发到多个队列

路由模式的消息队列可以给队列绑定不同的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.调用装饰者的方法时,也调用被装饰者的方法,同时进行功能的扩展

单例设计模式

目的:保证一个类只有一个实例(对象)

应用场景:

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

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

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

  1. 将所有构造方法定义为private

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

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

两种单例模式

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

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

代理模式

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

代理模式的作用

代理模式的作用

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)单一职责原则,一个合理的类,应该仅有一个引起它变化的原因,即单一职责,就是设计的这个类

功能应该只有一个;

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

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

闭。

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

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

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

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

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

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

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

化。

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

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

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

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

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

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

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

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

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

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

署。

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

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

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

优点:消除耦合。

RabbitMQ的用途

1)解耦

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

调用的代码

2)异步

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

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

3)削峰

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

排队处理

创建线程的三种方式

继承Thread类

1.继承Thread类        2.重写run方法        3.调用start启动线程

实现Runnable接口

1.实现Runnable接口        2.实现run方法

3.创建实现Runnable接口的对象,传入Thread对象中        4.启动线程

实现Callable接口

1.实现Callable接口,实现call方法        2.创建Callable对象,传入FutureTask对象

3.创建FutureTask对象,传入Thread对象        4.启动线程

5.调用get方法得到返回结果

线程中常用的方法

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

Jdk8比以前有什么新特性

java8的新特性还是比较多的如:函数式接口,Lambda表达式,方法引用,Stream接口, Optional类等。

elasticsearch用的什么查询

ElasticSearch常用的几种查询方式,terms 查询是term的扩展,可以支持多个vlaue匹配,只需要一个匹配就可以了。

1 term查询(精准查询)

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

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

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

3 fuzzy查询(模糊查询)

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

4  wildcard(通配符查询)

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

分词匹配查询。

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

5 bool查询(布尔查询)

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

Spring boot有什么注解

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,小于则进行扩容;否则,转红黑树。

面向对象的理解

  • 装(把代码装起来,把一个类相关的属性和方法装起来,将一些代码装到方法中,方便调用)

  • 封(信息的隐藏,将某些属性和方法隐藏起来,提供公开的属性和方法供调用者使用)

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

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

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

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

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

  1. 子类能够继承父类的属性和方法,实现了代码的重用

  2. 多个类具有相同的属性和方法,提取出来放到共同的父类

  3. 提升了代码重用性、可维护性和可扩展性

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

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

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

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

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

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

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

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

受消息的对象自行决定,如是,同一消息即可调用不同的方法。例如: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 接口的两个问题:
  第一个问题: 使用 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 注解
    代替的是标签<resultMap>
@Resutl 注解
    代替了 <id> 标签和<result> 标签
@One 注解(一对一)
    代替了<assocation> 标签,是多表查询的关键,在注解中用来指定子查询返回单一对象
@Many 注解(多对一)
    代替了<assocation> 标签,是多表查询的关键,在注解中用来指定子查询返回单一对象

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逻辑,后者负责处理数据过期、增量持久化的文件写入等任务

spring的事务

Spring中隔离级别的配置

@Transactional注解的属性isolation

值:

  1. Isolation.DEFAULT 默认,和数据库隔离级别一致

  2. Isolation.Readuncommitted 读未提交

  3. Isolation.Readcommitted 读已提交

  4. Isolation.Repeatableread 可重复读

  5. Isolation.Serializable 串行化

Spring中七种事务传播行为

事务传播行为类型说明
PROPAGATION_REQUIRED如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。
PROPAGATION_SUPPORTS支持当前事务,如果当前没有事务,就以非事务方式执行。
PROPAGATION_MANDATORY使用当前的事务,如果当前没有事务,就抛出异常。
PROPAGATION_REQUIRES_NEW新建事务,如果当前存在事务,把当前事务挂起。
PROPAGATION_NOT_SUPPORTED以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER以非事务方式执行,如果当前存在事务,则抛出异常。
PROPAGATION_NESTED如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。

索引的作用

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

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

控制反转和注入方式

DI—Dependency Injection,即“依赖注入”:组件之间依赖关系由容器在运行期决定,形象的说,

即由容器动态的将某个依赖关系注入到组件之中。依赖注入的目的并非为软件系统带来更多功能,

而是为了提升组件重用的频率,并为系统搭建一个灵活、可扩展的平台。通过依赖注入机制,我们

只需要通过简单的配置,而无需任何代码就可指定目标需要的资源,完成自身的业务逻辑,而不需

要关心具体的资源来自何处,由谁实现。

  理解DI的关键是:“谁依赖谁,为什么需要依赖,谁注入谁,注入了什么”

  ●谁依赖于谁:当然是应用程序依赖于IoC容器;

  ●为什么需要依赖:应用程序需要IoC容器来提供对象需要的外部资源;

  ●谁注入谁:很明显是IoC容器注入应用程序某个对象,应用程序依赖的对象;

  ●注入了什么:就是注入某个对象所需要的外部资源(包括对象、资源、常量数据)。

  IoC和DI由什么关系呢?其实它们是同一个概念的不同角度描述,由于控制反转概念比较含糊

(可能只是理解为容器控制对象这一个层面,很难让人想到谁来维护对象关系),所以2004年大

师级人物Martin Fowler又给出了一个新的名字:“依赖注入”,相对IoC 而言,“依赖注入”明确描述

了“被注入对象依赖IoC容器配置依赖对象”。

linux查看日志文件

tail:  
-n 是显示行号;相当于nl命令;例子如下:
tail -100f test.log 实时监控100行日志
tail -n 10 test.log 查询日志尾部最后10行的日志;
tail -n +10 test.log 查询10行之后的所有日志;
head:
跟tail是相反的,tail是看后多少行日志;例子如下:
head -n 10 test.log 查询日志文件中的头10行日志;
head -n -10 test.log 查询日志文件除了最后10行的其他所有日志;
cat:
tac是倒序查看,是cat单词反写;例子如下:
cat -n test.log |grep "debug" 查询关键字的日志

什么是线程

线程是CPU资源分配的最小单元,线程需要的资源更少,可以看做是一种轻量级的进程,

线程会共享进程中的内存,线程也有独立的空间(栈、程序计数器),线程相互通信更加方便

sleep和wait的区别

  1. 调用对象不同

    wait() 由锁对象调用

    sleep() 由线程调用

  2. 锁使用不同

    执行wait后,自动释放锁

    执行sleep后,不会释放锁

  3. 唤醒机制不同

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

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

深拷贝和浅拷贝的区别

1、浅拷贝:将原对象或原数组的引用直接赋给新对象,新数组,新对象数组只是原对象的一个引

用。

2、深拷贝:创建一个新的对象和数组,将原对象的各项属性的“值”(数组的所有元素)拷贝过

来,是“值”而不是“引用”。

举报

相关推荐

0 条评论