JAVA面试知识整理

1、我们是根据什么创建一个表 ?

数据库范式

2、数据库范式

第一范式

数据表的原子性

创建表的字段的时候,每个字段列不可再分出更多的字段

第二范式

在第一范式基础上

表需要一个唯一的字段为主键,通过主键可以快速的找到每一条数据

第三范式

在第二范式的基础上

当一个表需要用到另一个表的主键,但不能让他随便使用随便编造,需要一些约束

那么另一个表的主键就是主外键

第四范式

必须满足第三范式

对第二第三范式的设计规范要求更严格,消除数据冗余

3、关联表

select

from

where

group by   需要统计才要分组

order by 排序  asc升序 desc降序 默认升序

having 统计函数

limit

4、如何解决get 请求post请求乱码问题

我们可以在 web.xml 里面配置一个 CharacterEncodingFilter 过滤器。设置为 UTF-8 解决 get 请求的乱码:有两种方法。对于 get 请求中文参数出现乱码解决方法有两个:

1、修改 tomcat 配置文件添加码与工程编码一致。

2、另一种方法对参数进行重新编码 String userName = New String(Request.getParameter("userName").getBytes("ISO8859-1"),"utf-8");

5、HashMap和HashTable区别

HashMap和Hashtable是Java中用于存储键值对的两个类

1. 线程安全性:

HashTable是线程安全的,所有的方法都是同步的,可以在多线程环境下安全地使用。而HashMap是非线程安全的,它的方法没有进行同步处理,如果在多线程环境下使用HashMap可能会导致数据不一致或抛出异常。如果需要线程安全性,可以考虑使用ConcurrentHashMap。

2. null键和null值:

HashTable不允许存储null键和null值,如果尝试存储null键或null值,会抛出NullPointerException。而HashMap允许一个null键和多个null值的存在,即可以存储null键和null值。

3. 继承关系:

HashTable是基于Dictionary类实现的,而HashMap是基于AbstractMap类实现的。Dictionary是一个已经过时的类,不推荐使用。AbstractMap是一个抽象类,提供了一些Map相关的基本实现。

4. 初始容量和扩容机制:

HashTable的初始容量是11,扩容时会重新计算容量和阈值。而HashMap的初始容量是16,扩容时容量会扩大为原来的两倍。HashMap还允许通过构造函数指定初始容量和加载因子。

5. 性能:

由于HashTable是线程安全的,在多线程环境下性能可能较低,因为需要进行同步处理。而HashMap在单线程环境下性能较好,因为不需要进行同步。如果在单线程环境下使用,并且不需要考虑线程安全性,推荐使用HashMap。

6、Map常用方法

添加:put(Object key,Object value)。

删除:remove(Object key)。

查询:get(Object key)。

长度:size()。

遍历:keySet()/values()。

7、JAVA面向对象的特点

Java 是一种面向对象的编程语言,具有一些突出的面向对象特点。

1. 封装(Encapsulation):Java 使用类和对象来实现封装。通过将相关的数据和方法组合在一个类中,并且对外部隐藏内部实现细节,只提供公共接口来访问和操作数据,从而实现了数据的封装。这样可以提高代码的安全性和可靠性。

2. 继承(Inheritance):Java 支持继承机制,通过继承可以创建一个新的类,继承已存在的父类的属性和方法。继承可以实现代码的重用和层次化组织。子类可以使用父类的非私有成员,并可以通过重写(覆盖)父类的方法来扩展或修改父类的行为。

3. 多态(Polymorphism):多态是指同一个方法可以根据所操作的对象的类型而具有不同的行为。Java 的多态性是通过继承和接口来实现的。通过向上转型(Upcasting)可以实现多态,即将子类对象赋给父类类型的变量。在运行时,实际调用的是子类重写后的方法。

4. 抽象(Abstraction):Java 提供了抽象类和接口来实现抽象。抽象类是声明为抽象的类,不能被实例化,可以包含抽象方法和具体方法。接口是一种没有实现方法的完全抽象的类,它只能包含常量和抽象方法。通过抽象类和接口可以定义通用的规范和约束,提高代码的可维护性和扩展性。

5. 类和对象:Java 是一种面向对象的语言,所有的代码都必须包含在类中。类是对象的模板,它定义了对象的属性和方法。对象是类的实例,它具有类的属性和方法。通过类和对象的组合,可以创建复杂的程序,并将数据和操作进行组织和封装。

6. 封装和类的库:Java 提供了丰富的类库(包括 Java 核心库,如 java.lang、java.util 和 java.io),这些类库中封装了很多常用的功能和工具,可以简化开发人员的工作,提高开发效率。

Java 的面向对象特点使其具有良好的可维护性、可扩展性和可重用性。面向对象的编程方式使代码更加模块化、逻辑清晰,易于组织和理解。因此,Java 成为了广泛应用于企业级开发、桌面应用和移动应用开发的一种编程语言。

8、重写 equals方法的作用是什么?

重写 equals() 方法的作用是比较两个对象的内容是否相等。

9、哨兵模式?

Redis sentinel 是一个分布式系统中监控redis主从服务器, 并在主服务器下线时自动进行故障转移。其中三个特性:

监控(Monitoring):Sentinel(哨兵)会不断地检查你的主服务器和从服务器是否运作正常。

提醒(Notification):当被监控的某个Redis服务器出现问题时,Sentinel可以通过API向管理员或者其他应用程序发送通知。

自动故障转移(Automatic failover):当一个主服务器不能正常工作时,Sentinel会开始一次自动故障迁移操作。

特点:

  1. 保证高可用
  2. 监控各个节点
  3. 自动故障迁移

缺点:

主从模式,切换需要时间丢数据

没有解决master(主节点)写的压力

10、Redis常用命令?

redis-server:启动redis

redis-cli:连接redis

select 库名:用于切换到指定的数据库

ping:测试连通性

redis-cli shutdown:停止redis

keys *:获取所有键

dbsize:获取所有键数

exists key [key...]:查询键是否存在

del key:删除键

type key:查询键类型

move key db:移动键

查询key的生命周期(秒):

秒语法:ttl key

毫秒语法:pttl key

设置过期时间:

秒语法:expire key seconds

毫秒语法:pexpire key milliseconds

rename key newkey:更改键名称

get key:获取键

set key:存储键

sadd key member[member...]:存储值

smembers key:获取元素

mset key value [key value...]:批量存放键值

strlen key:获取值长度

1、一个“.Java”源文件中是否可以包括多个类(不是内部类)?有什么限制?

可以有多个类,但只能有一个public的类,并且public的类必须与文件名相一致。一个文件可以只有非public类,如果只有一个非public类,此类可以跟文件名不同。

2、说说&和&&的区别?

&和&&都可以用作逻辑与的运算符,&&为短路与,&不是短路与。另外&可以作为整数的位运算符。

例1:对于if(str != null && !str.equals(“”))表达式,当str为null时,后面的表达式不会执行,所以不会出现NullPointerException如果将&&改为&,则会抛出NullPointerException异常。

例2:if(x == 33 & ++y>0)y会增长,if(x == 33 && ++y>0)不会增长。

3、在JAVA中如何跳出当前的多重嵌套循环?

  1. break + 标签;
  2. 使用多个条件判断
  3. 使用方法return

4、静态变量和实例变量的区别?

在语法定义上的区别:静态变量前要加static关键字,而实例变量前则不加。

在程序运行时的区别:实例变量属于某个对象的属性,必须创建了实例对象,其中的实例变量才会被分配空间,才能使用这个实例变量。静态变量不属于某个实例对象,而是属于类,所以也称为类变量,只要程序加载了类的字节码,不用创建任何实例对象,静态变量就会被分配空间,静态变量就可以被使用了。

总之实例变量必须创建对象后才可以通过这个对象来使用,静态变量则可以直接使用类名来引用。

5、Integer和int的区别?

int是java提供的8中原始数据类型之一,意思整型,占用4字节。

Integer是java为int提供的封装类是引用数据类型。

Int的默认值为0,而Integer的默认值为null,即Integer可以区分出未赋值和值为0的区别,int则无法表达出未赋值的情况。

6、Math.round(11.5)等于多少?Math.round(-11.5等于多少)?

Math类中提供了三个与取整有关的方法:cell(向上取整)、floor(向下取整)、round(四舍五入),round算法为:Math.floor(x + 0.5),即将原来的数字加上0.5后在向下取整,所以,Math.round(11.5)的结果为12,Math.round(-11.5)的结果为-11。

7、请说出作用域public、private、protected,以及不写时的区别。

说明:如果在修饰元素上面没有写任何访问修饰符,则表示friendly/default。

作用域

当前类

同package

子孙类

其他package

public

protected

×

friendly

×

×

private

×

×

×

8、“==”和equals方法究竟有什么区别?

他们的区别主要存在在引用数据类型上:

==为比较两侧的对象是否同一对象,是用内存地址来比较的

equals是方法,默认是内存地址比较,重写后,主要用来比较两侧的对象的值是否相同,和equals方法中的实现有关。

==可以两侧都为null,但equals左侧的引用指向的对象不能为空,不然有NullPointerException。

除非需要比较两个引用指向的对象是同一对象,一般都使用equals方法进行比较。尤其是String之类的值对象,另外,常量尽量放在比较的左侧。

9、面向对象的特征有哪些方面?

1)封装,隐藏内部实现,只暴露公共行为

2)继承,提高代码的重用性

3)多态,体现现实生活中相似对象的差异性

4)抽象,抽取现实世界中相似对象的共同点

10、JAVA中实现多态的机制是什么?

通过继承父类或实现接口。不同子类或实现类对同一父类方法有不同的实现。根据对象调用相应的实现方法。另外对于相似的方法,可以使用重载。

1、yaml配置的优势在哪里

1)配置有序,在一些特殊的条件下,配置有序很关键。

2)支持数组,数组中的元素可以是基本数据类型也可以是对象

3)简洁,相比properties配置文件,yaml还有一个缺点,就是不支持@PropertySource注解导入自定义的yaml配置。

2、Springboot中如何解决跨域问题?

通过@CrossOrigin注解来解决跨域。

3、Springboot如何实现热部署

Springboot实现热部署只要引入devtools依赖即可,这样当编译文件发生变化时,Springboot就会自动重启。

4、Springboot是否可以使用xml配置

Springboot推荐使用Java配置而非xml配置,但是Springboot中也可以使用xml配置,通过@ImportResource注解可以引入一个xml配置。

5、ArrayList和LinkedList在增删改查操作上的差别?

1. 增加操作:

ArrayList在末尾添加元素时效率较高,但在中间或开头插入元素时效率较低。这是因为插入一个元素后,其后面的所有元素都需要往后移动一个位置。

LinkedList在末尾添加元素时比较低效,但在中间或开头插入元素时效率较高。这是因为链表插入元素时只需要改变节点指针的指向,而不需要移动其他元素。

2. 删除操作:

ArrayList删除元素时效率较低,因为需要将后面的元素往前移动一个位置。

LinkedList删除元素时效率较高,因为只需要改变节点指针的指向即可。

3. 修改操作:

ArrayList修改元素时效率较高,因为数组支持随机访问和修改。

LinkedList修改元素时效率较低,因为需要依次遍历链表找到要修改的节点。

4. 查找操作:

ArrayList查找元素时效率较高,因为数组支持随机访问,可以根据下标直接访问元素。

LinkedList查找元素时效率较低,因为需要从头节点依次遍历链表,直到找到要查找的元素为止。

综上所述,如果需要频繁进行插入和删除操作,建议使用LinkedList。如果需要频繁进行随机访问和修改操作,建议使用ArrayList。当然,在具体选择数据结构时,还需要根据具体场景和需求进行综合考虑。

6、v-show与v-if有什么区别?

1. v-show

v-show是Vue.js内置的指令,用于控制组件或元素的显示和隐藏。与其他指令相比,v-show的行为比较简单。它只是根据绑定的值来控制元素的display CSS属性的值,而不会将元素从DOM中移除。如果绑定的值为false,元素将被隐藏(display:none),如果绑定的值为true,元素将显示(display:block)。

2. v-if

v-if也用于控制组件或元素的显示和隐藏,但与show不同,它具有更加严格的控制行为。如果绑定的值为true,元素绑定的组件会被创建并渲染到DOM树中;如果绑定的值为false,元素绑定的组件将被销毁,并且从DOM树中移除。因此,v-if可以在需要频繁切换的场景中,实现更加高效的DOM操作。

综上所述,show和v-if都是用于控制组件或元素的显示和隐藏,但show只是控制元素的display属性,不会对DOM进行添加或删除,而v-if则可以根据绑定的值动态地添加或删除元素,并且对DOM的操作更加高效。

7、Vue的父组件和子组件生命周期钩子函数执行顺序?

Vue的父组件和子组件生命周期钩子函数执行顺序可以归类为以下4部分:

加载渲染过程 父 beforeCreate -> 父 created -> 父 beforeMount -> 子 beforeCreate -> 子 created -> 子 beforeMount -> 子 mounted -> 父 mounted

子组件更新过程 父 beforeUpdate -> 子 beforeUpdate -> 子 updated -> 父 updated

父组件更新过程 父 beforeUpdate -> 父 updated

销毁过程 父 beforeDestroy -> 子 beforeDestroy -> 子 destroyed  -> 父 destroyed

8、在哪个生命周期内调用异步请求?

可以在钩子函数 created、 beforeMount、 mounted 中进行调用,因为在这三个钩子函数中,data已经创建,可以将服务端返回的数据进行赋值。但是更推荐在created钩子函数中调用异步请求,因为在created钩子函数中调用异步请求有以下优点:

能更快获取到服务端数据,减少页面loading(加载)时间

ssr(服务器端渲染)不支持beforeMount、mounted钩子函数,所以放在created中有助于一致性;

9、String、StringBuffer、StringBuilder区别?

String是final修饰的,不可变,底层用char数组实现的。每次操作都会产生新的String对象,性能低。

StringBuffer和StringBuilder都是在原对象上操作。

StringBuffer是线程安全的,StringBuilder是线程不安全的,效率更高

10、重写和重载的区别?

方法重载:

同一个类里,有多个方法,名字相同,但是参数个数、参数类型不相同,这个现象就是方法重载。

方法重写:

子类继承父类时,可以重写父类的方法。

方法名相同,方法的参数和个数也得相同。

子类重写的方法的权限修饰符不小于父类被重写的方法的权限修饰符私有方法、静态方法不能被重写。

子类重写的方法抛出的异常类型不大于父类被重写的方法抛出的异常类型。

11、接口和抽象类的区别?

抽象类有以下特性:

抽象类是一种特殊的类,用abstract修饰。

不能直接new出抽象类的对象出来。

可以在类里定义抽象方法。也可以不定义抽象方法。

所以说,一般我们会写一个类,继承抽象类,这样才能new出对象来。

接口的特性:

接口里的变量,都是静态final的。

接口里的方法,都是抽象的。

Jdk8以后,接口里可以定义方法的默认实现。

1、Redis如何保证主从数据一致性?

采取读写分离的模式:

读操作:主、从库都可以执行,一般是在从库上读数据,对实时性和准确性有100%高真要求的部分业务,可以谨慎评估之后读主库;

写操作:只在主库上写数据,写完之后将写操作指令同步到从库。

2、主从复制

目前实现Redis高可用的模式主要有三种:主从模式、哨兵模式、集群模式。

Redis提供的主从模式,是通过复制的方式,将主服务器上的Redis的数据同步复制一份到从Redis服务器,这种做法很常见,MySQL的主从也是这么做的。

主节点的Redis我们称之为master,从节点的Redis我们称之为slave,主从复制为单向复制,只能由主到从,不能由从到主。可以有多个从节点,比如1主2从甚至n从,从节点的多少根据实际的业务需求来判断。

3、主从复制原理

主从复制分两种:主从刚连接的时候,进行全量同步;全量同步结束后,进行增量同步。

全量同步:首次配置完成主从库链接之后;

增量同步:全量同步结束后

准实时同步:主从正常运行期间;

Append增量数据+准实时同步:主从库间网络断开重连。

4、Redis的主要特点是什么?

以下是 Redis 的主要功能:

  • 读写性能优异, Redis 能读的速度是 110000 次/s,写的速度是 81000 次/s。
  • 支持数据持久化,支持 AOF 和 RDB 两种持久化方式。
  • 支持事务,Redis 的所有操作都是原子性的,同时 Redis 还支持对几个操作合并后的原子性执行。
  • 数据结构丰富,除了支持 String 类型的 value 外还支持 hash、set、zset、list 等数据结构。
  • 支持主从复制,主机会自动将数据同步到从机,可以进行读写分离。

5、Redis开启事务的关键字?

Redis本身提供了multi关键字用来开启事务,exec用来关闭事务。

6、什么是缓存穿透?如何避免?什么是缓存击穿?何如避免?什么是缓存雪崩?何如避免?

缓存穿透

用户访问的数据,数据库中根本不存在,这样缓存就不会起作用,大量请求就直接到了数据库。引起数据库压力过大。一般,是恶意攻击。

如何避免?

1. 缓存空值:即使数据库没有数据,也缓存空字符串,设置一个比较小的过期日期,比如10秒。

2. 校验非法数据

3. 布隆过滤器

4. nginx 设置 黑名单

缓存击穿

高并发场景下,当一个key失效时,大量查询请求从缓存里拿不到数据,会一起访问数据库查询数据,造成数据库压力瞬间过大,可能引起数据库崩溃。

如何避免?

1. 热点数据永不过期

2. 实时监控热点数据,延长过期时间

3. 加载数据前,要加锁,然后再次判断缓存中没有,这才加载数据。

缓存雪崩

同一时间点,大量key一起过期,造成数据库压力大,系统崩溃。

有几种可能,第一种可能是Redis宕机,第二种可能是采用了相同的过期时间。

如何避免?

1. 缓存时间设置的有一定随机性: 固定值 + 随机值

2. 构建多级缓存: 本地缓存 + redis缓存

3. 服务熔断 - 服务降级

7、== equal 的区别

对于基本类型,==比较的是值;

对于引用类型,==比较的是地址;

equals不能用于基本类型的比较;

如果没有重写equals,equals就相当于==;

如果重写了equals方法,equals比较的是对象的内容;

8、String的常用方法?

trim() 去掉左右两边空格

substring() 截取字符串。

replace() 替换字符串中的指定内容

replaceAll() 替换字符串中的指定内容

length() 获取字符串长度

charAt() 返回指定索引处的字符。

split() 分割字符串,返回一个分割后的字符串数组。

indexOf() 返回指定字符的索引。

getBytes() 返回字符串的 byte 类型数组。

equals() 字符串比较。

toLowerCase() 将字符串转成小写字母。

toUpperCase() 将字符串转成大写字符

9、String、StringBuffer、Stringbuilder区别?

String是final修饰的,不可变,底层用char数组实现的。每次操作都会产生新的String对象 ,性能低。

StringBuffer和StringBuilder都是在原对象上操作 。

StringBuffer是线程安全的,StringBuilder线程不安全的 ,效率更高。

10、重载和重写的区别?

方法重载:

同一个类里,有多个方法,名字相同,但是参数个数、参数类型不相同,这个现象就是方法重载。

方法重写:

子类继承父类时,可以重写父类的方法。

方法名相同,方法的参数类型和个数也得相同。

子类重写的方法的权限修饰符不小于父类被重写的方法的权限修饰符私有方法、静态方法不能被重写。

子类重写的方法抛出的异常类型不大于父类被重写的方法抛出的异常类型

11、接口和抽象类的区别?

抽象类有以下特性:

抽象类是一种特殊的类,用abstract修饰。

不能直接new出抽象类的对象出来。

可以在类里定义抽象方法。也可以不定义抽象方法。

所以说,一般我们会写一个类,继承抽象类,这样才能new出对象来。

接口的特性:

接口里的变量,都是静态final的

接口里的方法,都是抽象的。

jdk8以后,接口里可以定义方法的默认实现。

1.数据库的优点?

答:(1)方便检索

 (2)保持数据的一致性、完整性;

 (3)安全,可共享

 (4)通过组合分析,可产生新数据

 (5)存储量大

2.sql语句的分类?

答:DDL(Data Definition Language):数据定义语言,对库、表、列(字段)进行操作的sql (重点);

        DML(Data Manipulation Language):数据操作语言,对数据进行操作的sql (最重点);

        DCL(Data Control Language):数据控制语言,对用户以及用户权限设定的sql (了解);

        DQL(Data Query Language):数据查询语言,查询的sql (最重点)

3.聚合函数有哪些?

答:COUNT():数量;

       MAX():最大值;

        MIN():最小值;

        SUM():数值和;

        AVG():平均值;

4.完整性约束有哪些?

答:唯一约束:unique   约束该列数据唯一

非空约束:not null   约束该列数据不能为空

主键约束:primary key  主键列既不能为空,也不可重复,被外键引用

外键约束:foreign key  可以重复,可以为空,引用主键

5. 主键索引和唯一索引的区别?

答:(1)主键既不能为空,也不能重复

唯一索引不能重复,但可以为空

(2)一个表中只能有一个主键,但可以有多个唯一索引

6. 什么是事务?

答:作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行。事务就是执行的一组sql语句。

8. 事务的四大隔离级别?

答:序列化

可重复读

读已提交数据

读未提交数据

9. 事务的并发读问题?

答:脏读 一个事务A读取了被另一个事务B修改,但是还未提交的数据

不可重复读 事务B读取了两次数据资源,在这两次读取的过程中事务A修改了数据,导致事务B在这两次读取出来的数据不一致。

幻读(虚读)事务B前后两次读取同一个范围的数据,在事务B两次读取的过程中事务A新增了数据,导致事务B后一次读取到前一次查询没有看到的行。

10.mysql 的内连接、左连接、右连接有什么区别?

内连接,显示两个表中有联系的所有数据;

左链接,以左表为参照,显示所有数据,右表中没有则以null显示

右链接,以右表为参照显示数据,,左表中没有则以null显示

  1. List常用方法?

1、lilst.add() 向集合中添加数据

2、list.remove() 删除

3、list.size() 统计集合中有多少元素

4、list..isEmpty() 判断集合中是否有元素

5、list.clear() 清空集合中的所有元素

6、list.get() 获取对应位置index的数据

7、list.set() 在指定位置index的数据替换

1、for,增强for 区别是?

增强for循环的范围比for循环要小  

任何循环都能用普通for循环运行,但不一定能用增强for循环

增强for内部使用迭代器遍历 只能遍历数组和集合

普通for循环可以获取元素索引,增强for循环无法获取元素索引

增强for循环必要有被遍历的目标

增强for循环无法在循环时动态的删除元素和获取下标

2、Arraylist length获取长度?

ArrayList.size()获取长度

3、MySQl常用函数?

1. 聚合函数:SUM、AVG、COUNT、MAX、MIN 等函数,可以对一列数值进行聚合计算。

2. 字符串函数:CONCAT、SUBSTR、TRIM、UPPER、LOWER 等,可以对字符串进行处理和转换。

3. 日期时间函数:NOW、DATE、TIME、YEAR、MONTH、DAY 等,可以对日期和时间进行计算和格式化。

4. 数值函数:CEIL、FLOOR、ABS、ROUND、RAND 等,可以对数值进行计算和处理。

5. 逻辑函数:IF、CASE、COALESCE 等,可以对逻辑进行处理和转换。

6. 转换函数:CAST、CONV、HEX、UNHEX 等,可以对数据类型进行转换。

7. 加密函数:MD5、SHA1、PASSWORD 等,可以对字符串进行加密和散列。

8. JSON函数:JSON_OBJECT、JSON_ARRAY、JSON_EXTRACT 等,可以对 JSON 数据进行操作和解析。

4、MySQl事务开启,关闭关键字?

1. 开启事务:`START TRANSACTION` 或 `BEGIN` 语句可以来开启一个新的事务。

2. 提交事务:如果事务执行成功,可以使用 `COMMIT` 语句提交事务,并将对数据库所做的全部更改保存到数据库中。

3. 回滚事务:如果在事务执行过程中发生错误或者需要撤销之前的操作,可以使用 `ROLLBACK` 语句将事务回滚到之前的状态。

需要注意的是,为了确保事务执行的正确性和可靠性,应该在事务的开始和结束处都加入相应的开启和关闭语句。在执行事务过程中,应该遵循事务的 ACID 特性(原子性、一致性、隔离性和持久性),并尽可能使用索引、锁和其他优化技术来提高事务的效率和性能。

5、什么是MySQl事务?

在 MySQL 中,事务是指一组有序的操作,这些操作要么全部执行成功,要么全部不执行(或者回滚)。事务的目的是将多个操作视为逻辑上的单个操作组,从而保证数据的一致性、可靠性和完整性。

MySQL 中的事务具有 ACID 特性,即原子性、一致性、隔离性和持久性。这些特性具体表现在:

1. 原子性:事务是一个原子单元,事务的所有操作要么全部执行、要么全部回滚,保证数据的完整性和一致性。

2. 一致性:事务执行过程中的所有操作,都必须保证数据库从一个一致性状态转换到另一个一致性状态,保证数据的准确性。

3. 隔离性:一个事务的执行不会被其他事务干扰,多个并发事务执行过程中,相互之间不会影响,保证事务之间的隔离性。

4. 持久性:一旦事务提交,其所做的操作将永久保存到数据库中,即使出现系统故障或者数据库崩溃,也不会丢失数据。

在 MySQL 中,可以使用 BEGIN 或 START TRANSACTION 开始一个事务,使用 COMMIT 提交一个事务,使用 ROLLBACK 对一个事务进行回滚。同时,MySQL 还提供了多种隔离级别,通过设置不同的隔离级别,可以控制事务并发执行和数据一致性的关系。

需要注意的是,在数据库的设计和开发中,事务的正确使用非常重要。合理的事务设计能够保证数据的完整性和一致性,避免了不必要的数据冲突和错误。

6、什么是跨域

当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域

当前页面url

被请求页面url

是否跨域

原因

http://www.test.com/

http://www.test.com/index.html

同源(协议、域名、端口号相同)

http://www.test.com/

https://www.test.com/index.html

跨域

协议不同(http/https)

http://www.test.com/

http://www.baidu.com/

跨域

主域名不同(test/baidu)

http://www.test.com/

http://blog.test.com/

跨域

子域名不同(www/blog)

http://www.test.com:8080/

http://www.test.com:7001/

跨域

端口号不同(8080/7001)

7、throw和throws的区别?

(1)throw

作用在方法内,表示抛出具体异常,由方法体内的语句处理;

一定抛出了异常;

(2)throws

作用在方法的声明上,表示抛出异常,由调用者来进行异常处理;可能出现异常,不一定会发生异常;

8、java常见的异常类有哪些?

NullPointerException:空指针异常;

SQLException:数据库相关的异常;

IndexOutOfBoundsException:数组下角标越界异常;

IOException:当发生某种IO异常时抛出;

FileNotFoundException:打开文件失败时抛出;

NumberFormatException:当试图将字符串转换成数字时,失败了,抛出;

IllegalArgumentException 抛出的异常表明向方法传递了一个不合法或不正确的参数

9、cookie和session的区别?

(1)存储位置不同

cookie在客户端浏览器;

session在服务器;

(2)存储容量不同

cookie<=4K,一个站点最多保留20个cookie;

session没有上线,出于对服务器的保护,session内不可存过多东西,并且要设置session删除机制;

(3)存储方式不同

cookie只能保存ASCII字符串,并需要通过编码方式存储为、字符或者二进制数据;

session中能存储任何类型的数据,包括并不局限于String、integer、list、map等;

(4)隐私策略不同

cookie对客户端是可见的,不安全;

session存储在服务器上,安全;

(5)有效期不同

开发可以通过设置cookie的属性,达到使cookie长期有效的效果;

session依赖于名为JESSIONID的cookie,而cookie JSESSIONID的过期时间默认为-1,只需关闭窗口该session就会失效,因而session达不到长期有效的效果;

(6)跨域支持上不同

cookie支持跨域;

session不支持跨域;

10、什么是控制反转、什么是依赖注入?

借助Spring实现具有依赖关系的对象之间的解耦

对象A运行需要对象B,由主动创建变为IOC容器注入,这便是控制反转

获得依赖关系对象的过程被反转了,获取依赖对象的过程由自身创建变为IOC容器注入,这便是依赖注入

1、Vue常用指令

v-model:用于在表单元素和数据之间双向绑定。

v-for:用于循环渲染列表。

v-bind:用于绑定 HTML 元素属性或组件的 props。

v-if / v-else / v-show:用于根据条件展示或隐藏元素。     

 v-on:用于绑定事件监听器。

v-text / v-html:用于渲染文本或 HTML 内容。

v-pre:跳过当前节点的编译过程,用于优化性能。

v-cloak:用于防止页面闪烁问题。

v-once:用于只渲染一次的情况,不再响应数据变化。

v-bind:class / v-bind:style:用于绑定类名或样式,可以动态改变。

2、什么是缓存穿透?如何避免?什么是缓存击穿?何如避免?什么是缓存雪崩?何如避免?

缓存穿透

用户访问的数据,数据库中根本不存在,这样缓存就不会起作用,大量请求就直接到了数据库。引起数据库压力过大。一般,是恶意攻击。

如何避免?

1. 缓存空值:即使数据库没有数据,也缓存空字符串,设置一个比较小的过期日期,比如10秒。

2. 校验非法数据

3. 布隆过滤器

4. nginx 设置 黑名单

缓存击穿

高并发场景下,当一个key失效时,大量查询请求从缓存里拿不到数据,会一起访问数据库查询数据,造成数据库压力瞬间过大,可能引起数据库崩溃。

如何避免?

1. 热点数据永不过期

2. 实时监控热点数据,延长过期时间

3. 加载数据前,要加锁,然后再次判断缓存中没有,这才加载数据。

缓存雪崩

同一时间点,大量key一起过期,造成数据库压力大,系统崩溃。

有几种可能,第一种可能是Redis宕机,第二种可能是采用了相同的过期时间。

如何避免?

1. 缓存时间设置的有一定随机性: 固定值 + 随机值

2. 构建多级缓存: 本地缓存 + redis缓存

3. 服务熔断 - 服务降级

3、什么是跨域?

跨域全称为Cross-Origin Resource Sharing,意为跨域资源共享,是一种允许当前域(domain)的资源被其他域(domain)的脚本请求访问的机制,通常由于同源安全策略,浏览器会禁止这种跨域请求。

而我们所说的跨域问题是因为违反了浏览器的同源安全策略而产生的。

4、怎么解决跨域?

后端:@CrossOrigin注解

前端:配置下载axios连接前后端

5、Mybatis 中的动态标签

1. if 标签:用于在 SQL 语句中添加条件判断,格式如下:

<select id="findUsers" parameterType="User">

 SELECT * FROM user WHERE 1=1

   <if test="username != null">

     AND username like '%${username}%'

   </if>

   <if test="age != null">

    AND age = #{age}

   </if>

</select>

2. choose/when/otherwise 标签:类似于 Java 中的 switch/case/default 分支语句,用于在多个条件中进行选择,格式如下:

<select id="findUsers" parameterType="User">

  SELECT * FROM user WHERE 1=1

  <choose>

    <when test="username != null">

      AND username like '%${username}%'

    </when>

    <when test="age != null">

      AND age = #{age}

    </when>

    <otherwise>

      AND status = 1

    </otherwise>

  </choose>

</select>

3. foreach 标签:用于循环遍历数组或集合,格式如下:

<select id="findUsers" parameterType="User">

  SELECT * FROM user WHERE id IN

  <foreach item="id" collection="ids" open="(" separator="," close=")">

    #{id}

  </foreach>

</select>

4. trim 标签:在 SQL 中添加固定的文字、去除多余的逗号等,格式如下:

<select id="findUsers" parameterType="User">

  SELECT * FROM user

  <trim prefix="" prefixOverrides="AND | OR">

    <if test="username != null">

      AND username like '%${username}%'

    </if>

    <if test="age != null">

      AND age = #{age}

    </if>

  </trim>

</select>

还有其他一些标签,如 set 标签、where 标签、bind 标签等,它们都可以根据业务需求进行灵活使用,组合出合适的查询语句。需要注意的是,动态 SQL 确实可以很好地处理一些复杂的查询业务,但同时也可能引入 SQL 注入等安全问题,需要根据实际场景进行审慎使用。

6、MySQl中的视图?

MySQL 中的视图(View)是存储在数据库中的虚拟表。视图是从单个或多个现有的表中导出的结果集,可以被认为是一个虚拟的表。和表一样,视图包含行和列,它们可以被用于查询和更新,就好像它们实际上是一个表一样。使用视图,可以方便地重用查询并简化复杂的 SQL 查询。

在 MySQL 中,视图可以有如下优点:

1. 简化查询:可以使用 SELECT 语句定义视图,可以将复杂的 SQL 查询转换为简单的 SELECT 语句查询视图。

2. 数据安全性和访问控制:可以定义视图来过滤不需要的信息,以控制用户访问的数据。

3. 重用查询:使用视图可以在同一个查询中多次调用相同的 SELECT 语句。

4. 简化数据维护:对于多个表之间的复杂关系,使用视图可以简化数据维护。

在 MySQL 中创建视图的语法如下:

CREATE VIEW view_name AS

SQL_SELECT_STATEMENT;

其中 `view_name` 是视图的名称,`SQL_SELECT_STATEMENT` 是视图定义的 SELECT 语句。例如,定义一个视图 `emp_view`,该视图从 `employees` 表中选择 `employee_id` 和 `last_name` 列:

CREATE VIEW emp_view AS

SELECT employee_id, last_name

FROM employees;

通过添加适当的 WHERE 子句,可以定义更复杂的视图,使用视图的时候,可以像表一样进行查询,例如:

SELECT * FROM emp_view WHERE employee_id < 100;

需要注意的是,视图并不是物理的表,不能存储数据,它只是一个 SELECT 语句的虚拟表。因此,在修改视图时,实际上是修改了 SELECT 语句,而不是修改了表中的数据。此外,对于一些复杂的视图,也可能影响性能,需要根据实际需求进行审慎使用。

7、vue显示与隐藏怎么实现

在 Vue 中,可以使用条件渲染指令 `v-if` 和 `v-show` 来控制组件或元素的显示与隐藏。

1. v-if 指令:此指令会根据给定的表达式的真假条件,来销毁或重建元素及其所有的事件和子组件。如果表达式返回 true,则元素会被渲染,否则会被销毁。例如:

<template>

  <div>

    <p v-if="showText">显示文本</p>

    <button @click="toggleShow">Toggle</button>

  </div>

</template>

<script>

export default {

  data() {

    return {

      showText: true

    };

  },

  methods: {

    toggleShow() {

      this.showText = !this.showText;

    }

  }

};

</script>

在上述代码中,当数据对象 `showText` 为 true 时,`<p>` 元素将被渲染,否则不会被渲染。

2. v-show 指令:此指令只会根据给定的表达式的真假条件来切换元素的 CSS 样式中的 `display` 属性,不会销毁或重建元素及其事件和子组件。如果表达式返回 true,则元素会显示,否则会隐藏,例如:

<template>

  <div>

    <p v-show="showText">显示文本</p>

    <button @click="toggleShow">Toggle</button>

  </div>

</template>

<script>

export default {

  data() {

    return {

      showText: true

    };

  },

  methods: {

    toggleShow() {

      this.showText = !this.showText;

    }

  }

};

</script>

在上述代码中,当数据对象 `showText` 为 true 时,`<p>` 元素会显示,否则会隐藏,但是元素不会被销毁。

因此,需要根据实际需求选择使用 v-if 还是 v-show 指令。如果元素不常用,或需要根据复杂的条件来渲染,建议使用 v-if,因为它可以节省性能。如果元素需要频繁的显示和隐藏,并且不需要销毁和重建,建议使用 v-show。

8、集合的遍历方式?

在 Java 中,可以使用多种方式遍历集合,以下是常见的几种遍历方式:

1. 增强型 for 循环:在 Java 5 中新增的一种循环方式,适用于遍历任何实现了 `Iterable` 接口的类,如 `List`、`Set` 等。语法如下:

for (元素类型 变量名 : 集合名) {

    循环执行的语句块;

}

```

示例代码如下:

```

List<String> list = new ArrayList<>();

list.add("apple");

list.add("banana");

list.add("orange");

for (String fruit : list) {

    System.out.println(fruit);

}

```

输出:

```

apple

banana

orange

```

2. 迭代器(Iterator):是集合框架中的一种通用设计模式,用于遍历集合中的元素。可以使用 `Iterator` 接口的 `hasNext()` 方法判断是否还有下一个元素,使用 `next()` 方法获取下一个元素。示例代码如下:

```

List<String> list = new ArrayList<>();

list.add("apple");

list.add("banana");

list.add("orange");

Iterator<String> it = list.iterator();

while (it.hasNext()) {

    System.out.println(it.next());

}

```

输出:

```

apple

banana

orange

```

3. forEach 方法:该方法是 Java 8 中 Iterable 接口新增的默认方法,可以使用 lambda 表达式遍历集合中的元素。示例代码如下:

```

List<String> list = new ArrayList<>();

list.add("apple");

list.add("banana");

list.add("orange");

list.forEach(fruit -> System.out.println(fruit));

```

输出:

```

apple

banana

orange

```

需要注意的是,在遍历过程中,不应该对集合进行修改,否则会抛出 `ConcurrentModificationException` 异常。如果需要在遍历过程中修改集合,可以使用迭代器的 `remove()` 方法进行删除操作。

9、varchar 与char区别?

在关系型数据库中,`VARCHAR` 和 `CHAR` 都是存储字符串类型的列。它们的主要区别在于如何存储和使用存储空间。

1. 存储方式:

 `VARCHAR`:可变长度的字符串类型,它存储的字符串可以为任意长度,其长度为在插入数据时所输入的实际长度,通常使用长度不固定的数据类型来存储变长的字符串,因为在使用时节约了存储空间。

 `CHAR`:定长的字符串类型,它存储的字符串长度固定,超过指定长度的部分将被截断。它可以浪费存储空间,如果存储的字符串长度小于列的定义长度,则系统会自动在其后面填充空格。

2. 存储空间:

`VARCHAR`:存储空间由该列中存储的值的长度决定,可以节约存储空间。在 MySQL 中,一个 `VARCHAR(N)` 列,如果存储的实际数据长度不足 N 时,只占用实际长度的存储空间,因此在存储空间方面更加灵活。

`CHAR`:存储空间固定,如果存储的实际数据长度小于该列定义的长度,则后面填充空格浪费存储空间,但由于其定长特性,不需要为字符串长度增加的列大小需自适应调整,对于较短的字符串可能不如 `VARCHAR` 存储空间更节省;但在查询时,由于每行数据的存储空间都相同,所以在查询效率上通常比 `VARCHAR` 更快。

因此,当存储数据长度不确定的字符串时,宜使用 `VARCHAR` 类型,当存储数据长度固定的字符串时,可以考虑使用 `CHAR` 类型。但需要根据实际业务场景来选择,较长而变化范围较小的字符串可以使用 `CHAR`,较短,经常变化的字符串可以使用 `VARCHAR`。

10、数据库索引知道几种?

1. B-tree 索引:B-tree 是基于平衡树的一种数据结构,常用于实现数据库索引。它可以保持数据有序,并且支持快速的查询、插入和删除操作。在 B-tree 索引中,每个节点存储有序的 key 值,并且具有指向下一级节点的指针,从根节点开始遍历,即可快速找到所需的数据。

2. Hash 索引:Hash 索引使用哈希表存储数据,能够快速实现等值查询,但是无法用于模糊查询、范围查询等操作。在 Hash 索引中,每个键值对会被映射到一个特定的桶中,通过计算哈希值即可快速找到所需的数据。

3. 全文索引:全文索引常用于文本数据的查询操作,例如评论内容、邮件内容等。全文索引可识别、分离、整理出特定文本中的单词或词组,并为这些单词建立索引,支持模糊查询、范围查询等操作。

4. 空间索引(Spatial Index):空间索引主要应用于地理信息系统、地图、航空航天等领域,用于查询空间数据。它可以快速计算数据的位置、距离、方向、形状等属性。

  1. 加密索引(Encrypted Index):加密索引用于对敏感数据进行加密存储,防止数据泄露和窃取。在加密索引中,数据必须加密后才能被存储,查询时需要对查询条件也进行加密,才能进行相应的查询操作。

需要根据实际的业务情况来选择适合的索引类型,例如在需要快速查找数据、并支持模糊查询等操作时,可以使用 B-tree 索引;在需要对文本数据进行查询时,可以使用全文索引;在需要对地理信息进行查询时,可以使用空间索引等。

1、Spring常用注解

@AutoWired:自动装配,可以自动注入spring所管理对象之间的依赖关系。

@Resource:

@Component:将一个Java类定义为Bean交给spring容器管理,@Component是一个泛化的概念,与具体实现无关所以使用时用更具体的注解,如@Controller,@Service,@@Repository等。

@RequestMapping:定义处理HTTP请求的方法,用于处理浏览器发送的请求,映射URL到控制器类上的方法,定义不同不同路径下请求的映射逻辑。

@ResponseBody:将方法的返回值直接转换为HTTP响应体,并写入响应流中。

@PathVariable:使用注解可以将请求路径中的变量绑定到方法的参数上,方便获取路径中的参数。

@RestController:注解相当于@Controller和@ResponseBody的结合体,可以将控制器类的所有请求处理方法直接转换为HTTP响应体。

@Service:声明一个服务类Bean,一般用于定义服务层的业务逻辑。

@Transactional:标记这个方法或类为事务性处理,用于确保所有读写数据库操作之间保持一个完整的事务。

@Configuration:声明一个类为配置类,通常和@Bean注解一起使用,用于替代xml配置文件。

@Bean:声明一个方法为Bean,交给Spring容器管理,同事可以用于构造依赖关系。在@Configuration注解的类中使用,返回值为Bean对象。

@Value:从Spring容器中获取属性值,常用于配置文件中获取属性值,并赋给成员变量或方法参数。

2、Springboot常用注解?

@SpringbootApplication:该注解融合了其他三个注解:@Configuration,@EnableAutoConfiguration和@ComponentScan。使用这个注解标注的类会变成Springboot上下文的一个Bean,同时自动启用SpringBoot中的许多特性。

@ResponseBody:将后端的值转换为JSON或XML格式传向前端

@RestController:注解相当于@Controller+@ResponseBody两个注解的结合体。@RestController相当于简化编写RESTful API的代码的写法,RESTful API典型的实现方式就是在前面加上RequestMapping,同时在Controller响应方法上加上@ResponseBody注解

@RequestMapping是Spring中用于吃力请求的注解,可以用于将某个URL映射到具体的处理方法上。和SpringMVC一样,RequestMapping注解也可以设置请求方法、请求头、请求参数、请求体等属性。

@Autowired注解是自动装配的基本注解,可以将Spring容器中的Bean自动那个注入到属性或方法上。可以用于依赖注入、控制反转等功能。

@Value注解用来获取配置文件中的属性值等信息。通过该注解,可以方便地将配置信息注入到Java对象中。

@Service注解用于标注一个类为服务类,一般用于定义服务层的业务逻辑。

@Repository注解用于标注一个类为数据访问层类,一般负责数据库操作等功能。

@Transactional注解用于标记一个事务性方法,使这个方法执行时生效事务管理,从而保证更新数据库的操作成功或失败时可以进行事务回滚。

@Component注解是一个泛化的概念,表示Spring管理的Bean组件。当采用基于注解的自动扫描结构时,任何一个被@Bean、@Component、@Controller、@Service或@Repository注解的Java类,都被作为一个Bean事先实例化到Spring IoC容器中。

@Configuration注解将一个类标识为应用程序上下文的Java配置类。该类应该包含在应用程序中处理bean创建和配置以及其他应用程序运行时使用的引导逻辑的方法。

  1. Vue钩子函数

1、beforeCreate():在实例初始化之后,数据观测和时间配置之前被调用。在这个阶段,实例的属性和方法都不能被访问到。

2、created():在实例创建完成后被立即调用。在这个阶段,实例已经完成了数据的观测和事件的配置,但是$el属性并没有被创建。

3、beforeMount():在挂载开始之前被调用。在这个阶段,vue实例的模板已经编译完成,但是还没有挂载到页面上的DOM节点上。

4、mounted():在实例挂载之后被调用。在这个时候,vue实例已经挂载到页面上的固定节点上,并对DOM进行了渲染,这个时候可以进行DOM操作。

5、beforeUpdate():在数据更新时被调用。在这个阶段,页面上的数据并没有更新,因此可以在这个阶段进行数据比较,并做出相应的更新。

6、updated():在数据更新完成后被调用。在这个时候,vue实例的DOM已经更新完成。

7、beforeDestroy():在实例销毁之前被调用。在这个阶段,Vue实例仍然有用,可以进行最后的清理和资源管理。

8、destroyed():在实例销毁之后在调用。在这个阶段,Vue实例和它的所有指令已经被完全销毁,可以进行最后的清理工作。

除以上的是生命周期钩子函数,含有其他一些事件钩子函数,如beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave等。

  1. Sql中的逻辑运算符?

在SQL中,逻辑运算符包括以下三种:

AND:用于逻辑与运算,即只有在所有的条件都为真的情况下,才返回true,否则返回false。

OR:用于逻辑或运算,即只需要满足任意一个条件为真,就返回true。

NOT:用于逻辑非运算,即对一个条件进行取反操作,如果原条件为true,则返回false,反之亦然。

  1. ArrayList和LinkList的区别

ArrayList和LinkedList是两种常见的列表实现方式,它们最显著的不同点在于数据的存储和操作的速度。

ArrayList是以数组的形式实现的动态数组,其内部以数组的形式存储数据,因此可以随机访问任何一个元素,访问速度非常快。由于ArrayList底层是基于数组实现的,在内存中需要连续的空间分配以保证性能,所以在插入或删除元素时,需要进行大量的数据移动,导致效率较低。

LinkedList是以链表的形式存储数据,其每个节点包含两个属性,一个是数据本身,另一个是指向下一个节点的指针。由于LinkedList底层是基于链表实现的,在内存中不需要连续的空间分配,可以在插入或删除元素时快速的调整指针,不需要进行大量的数据移动,因此LinkedList对于随机元素的读取效率较低,但是对于插入、删除元素的操作效率较高。

综上所述,ArrayList适用于随机访问单个元素的场景,而LinkedList适用于需要高效插入、删除元素的场景。

下面是ArrayList和LinkedList的比较:

1. 数据存储方式

ArrayList底层采用动态数组的方式存储数据,访问单个元素速度快,但是插入和删除元素需要大量元素移动,效率较低。

LinkedList底层采用链表的方式存储数据,每个节点包含指向下一个节点的指针,插入和删除元素时调整指针即可,非常高效,但是访问单个元素需要遍历整个链表,效率较低。

2. 内存空间

ArrayList在创建时需要指定大小,当容量不足时,需要创建一个更大的数组,将原数组元素拷贝到新数组中,因此会浪费一些空间。而LinkedList每个节点只需要存储本身的数据与指向下一个节点的指针,内存占用相对较小。

3. 插入和删除操作

ArrayList在插入或删除一个元素时,需要将该元素后面的所有元素后移一位或前移一位,效率低下。而LinkedList插入或删除一个元素时,只需要调整指针即可,效率比ArrayList高。

4. 访问操作

ArrayList采用数组的方式存储元素,因此支持随机访问某个元素,时间复杂度为O(1)。而LinkedList是通过遍历整个链表才能访问某个元素,时间复杂度为O(n)。

总的来说,ArrayList适合读取需求高、修改需求低的情况,而LinkedList适合插入、删除需求高、读取需求相对较低的情况。

  1. 数据库常用函数?

1. COUNT:用于统计表中的行数或查询结果集中的行数。

2. SUM:用于计算指定列的数值总和。

3. AVG:用于计算指定列的平均值。

4. MAX:用于找出指定列的最大值。

5. MIN:用于找出指定列的最小值。

6. UPPER / LOWER:用于将文本类型的列转换为大写或小写。

7. SUBSTR:用于截取字符串的一部分。

8. CONCAT:用于将两个或多个字段连接在一起。

9. TRIM:用于删除指定字符串或空格字符。

10. ROUND:用于取整或四舍五入。

11. YEAR / MONTH / DAY:用于从日期中提取年、月、日。

12. NOW / CURRENT_TIMESTAMP:用于获取当前的日期和时间。

13. DATEADD / DATEDIFF:用于添加或减去日期的一部分(如天数、小时、分钟等)。

14. CAST / CONVERT:用于将一个数据类型转换为另一个数据类型。

15. COALESCE:用于返回第一个非 NULL 值。

7、集合中 Set List Map的区别

1. List

List是有序的集合,可以有重复的元素,可以根据下标(index)访问元素,可以用Iterator来遍历它的元素。List主要有三种实现:ArrayList、LinkedList和Vector。ArrayList和LinkedList都是基于列表实现的,它们的主要区别是在元素的添加和删除方面。ArrayList的添加和删除速度较慢,但是它的随机访问速度非常快,而LinkedList的添加和删除速度非常快,但是它随机访问的速度较慢。Vector是线程安全的,但其性能较差,因为它是同步的。

2. Set

Set是无序的集合,不可以有重复的元素(如果有的话,后加的会覆盖掉前面的元素),可以用Iterator来遍历它的元素。Set的主要实现有HashSet、TreeSet和LinkedHashSet。HashSet内部是基于哈希表实现的,插入、删除和查找元素的速度非常快;TreeSet基于红黑树实现,插入、删除和查找元素的速度较快,而且元素有序;LinkedHashSet在HashSet的基础上,元素的遍历顺序跟插入顺序一致。

3. Map

Map是一种键值对映射的数据结构,它保存了对象间的映射关系,并且键不允许重复。Map主要的实现类有HashMap、TreeMap、LinkedHashMap、WeakHashMap等。HashMap是基于哈希表实现的,它们插入、删除和查找元素的速度非常快,但是元素的遍历顺序不确定;TreeMap可以使键保持有序,插入、删除和查找元素的速度较快;LinkedHashMap在HashMap的基础上,元素的遍历顺序跟插入顺序一致。

8、String常用方法?

1. length():返回字符串的长度。

2. charAt(int index):返回指定位置的字符。

3. substring(int beginIndex):返回从指定位置开始到字符串末尾的子字符串。

4. substring(int beginIndex, int endIndex):返回指定位置之间的子字符串。

5. indexOf(String str):返回字符串中第一次出现指定字符串的位置。

6. lastIndexOf(String str):返回字符串中最后一次出现指定字符串的位置。

7. replace(char oldChar, char newChar):用新字符替换字符串中所有的旧字符。

8. replaceAll(String regex, String replacement):使用一个新字符串替换所有与正则表达式匹配的字符串。

9. toLowerCase():将字符串转换成小写形式。

10. toUpperCase():将字符串转换成大写形式。

11. trim():返回一个去除首尾空格的字符串。

12. startsWith():判断字符串是否以指定的字符串开头。

13. endsWith():判断字符串是否以指定的字符串结尾。

14. equals():判断两个字符串是否相等。

15. equalsIgnoreCase():忽略大小写,判断两个字符串是否相等。

16. split(String regex):按照指定的分隔符把字符串分成多个子字符串。

17. format():将字符串格式化成指定的格式。

18. valueOf():将其他类型的数据转换成字符串类型。

9、验证码在redis中用的什么数据类型

验证码在Redis中通常使用字符串类型(string)存储。具体地,可以将验证码的值作为字符串类型的值存储在Redis中,使用一个唯一的key作为该验证码的标识符。当用户输入验证码时,后台服务器从Redis中获取该验证码的值,与用户输入的值进行比较,以验证该用户的身份。

在使用Redis存储验证码时,需要注意以下几点:

1. 确定验证码的有效期,设置过期时间以保证验证码及时失效。

2. 生成一个唯一的key作为验证码的标识符,可以使用用户的手机号或邮箱作为key,或者生成一个随机的字符串作为key。

3. 在存储验证码时,可以使用SET命令设置键值对,并使用EXPIRE命令设置键的过期时间。

4. 在验证验证码时,可以使用GET命令获取键的值,并与用户输入的值进行比较,注意控制每个验证码的使用次数,避免被利用浪费资源。

10、缓存击穿,缓存穿透,缓存雪崩

缓存技术是解决高并发场景下数据库访问压力较大的一种有效方式。但是,在使用缓存技术时,也会遇到一些问题,比如缓存击穿、缓存穿透和缓存雪崩等问题。

1. 缓存击穿(Cache Breakdown)

缓存击穿是指在高并发的场景中,当一个热点key过期的时候,所有的请求都会导致将这个热点key的数据从数据库中加载并放入缓存。由于在这个热点key过期之后,所有的请求都需要重新从数据库中获取该数据,导致数据库压力大增,甚至会导致数据库宕机。

解决方法:

   (1) 设置热点数据常驻缓存,使用手动过期和更新缓存的方法,而不是简单地依靠过期时间。

   (2) 对于请求量较大的热点key,可以使用布隆过滤器(Bloom Filter)等技术来解决。

   (3) 对于没有查询到任何结果的请求,可以使用空对象(Null Object)或者缓存雪崩中的“半请求保护机制”。

2. 缓存穿透(Cache Penetration)

缓存穿透是指在高并发的场景中,由于缓存中没有所需数据,每个请求都会直接访问数据库,导致数据库压力大增。

常见的攻击方式是使用一些不存在的key或者不存在的ID来请求服务,因此可以在系统的前置校验中对参数进行基本类型、非空、业务合法性的断言校验,避免无效请求的访问后台服务。

解决方法:

   (1) 使用布隆过滤器(Bloom Filter)等技术过滤掉不存在的key或ID,从而避免大量无效请求落到数据库上。

   (2) 对于无法在缓存中查找到的请求,直接返回null或者空对象。

   (3) 对于请求的频率比较高的场景,可以使用缓存预热等技术,将系统常用的数据加载到缓存中,减少数据库访问次数。

3. 缓存雪崩(Cache Collapse)

缓存雪崩是指在高并发的场景中,缓存中大量的数据同时过期,导致大量的请求直接落到数据库上,导致数据库崩溃。

解决方法:

   (1) 对缓存的数据过期时间进行随机化,避免大量的数据同时失效。

   (2) 使用延迟失效策略,缓存的数据失效的时候,把它放到一个待处理数据队列中,并在后台线程中异步更新缓存。

   (3) 使用缓存的二级策略,让不同的数据过期时间错开,不会同时失效。

(4) 对于失效的数据,可以使用半请求保护机制,避免对数据库的连续大量请求。

  1. MySQl一对多?

一个表中的一条记录对应另一个表中的多条记录

  1. 什么是HashMap?

HashMap是一种常用的数据结构,用于在O(1)时间内实现key-value的快速查找。它通过哈希函数对每个key计算出一个索引值,然后将这个key-value存储在对应的索引位置上。

HashMap中的键值对数据是无序的,由哈希表(hash table)来实现存储和查找。

当发生哈希冲突时,HashMap会将新的键值对添加到原有的链表中,因此,当链表长度过长时,查询效率会降低。为了保证好的查询效率,建议将HashMap中最大链表长度通过加载因子进行调整。

HashMap的优点有:查找速度快、插入速度快、支持动态扩容等。

HashMap的内部实现并不是线程安全的,因此,在并发环境中使用时,可能需要进行同步操作,或者选择使用线程安全的ConcurrentHashMap。

  1. Mybatis和MybatisPlus的区别

MyBatis和MyBatis-Plus都是基于Java语言的持久层框架,相对于原生的JDBC,它们都简化了与关系型数据库的交互过程。

MyBatis是一个半自动化的ORM框架,即对象和SQL语句都要手动编写,它绑定Sql和java对象,封装了JDBC操作数据库的底层细节。

MyBatis-Plus在MyBatis的基础上提供了更多的便捷和高级特性,如基于注解和反射的无XML操作、通用CRUD操作、分页插件、性能分析插件、代码生成器等等。其中最核心的是基于泛型的 `BaseMapper`,可以极大地减少DAO层的代码量。

总的来说,MyBatis是一个轻量级的ORM框架,使用简便,拓展性高,适合对SQL比较熟悉的开发者使用;MyBatis-Plus在MyBatis基础上,提供更方便的增删改查操作和额外的功能插件,适合集成度较高的企业应用。

4HashMap和HashTable的区别?

HashMap和Hashtable都是实现了Map接口的类,提供了KeyValue键值对的存储和检索功能。它们的主要区别如下:

1. 线程安全性:Hashtable是线程安全的,它的每个方法都是同步方法;而HashMap是非线程安全的,多个线程对同一个HashMap进行并发修改可能会产生不可预料的结果。

2. 空键空值:Hashtable不允许键或值为空(null);而HashMap可以,它允许一个为空的键和多个为空的值。

3. 迭代器:迭代器Iterator遍历 Hashtable时,不保证按照插入时间的顺序遍历;而HashMap中,迭代器按照插入的顺序遍历。

4. 继承:Hashtable继承自Dictionary类,而HashMap继承自AbstractMap类,它们的父类不同。

5. 性能:HashMap的性能比Hashtable更好,因为Hashtable在每次操作时都需要进行同步锁定,而HashMap不需要。

综上所述,如果不考虑线程安全的因素,建议使用HashMap,因为HashMap性能更好。如果需要对多个线程同时访问同一个Map时保证线程安全,可以使用Hashtable。

5、Redis主从了解吗?Redis 哨兵了解吗?

(1) 主从:为了避免单点Redis服务器故障,准备多台服务器,互相连通。将数据复制多个副本保存在不同的服务器上,连接在一起,并保证数据是同步的。

(2) 即使有其中一台服务器宕机,其他服务器依然可以继续提供服务,实现Redis的高可用,同时实现数据冗余备份。

(3) 哨兵:是一种特殊的模式,首先 Redis 提供了哨兵的命令,哨兵是一个独立的进程,作为进程,它会独立运行。其原理是哨兵通过发送命令,Redis服务器响应,从而监控运行的多个 Redis 实例。

6、Redis集群了解吗?什么是集群

(1) Redis 集群是一个分布式(distributed)、容错(fault-tolerant)的 Redis 实现, 集群可以使用的功能是普通单机 Redis 所能使用的功能的一个子集(subset)。

(2) Redis 集群中不存在中心(central)节点或者代理(proxy)节点, 集群的其中一个主要设计目标是达到线性可扩展性(linear scalability)。

(3) Redis 集群提供了一种运行 Redis 的方式,其中数据在多个 Redis 节点间自动分区。Redis 集群还在分区期间提供一定程度的可用性,即在实际情况下能够在某些节点发生故障或无法通信时继续运行。但是,如果发生较大故障(例如,大多数主站不可用时),集群会停止运行。

7、扫描识别application.properties或application.yml

使用@PropertySource(“定义扫描配置”)

8、什么是缓存雪崩?

同一时间点,大量key一起过期,造成数据库压力大,系统崩溃。

有几种可能,第一种可能是Redis宕机,第二种可能是采用了相同的过期时间。

如何避免?

1. 缓存时间设置的有一定随机性: 固定值 + 随机值

2. 构建多级缓存: 本地缓存 + redis缓存

3. 服务熔断 - 服务降级

9、什么是Redis?

非关系型数据库,redis数据存在内存中,读写速度快,广泛应用于缓存,是已知性能最快的key_value数据库

10、主从复制原理

Redis 的复制(replication)功能允许用户根据一个 Redis 服务器来创建任意多个该服务器的复制品,其中被复制的服务器为主服务器(master),而通过复制创建出来的服务器复制品则为从服务器(slave)。 只要主从服务器之间的网络连接正常,主从服务器两者会具有相同的数据,主服务器就会一直将发生在自己身上的数据更新同步 给从服务器,从而一直保证主从服务器的数据相同。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值