面试常见问题

面试详解

1.单例模式

单:唯一 例:实例

1.1 饿汉模式

饿汉式:在类初始化时直接创建对象,不管你是否需要这个对象都会创建,不存在线程安全问题

直接实例化饿汉式(简洁直观)

/*
饿汉式:在类初始化时直接创建对象,不管你是否需要这个对象都会创建,不存在线程安全问题
(1)构造器私有化
(2)自行创建,并且用静态变量保存
(3)向外提供这个实例
(4)强调这是一个单例,可以用final修改
*/
public class Singleton1{
public static final Singleton1 INSTANCE = new Singleton1();
private Singleton(){
}
}

枚举式(最简洁)

/* 饿汉式:枚举式(最简洁) 枚举类型:表示该类型的对象是有限的几个 我们可以限定为一个,就成了单例 */

public enum Singleton2{

INSTANCE

}

静态代码块(适合复杂实例化)

/**
饿汉式:静态代码块(适合复杂实例化)
*/
public class Singleton3 {
public static final Singleton3 INSTANCE;
static {
INSTANCE = new Singleton3();
}
}

1.2 懒汉模式

懒汉式:延迟创建实例对象对象

线程不安全(适用于单线程)

/*
懒汉式:延迟创建实例对象对象
线程不安全(适用于单线程)
(1)构造器私有化
(2)用一个静态变量保存这个唯一的实例
(3)提供一个静态方法,获取这个实例对象
*/
public class Singleton4{
private static Singleton4 instance
private Singleton4(){
}
public static Singleton4 getInstance(){
if(instance == null){
instance = new Singleton4();
}
return instance;
}
}

(加了锁) 线程安全(适用于多线程)

/*
懒汉式:延迟创建实例对象对象
(加了锁)
线程安全(适用于多线程)
(1)构造器私有化
(2)用一个静态变量保存这个唯一的实例
(3)提供一个静态方法,获取这个实例对象
*/
public class Singleton5 {
private static Singleton5 instance;
private Singleton5() {}
public static Singleton5 getInstance() {
if (instance == null) {
synchronized (Singleton5.class) {
if (instance == null) {
instance = new Singleton5();
}
return instance;
}
}
return instance;
}
}

静态内部类形式(适用于多线程)*

/*
懒汉式:延迟创建实例对象对象
静态内部类形式(适用于多线程)
在内部类被加载和初始化时,才创建INSTANCE实例对象
静态内部类不会自动随着外部类的加载和初始化而初始化,它是单独去加载和初始化的
因为是在内部类加载和初始化时,创建的,因此是线程安全的
*/
public class Singleton6 {

private Singleton6() {}
public static class Inner() {
	private static Singleton6 INSTANCE = new Singleton6();
}
public static Singleton6 getInstance(){
	return Inner.INSTANCE;
}

}

2.重写

方法的重写

(1)哪些方法不可以被重写
final方法
静态方法
private等子类中不可见的方法
(2)对象的多态性
子类如果重写了父类的方法,通过子类对象调用的一定是子类重写过得代码
非静态方法默认的调用对象是this
this对象在构造器或则说方法中就是正在创建的对象

3.Spring支持的常用数据库事务传播属性和事务隔离级别

3.1 什么是事务

事务是数据库操作最基本单元,逻辑上一组操作,要么都成功,如果有一个失败,所有操作都失败

8.2 事务的四个特性(ACID)

原子性(Atomicity) 一个事务(transaction)中的所有操作,或者全部完成,或者全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。即,事务不可分割、不可约简。
一致性(Consistency) 在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设约束、触发器、级联回滚等。
隔离性(Isolation) 数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括未提交读(Read uncommitted)、提交读(read committed)、可重复读(repeatable read)和串行化(Serializable)。
持久性(Durability) 事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。

3.3 事务的传播行为(propagation)

REQUIRED 如果有事务在运行,当前的方法就在这个事务内运行,否则就启动一个新的事务,并在自己的事务内运行
REQUIRED_NEW 当前方法必须启动事务,并在它自己的事务内运行,如果有事务正在运行,应该将他挂起
SUPPORTS 如果有事务在运行,当前的方法就在这个事务内运行,否则他可以不运行在事务中
NOT_SUPPORTE 当前的方法不应该运行在事务中,如果有运行的事务,将他挂起
MANDATORY 当前的方法必须运行在事务内部,如果没有正在运行的事务,就抛出异常
NEVER 当前方法不应该运行在事务中,如果有运行的事务,就抛出异常
NESTED 如果有事务在运行,当前的方法就应该在这个事物的嵌套事务内运行,否则,就启动一个新的事务,并在它自己的事务内运行

3.4 事务的隔离级别(isolation)

3.4.1 不隔离出现的三个问题

1.脏读:一个未提交事务读取到另一个未提交事务的数据
2.不可重复读:一个未提交事务读取到另一提交事务修改数据
3.虚读:一个未提交事务读取到另一提交事务添加数据

3.4.2 解决:设置事务隔离级别

隔离级别 脏读 不可重复读 虚读
READ UNCOMMITTED(读未提交) 有 有 有
READ COMMITTED(读已提交) 无 有 有
REPEATABLE READ(可重复读) 无 无 有
SERIALIZABLE(串行化) 无 无 无

3.5 面试题

请简单介绍Spring支持的常用数据库事务传播属性和事务隔离级别?

事务的属性:
1.propagation:用来设置事务的传播行为
事务的传播行为:一个方法运行在了一个开启了事务的方法中时,当前方法是使用原来的事务还是开启一个新的事务
-Propagation.REQUIRED:默认值,使用原来的事务
-Propagation.REQUIRES_NEW:将原来的事务挂起,开启一个新的事务
2.isolation:用来设置事务的隔离级别
-Isolation.REPEATABLE_READ:可重复读,MySQL默认的隔离级别
-Isolation.READ_COMMITTED:读已提交,Oracle默认的隔离级别,开发时通常使用的隔离级别

4. Mybatis中当实体类中的属性名和表中的字段名不一样,怎么办?

4.1 解决方案:

1.写sql语句的时候起别名
  方式一:使用as
	select last_name AS 姓,first_name AS 名 from employees;
  方式二:使用空格
	select last_name 姓,first_name 名 from employees;
2.在Mybaits的全局配置文件中开启驼峰命名规则
	可以将数据库中的下划线映射为驼峰命名
	例如:last_name 可以映射为lastName
<settings>
	<setting name="mapUnderscoreToCameCase" value="true">
</settings>
3.在Mapper映射文件中自定义文件中使用resultMap自定义映射
	<resultMap type="com.atguigu.pojo.Employee" id="myMap">
	    <!-- 映射主键 -->
		<id cloumn="id" property="id"/>
	    <!-- 映射其他列 -->
	    <result column="last_name" property="lastName" />
	    <result column="email" property="email" />
	    <result column="salary" property="salary" />
	    <result column="dept_id" property="deptId" />
	</resultMap>

5.MySQL索引

5.1 简介

MySQL官方对索引的定义为:
索引(Index)是帮助MySQL高效获取数据的数据结构。
可以得到索引的本质:索引是数据结构

5.2 适合建立索引的情况

主键自动建立唯 一 索引
频繁作为查询条件的字段应该创建索引
查询中与其它表关联的字段,外键关系建立索引
频繁更新的字段不适合创建索引,因为每次更新不单是更新了记录还会更新索引
单键组索引的选择问题,who? 在高并发下领向创建组合索引
意询中排序的字段,排序字段若通过索引法访问将大大提高排序速度
查询中统计或者分组字段

5.3 不适合建立索引的情况

表记录太少
经常增删改的表或则字段
Where条件里用不到的字段不创建索引
过滤性不好的不适合创建索引

6.JVM

面试题:JVM垃圾回收机制、GC发生在JVM哪部分,有几种GC,他们的算法是什么

1.GC发生在堆区
2.GC就是分代收集算法:
次数上频繁收集Young区 (Minor GC )
次数上较少收集old区 ( Full GC)
基本不动元空间(Perm区)
3.GC四大算法:
(1)引用计数法
(2)复制算法
(3)标记清除
(4)标记压缩

7.redis在项目中的使用场景

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Vr9wzEVp-1656163665550)(C:\Users\xx\AppData\Roaming\Typora\typora-user-images\1653642439167.png)]

8.购物车实现过程

购物车:

1、购物车跟用户的关系 ?
(1)一个用户必须对应一个购物车【一个用户不管买多少商品,都会存在属于自己的购物车中】
(2)单点登录一定要在购车前
2、跟购物车有关的操作有那些?
(1)添加购物车

用户未登录状态

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kyerZvQ3-1656163665553)(C:\Users\xx\AppData\Roaming\Typora\typora-user-images\1653642525609.png)]
用户登录状态

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zvnI889v-1656163665554)(C:\Users\xx\AppData\Roaming\Typora\typora-user-images\1653642545226.png)]

(2)展示购物车

未登录状态显示

1.直接从 cookie 中取得数据展示即可

登录状态

  1. 用户一旦登录,必须显示数据库【redis】 + cookie 中的购物车的数据
  2. (1)Cookie 中有三条记录
  3. (2)Redis 中有五条记录
  4. (3)真正展示的时候应该是八条记录

9. AOP

(Aspect Orient Programming),直译过来就是 面向切面编程,AOP 是一种编程思想,是面向对象编程(OOP)的一种补充。

面向切面编程,实现在不修改源代码的情况下给程序动态统一添加额外功能的一种技术

面向切面编程,实现在不修改源代码的情况下给程序动态统一添加额外功能的一种技术

面试过程

1.自我介绍

2.实习经历

3.公司组成----研发小组有多少人

面试题总结

1.Java的四种访问权限

Java中有四种访问权限,分别是「public、protected、包访问权限(默认)、private」,如果省略了访问修饰符,那默认访问权限为「包访问权限」。 这四种权限从「最大权限」到「最小权限」分别是: public > protected > 包访问权限> private

2.详细讲解访问权限

「包访问权限:」 没有任何修饰符的权限就是「包访问权限」,意味着当前包的所有类都可以访问这个成员,如表中所示,对于本包之外的类,这个成员就变成了「private」,访问不了

「public:」 被public修饰的成员对任意一个类都是可用的,任何一个类都可以访问到,通过操作该类的对象随意访问「public」成员

「protected:」 在相同的class内部,同一个包内和其他包的子类中能被访问。要理解「protected」权限,就需要了解「继承」,因为这个权限处理的就是继承相关的概念,继承而来的子类可以访问「public、protected」,

「private:」 除了包含这个成员的类之外,所有类都无法访问这个成员,相当于自我封闭,防止其他类改变或删除这个方法

3.重载和重写的区别

重载: 发生在同一个类中,方法名必须相同,参数类型不同.个数不同.顺序不同, 方法返回值和访问修饰符可以不同,发生在编译时。

重写: 发生在父子类中,方法名.参数列表必须相同,返回值范围小于等于父类, 抛出的异常范围小于等于父类, 访问修饰符范围大于等于父类;如果父类方法访问修饰符为 private 则子类就不能 重写该方法。

4.接口和抽象类的区别是什么?

实现:抽象类的子类使用 extends 来继承;接口必须使用 implements 来实现接 口。

构造函数:抽象类可以有构造函数;接口不能有。

main 方法:抽象类可以有 main 方法,并且我们能运行它;接口不能有 main 方 法。

实现数量:类可以实现很多个接口;但是只能继承一个抽象类。

访问修饰符:接口中的方法默认使用 public 修饰;抽象类中的方法可以是任意访问修饰符

5.数据库的连接方式

连接查询的概念

连接查询是关系数据库中最主要的查询,主要包括自连接、内连接、外连接和交叉连接。通过连接运算符可以实现多个表查询。连接是关系数据库模型的主要特点,也是它区别于其它类型数据库管理系统的一个标志。 在关系数据库管理系统中,表建立时各数据之间的关系不必确定,常把一个实体的所有信息存放在一个表中。当检索数据时,通过连接操作查询出存放在多个表中的不同实体的信息。连接操作给用户带来很大的灵活性,他们可以在任何时候增加新的数据类型。为不同实体创建新的表,然后通过连接进行查询。

连接查询的方式

1.交叉连接

交叉连接即笛卡儿乘积,是指两个关系中所有元组的任意组合。一般情况下,交叉查询是没有实际意义的。

例如:如果希望得到学生表和选课表两个关系模式的乘积,查询语句为

SELECT ***** FROM学生表CROSS JOIN选课表

2.内连接

内连接是一种最常用的连接类型。内连接查询实际上是一种任意条件的查询。使用内连接时,如果两个表的相关字段满足连接条件,就从这两个表中提取数据并组合成新的记录,也就是在内连接查询中,只有满足条件的元组才能出现在结果关系中。

例如:要查询每个已经选课的学生的情况,查询语句为

SELECT ***** FROM学生表INNER JOIN选课表ON学生表.学号=选课表.学号

3.根据比较方式分类:

**等值连接:**在连接条件中使用等于号(=)运算符比较被连接列的列值,其查询结果中列出被连接表中的所有列,包括其中的重复列。

**不等连接:**在连接条件使用除等于运算符以外的其它比较运算符比较被连接的列的列值。这些运算符包括>、>=、<=、<、!>、!<和<>。

**自然连接:**在连接条件中使用等于(=)运算符比较被连接列的列值,但它使用选择列表指出查询结果集合中所包括的列,并删除连接表中的重复列。

4.自连接

如果在一个连接查询中,涉及到的两个表都是同一个表,这种查询就称为自连接查询。同一张表在FROM字句中多次出现,为了区别该表的每一次出现,需要为表定义一个别名。自连接是一种特殊的内连接,它是指相互连接的表在物理上为同一张表,但可以在逻辑上分为两张表。

例如:要求检索出学号为20210的学生的同班同学的信息,查询语句为

SELECT学生表 ***** FROM学生表JOIN学生表AS学生表1ON学生表.班级=学生表1.班级

WHERE学生表1.学号=‘20210’

5.外连接

内连接的查询结果都是满足连接条件的元组。但有时我们也希望输出那些不满足连接条件的元组信息。比如,我们想知道每个学生的选课情况,包括已经选课的学生(这部分学生的学号在学生表中有,在选课表中也有,是满足连接条件的),也包括没有选课的学生(这部分学生的学号在学生表中有,但在选课表中没有,不满足连接条件),这时就需要使用外连接。外连接是只限制一张表中的数据必须满足连接条件,而另一张表中的数据可以不满足连接条件的连接方式。

左外连接(LEFTOUTER JOIN)

如果在连接查询中,连接管子左端的表中所有的元组都列出来,并且能在右端的表中找到匹配的元组,那么连接成功。如果在右端的表中,没能找到匹配的元组,那么对应的元组是空值(NULL)。这时,查询语句使用关键字LEFT OUTERJOIN,也就是说,左外连接的含义是限制连接关键字右端的表中的数据必须满足连接条件,而不关左端的表中的数据是否满足连接条件,均输出左端表中的内容。

例如:要查询所有学生的选课情况,包括已经选课的和还没有选课的学生,查询语句为

SELECT学生表.学号,姓名,班级,课程号,成绩 FROM学生表LEFT OUTER JOIN选课表ON学生表.学号=选课表.学号

左外连接查询中左端表中的所有元组的信息都得到了保留。

右外连接(RIGHTOUTERJOIN)

右外连接与左外连接类似,只是右端表中的所有元组都列出,限制左端表的数据必须满足连接条件,而不管右端表中的数据是否满足连接条件,均输出表中的内容。

例如:同上例内容,查询语句为

SELECT学生表.学号,姓名,班级,课程号,成绩

FROM学生表RIGHTOUTERJOIN选课表ON学生表.学号=选课表.学号

右外连接查询中右端表中的所有元组的信息都得到了保留。

全外连接(FULL OUTER JOIN)

全外连接查询的特点是左、右两端表中的元组都输出,如果没能找到匹配的元组,就使用NULL来代替。

例如:同左外连接例子内容,查询语句为

SELECT学生表.学号,姓名,班级,课程号,成绩 FROM学生表FULL OUTER JOIN选课表ON学生表.学号=选课表.学号

全外连接查询中所有表中的元组信息都得到了保留。

6.Java连接数据库的四种方式

1.类驱动。这就是JDBC-ODBC桥的方式。

但这种方式不适合程序的重用与维护,不推荐使用。需要数据库的ODBC驱动。

2.类驱动。这就是JDBC+厂商API的形式。

厂商API一般使用C编写,所以,这种方式也不长使用。

3.类驱动。这就是JDBC+厂商Database Connection Server+DataBase的形式。

这种方法就是在JAVA 与 DATABASE之间价起了一台专门用与数据库连接的服务器(一般由数据库厂商提供)。

他的好处在于能优化连接。

4.类驱动。这就是纯JDBC+DATABASE的连接方式。也是推荐的连接方式。

这使得APPLICATION与数据库分开,开发者只需关心内部逻辑的实现而不需注重数据库连接的具体实现。

在这其中有两种连接的方式:硬编码方式,就是在程序中硬性编入数据库连接的所须参数。

JNDI DataSource方式。就是在程序运行的外布环境中又称(Context)设置一个datasource数据源,有一个jndi 名称,程序只须查找此名称就可得到一个数据库连接的对象

7.SQL语法

8.前端页面是如何搭建的(不知道)

9.B/S C/S

9.1 B/S结构

B是英文单词“Browser”的首字母,即浏览器的意思;S是英文单词“Server”的首字母,即服务器的意思。B/S就是“Browser/Server”的缩写,即“浏览器/服务器”模式。

B/S结构是随着互联网的发展,web出现后兴起的一种网络结构模式。这种模式统一了客户端,让核心的业务处理在服务端完成。你只需要在自己电脑或手机上安装一个浏览器,就可以通过web Server与数据库进行数据交互。

9.2 C/S结构

C是英文单词“Client”的首字母,即客户端的意思,C/S就是“Client/Server”的缩写,即“客户端/服务器”模式。

C/S结构是一种软件系统体系结构,也是生活中很常见的。这种结构是将需要处理的业务合理地分配到客户端和服务器端,这样可以大大降低通信成本,但是升级维护相对困难。比如我们手机中安装的微信、qq、王者荣耀等应用程序就是C/S结构。

9.3 B/S结构和C/S结构的区别

硬件环境不同,C/S通常是建立在专用的网络上,小范围的网络环境。而B/S是建立在广域网上的,适应范围强,通常有操作系统和浏览器就行;

C/结构比B/S结构更安全,因为用户群相对固定,对信息的保护更强;

B/S结构维护升级比较简单,而C/S结构维护升级相对困难;

10.内存泄漏和内存溢出

什么是内存泄漏和内存溢出?

(溢出是指创建太多对象导致内存空间不足,泄漏是无用对象没有回收)

11.JVM怎么判断对象是无用对象?

根搜索算法,从GC Root出发,对象没有引用,就判定为无用对象

面试常见问题补充

1.系统的架构图

可以将Dubbo换成SpringCloud

做过分布式电商系统的一定很熟悉上面的架构图(目前比较流行的是微服务架构,但是如果你有分布式开发经验也是非常加分的!)

2.介绍项目

我: 我一本正经的对着我刚刚画的商城架构图开始了满嘴造火箭的讲起来:

本系统主要分为展示层、服务层和持久层这三层。表现层顾名思义主要就是为了用来展示,比如我们的后台管理系统的页面、商城首页的页面、搜索系统的页面等等,这一层都只是作为展示,并没有提供任何服务。

展示层和服务层一般是部署在不同的机器上来提高并发量和扩展性,那么展示层和服务层怎样才能交互呢?在本系统中我们使用SpringCloud 来进行服务治理。SpringCloud 是一款高性能、轻量级的开源 Java RPC 框架。SpringCloud 在本系统的主要作用就是提供远程 RPC 调用。在本系统中服务层的信息通过 SpringCloud 注册给 Nacos,表现层通过SpringCloud去 Nacos 中获取服务的相关信息。Nacos 的作用仅仅是存放提供服务的服务器的地址和一些服务的相关信息,实现 RPC 远程调用功能的还是SpringCloud。如果需要引用到某个服务的时候,我们只需要在配置文件中配置相关信息就可以在代码中直接使用了,就像调用本地方法一样。假如说某个服务的使用量增加时,我们只用为这单个服务增加服务器,而不需要为整个系统添加服务。

另外,本系统的数据库使用的是常用的 MySQL,并且用到了数据库中间件 MyCat。另外,本系统还用到 redis 内存数据库来作为缓存来提高系统的反应速度。假如用户第一次访问数据库中的某些数据,这个过程会比较慢,因为是从硬盘上读取的。将该用户访问的数据存在数缓存中,这样下一次再访问这些数据的时候就可以直接从缓存中获取了。操作缓存就是直接操作内存,所以速度相当快。

系统还用到了 Elasticsearch 来提供搜索功能。使用 Elasticsearch 我们可以非常方便的为我们的商城系统添加必备的搜索功能,并且使用 Elasticsearch 还能提供其它非常实用的功能,并且很容易扩展

面试官: 我看你的系统里面还用到了消息队列,能说说为什么要用它吗?

我:

使用消息队列主要是为了:

  1. 减少响应所需时间和削峰。
  2. 降低系统耦合性(解耦/提升系统可扩展性)。

面试官: 你这说的太简单了!能不能稍微详细一点,最好能画图给我解释一下。

我: 内心 os:“都 2019 年了,大部分面试者都能对消息队列的为系统带来的这两个好处倒背如流了,如果你想走的更远就要别别人懂的更深一点!”

当我们不使用消息队列的时候,所有的用户的请求会直接落到服务器,然后通过数据库或者缓存响应。假如在高并发的场景下,如果没有缓存或者数据库承受不了这么大的压力的话,就会造成响应速度缓慢,甚至造成数据库宕机。但是,在使用消息队列之后,用户的请求数据发送给了消息队列之后就可以立即返回,再由消息队列的消费者进程从消息队列中获取数据,异步写入数据库,不过要确保消息不被重复消费还要考虑到消息丢失问题。由于消息队列服务器处理速度快于数据库,因此响应速度得到大幅改善。

文字 is too 空洞,直接上图吧!下图展示了使用消息前后系统处理用户请求的对比(ps:我自己都被我画的这个图美到了,如果你也觉得这张图好看的话麻烦来个素质三连!)。

通过异步处理提高系统性能

3.项目出现的问题

面试官**:做项目的过程中遇到了什么问题吗?解决了吗?如果解决的话是如何解决的呢?

: 内心 os: “做的过程中好像也没有遇到什么问题啊!怎么办?怎么办?突然想到可以说我在使用 Redis 过程中遇到的问题,毕竟我对 Redis 还算熟悉嘛,把面试官往这个方向吸引,准没错。”

我在使用 Redis 对常用数据进行缓冲的过程中出现了缓存穿透问题。然后,我通过谷歌搜索相关的解决方案来解决的。

面试官: 你还知道缓存穿透啊?不错啊!来说说什么是缓存穿透以及你最后的解决办法。

我: 我先来谈谈什么是缓存穿透吧!

缓存穿透说简单点就是大量请求的 key 根本不存在于缓存中,导致请求直接到了数据库上,根本没有经过缓存这一层。举个例子:某个黑客故意制造我们缓存中不存在的 key 发起大量请求,导致大量请求落到数据库。

总结一下就是:

  1. 缓存层不命中。
  2. 存储层不命中,不将空结果写回缓存。
  3. 返回空结果给客户端。

一般 MySQL 默认的最大连接数在 150 左右,这个可以通过 show variables like '%max_connections%';命令来查看。最大连接数一个还只是一个指标,cpu,内存,磁盘,网络等物理条件都是其运行指标,这些指标都会限制其并发能力!所以,一般 3000 的并发请求就能打死大部分数据库了。

面试官: 小伙子不错啊!还准备问你:“为什么 3000 的并发能把支持最大连接数 4000 数据库压死?”想不到你自己就提前回答了!不错!

我: 别夸了!别夸了!我再来说说我知道的一些解决办法以及我最后采用的方案吧!您帮忙看看有没有问题。

最基本的就是首先做好参数校验,一些不合法的参数请求直接抛出异常信息返回给客户端。比如查询的数据库 id 不能小于 0、传入的邮箱格式不对的时候直接返回错误消息给客户端等等。

参数校验通过的情况还是会出现缓存穿透,我们还可以通过以下几个方案来解决这个问题:

1)缓存无效 key : 如果缓存和数据库都查不到某个 key 的数据就写一个到 redis 中去并设置过期时间,具体命令如下:SET key value EX 10086。这种方式可以解决请求的 key 变化不频繁的情况,如何黑客恶意攻击,每次构建的不同的请求 key,会导致 redis 中缓存大量无效的 key 。很明显,这种方案并不能从根本上解决此问题。如果非要用这种方式来解决穿透问题的话,尽量将无效的 key 的过期时间设置短一点比如 1 分钟。

另外,这里多说一嘴,一般情况下我们是这样设计 key 的: 表名:列名:主键名:主键值

2)布隆过滤器: 布隆过滤器是一个非常神奇的数据结构,通过它我们可以非常方便地判断一个给定数据是否存在于海量数据中。我们需要的就是判断 key 是否合法,有没有感觉布隆过滤器就是我们想要找的那个“人”。

面试官: 不错不错!你还知道布隆过滤器啊!来给我谈一谈。

我: 内心 os:“如果你准备过海量数据处理的面试题,你一定对:“如何确定一个数字是否在于包含大量数字的数字集中(数字集很大,5 亿以上!)?”这个题目很了解了!解决这道题目就要用到布隆过滤器。”

布隆过滤器在针对海量数据去重或者验证数据合法性的时候非常有用。布隆过滤器的本质实际上是 “位(bit)数组”,也就是说每一个存入布隆过滤器的数据都只占一位。相比于我们平时常用的的 List、Map 、Set 等数据结构,它占用空间更少并且效率更高,但是缺点是其返回的结果是概率性的,而不是非常准确的。

当一个元素加入布隆过滤器中的时候,会进行如下操作:

  1. 使用布隆过滤器中的哈希函数对元素值进行计算,得到哈希值(有几个哈希函数得到几个哈希值)。
  2. 根据得到的哈希值,在位数组中把对应下标的值置为 1。

当我们需要判断一个元素是否存在于布隆过滤器的时候,会进行如下操作:

  1. 对给定元素再次进行相同的哈希计算;
  2. 得到值之后判断位数组中的每个元素是否都为 1,如果值都为 1,那么说明这个值在布隆过滤器中,如果存在一个值不为 1,说明该元素不在布隆过滤器中。

举个简单的例子:

布隆过滤器hash计算

如图所示,当字符串存储要加入到布隆过滤器中时,该字符串首先由多个哈希函数生成不同的哈希值,然后在对应的位数组的下表的元素设置为 1(当位数组初始化时 ,所有位置均为 0)。当第二次存储相同字符串时,因为先前的对应位置已设置为 1,所以很容易知道此值已经存在(去重非常方便)。

如果我们需要判断某个字符串是否在布隆过滤器中时,只需要对给定字符串再次进行相同的哈希计算,得到值之后判断位数组中的每个元素是否都为 1,如果值都为 1,那么说明这个值在布隆过滤器中,如果存在一个值不为 1,说明该元素不在布隆过滤器中。

不同的字符串可能哈希出来的位置相同,这种情况我们可以适当增加位数组大小或者调整我们的哈希函数。

综上,我们可以得出:布隆过滤器说某个元素存在,小概率会误判。布隆过滤器说某个元素不在,那么这个元素一定不在。

面试官: 看来你对布隆过滤器了解的还挺不错的嘛!那你快说说你最后是怎么利用它来解决缓存穿透的。

我: 知道了布隆过滤器的原理就之后就很容易做了。我是利用 Redis 布隆过滤器来做的。我把所有可能存在的请求的值都存放在布隆过滤器中,当用户请求过来,我会先判断用户发来的请求的值是否存在于布隆过滤器中。不存在的话,直接返回请求参数错误信息给客户端,存在的话才会走下面的流程。总结一下就是下面这张图(这张图片不是我画的,为了省事直接在网上找的):

更多关于布隆过滤器的内容可以看我的这篇原创:《不了解布隆过滤器?一文给你整的明明白白!》 ,强烈推荐,个人感觉网上应该找不到总结的这么明明白白的文章了。

4.补充问题

4.1 B树和B+树的区别

1、B树

B树是一种自平衡的搜索树,形式很简单:

img

这就是一颗B-树。针对我们这个问题的最核心的特点如下:

(1)多路,非二叉树

(2)每个节点既保存索引,又保存数据

(3)搜索时相当于二分查找

** 2、 B+树**

B+树是B树的变种

img

最核心的特点如下:

(1)多路非二叉

(2)只有叶子节点保存数据

(3)搜索时相当于二分查找

(4)增加了相邻接点的指向指针。

从上面我们可以看出最核心的区别主要有俩,

一个是数据的保存位置:B树保存在所有的节点中,B+树保存在叶子节点

一个是相邻节点的指向:B树叶子节点之间没有指针,B+树有

3、从区别找特点

第一:查找元素

(1)B树的数据保存在所有节点,查询复杂度最好是 O(1)。

(2)B+树的数据保存在叶子节点,查询时间复杂度固定是O(log(n))

第二:区间查找

(1)B树每个节点 key 和 data 在一起,则无法区间查找。

(2)B+树相邻接点的指针可以大大增加区间访问性,可使用在范围查询等

第三:存储

(1)B树每个节点即保存数据又保存索引,所以每一节点特别大,这一层所有节点加起来数据量将非常大。磁盘每次IO一定量的数据,对于Mysql来说如何衡量查询效率呢?就是磁盘IO次数。既然B树每一层特别大,那每一层就需要对数据分开从而进行多次IO操作。所有Mysql不用。

(2)B+树更适合外部存储,也就是磁盘存储。由于内节点无 data 域,每个节点能索引的范围更大更精确,所以不需要用B+树。

有了他们的区别之后,现在我们再来解释这个原因就好多了。

二、原因解释

上面解释了不使用的原因,我们再来看为什么Mysql使用B+树,而MongoDB使用B树,想要解释原因,我们还必须要了解一下MongoDB和Mysql的基本概念。

1、MongoDB

MongoDB 是文档型的数据库,是一种 nosql,它使用类 Json 格式保存数据。比如之前我们的表可能有用户表、订单表、购物篮表等等,还要建立他们之间的外键关联关系。但是类Json就不一样了。

img

我们可以看到这种形式更简单,通俗易懂。那为什么 MongoDB 使用B-树呢?

MongoDB使用B树,所有节点都有Data域,只要找到指定索引就可以进行访问,无疑单次查询平均快于Mysql

2、Mysql

Mysql作为一个关系型数据库,数据的关联性是非常强的,区间访问是常见的一种情况,B+树由于数据全部存储在叶子节点,并且通过指针串在一起,这样就很容易的进行区间遍历甚至全部遍历。

还有一点,B+树只有叶子节点保存数据,所以每一节点比较小,每一层所有节点加起来数据量也相对比较小。磁盘每次IO一定量的数据,对于Mysql来说。既然B+树每一层小,那每一层只需要少量IO操作。

4.2 B+和hash的区别? 红黑树呢? avl树呢?

二叉排序树:二叉排序树也称为也叫二叉查找树,二叉搜索树, BST。
满足二叉查找树的一般性质,是指一棵空树具有如下性质:

对于二叉树中的任何一个非叶子节点,要求左子节点比当前节点值小,右子节点比当前节点值大。任意节点的左右子树也分别是二叉查找树.没有键值相等的节点.中序遍历二叉排序树得到递增有序序列
AVL树: 相比于”二叉查找树”,它的特点是:AVL树中任何节点的两个子树的高度最大差别为1。
红黑树相比,它是严格的平衡二叉树,平衡条件必须满足(所有节点的左右子树高度差不超过1)。
AVL树的查找、插入和删除在平均和最坏情况下都是O(logn)。

总结:发生问题的那个节点要成为根节点才能解决问题。不管我们是执行插入还是删除操作,只要不满足上面的条件,就要通过旋转来保持平衡,而旋转是非常耗时的,由此我们可以知道AVL树适合用于插入删除次数比较少,但查找多的情况 。

红黑树 略

  1. hash树概述
    理想的情况是希望不经过任何比较,一次存取便能得到所查的记录, 那就必须在记的存储位置和它的关键字之间建立一个确定的对应关系f,使每个关键字和一个唯一的存储位置相对应。因而在查找时,只要根据这个对应关系f找到 给定值K的像f(K)。由此,不需要进行比较便可直接取得所查记录。在此,我们称这个对应关系为哈希(Hash)函数,按这个思想建立的表为哈希表。

在哈希表中对于不同的关键字可能得到同一哈希地址,这种现象称做冲突。在一般情况下,冲突只能尽可能地减少,而不能完全避免。因为哈希函数是从关键字集合 到地址集合的映像。通常关键字的集合比较大,它的元素包括所有可能的关键字,而地址集合的元素仅为哈希表中的地址值。在一般情况下,哈希函数是一个压缩映像函数,这就不可避免的要产生冲突。
4. 哈希树的应用
  哈希树是一种可以自适应的树。通过给出足够多的不同质数,我们总可以将所有已经出现的关键字进行区别。而质数本身就是无穷无尽的。这种方式使得关键字空间和地址空间不再是压缩对应方式,而是完全可以等价的。

哈希树可以广泛应用于那些需要对大容量数据进行快速匹配操作 的地方。
例如:数据库索引系统、短信息中的收条匹配、大量号码路由匹配、信息过滤匹配。程序员可以利用各种代码来实现哈希树结构。它可以为程序员提供一种使用起来更加方便,更加简单的快速数据存储方式

5. 说一下es的分布式架构原理(es是如何实现分布式的)?

1、分片

Elasticsearch 也是会对数据进行切分,同时每一个分片会保存多个副本,其原因是为了保证分布式环境下的高可用,同时也扩大了存储空间。es也是master-slave架构,在 es 中,节点是对等的,节点间会通过自己的一些规则选取集群的 Master,Master 会负责集群状态信息的改变,并同步给其他节点。值得注意的是,只有建立索引和类型需要经过 Master,数据的写入有一个简单的 Routing 规则,可以 Route 到集群中的任意节点,所以数据写入压力是分散在整个集群的。

具体就是你先建立一个索引,这个索引可以拆分成多个 shard,每个 shard 存储部分数据。这个shard 的数据实际是有多个备份,就是说每个 shard 都有一个 primary shard,负责写入数据,但是还有几个 replica shardprimary shard 写入数据之后,会将数据同步到其他几个 replica shard 上去。

img

通过这个 replica 的方案,每个 shard 的数据都有多个备份,如果某个机器宕机了,没关系啊,还有别的数据副本在别的机器上呢。高可用了吧。

es 集群多个节点,会自动选举一个节点为 master 节点,这个 master 节点其实就是干一些管理的工作的,比如维护索引元数据、负责切换 primary shard 和 replica shard 身份等。要是 master 节点宕机了,那么会重新选举一个节点为 master 节点。如果是非 master节点宕机了,那么会由 master 节点,让那个宕机节点上的 primary shard 的身份转移到其他机器上的 replica shard。接着你要是修复了那个宕机机器,重启了之后,master 节点会控制将缺失的 replica shard 分配过去,同步后续修改的数据之类的,让集群恢复正常。说得更简单一点,就是说如果某个非 master 节点宕机了。那么此节点上的 primary shard 不就没了。那好,master 会让 primary shard 对应的 replica shard(在其他机器上)切换为 primary shard。如果宕机的机器修复了,修复后的节点也不再是 primary shard,而是 replica shard。

其实上述就是 ElasticSearch 作为分布式搜索引擎最基本的一个架构设计。

6. MongoDB是什么?

答:MongoDB是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统。 在高负载的情况下,添加更多的节点,可以保证服务器性能。 MongoDB旨在为WEB应用提供可扩展的高性能数据存储解决方案。

MongoDB将数据存储为一个文档,数据结构由键值(key=>value)对组成。 MongoDB文档类似于JSON对象。字段值可以包含其他文档,数组及文档数组。

6.1MongoDB成为最好NoSQL数据库的原因是什么?

以下特点使得MongoDB成为最好的NoSQL数据库:

  • 面向文件的
  • 高性能
  • 高可用性
  • 易扩展性
  • 丰富的查询语言

6.2MySQL与MongoDB之间最基本的差别是什么?

MySQL和MongoDB两者都是免费开源的数据库。MySQL和MongoDB有许多基本差别包括数据的表示(data representation),查询,关系,事务,schema的设计和定义,标准化(normalization),速度和性能。

通过比较MySQL和MongoDB,实际上我们是在比较关系型和非关系型数据库,即数据存储结构不同

7. Nacos

7.1 为什么要将服务注册到nacos?

为了更好的查找这些服务。

7.2 Nacos服务是如何判定服务实例的状态?

通过发送心跳包,5秒发送一次,如果15秒没有回应,则说明服务出现了问题,
如果30秒后没有回应,则说明服务已经停止。

7.3 Nacos中的负载均衡底层是如何实现的?

通过Ribbon实现,Ribbon中定义了一些负载均衡算法。然后基于这些算法从服务
实例中获取一个实例为消费方提供服务。

7.4 Nacos主要提供以下四大功能:

  1. 服务发现和服务健康监测
  2. 动态配置服务
  3. 动态DNS服务
  4. 服务及其元数据管理

7.5 Nacos客户端注解

@EnableDiscoveryClient

8.Feign

8.1 各种注解

@FeignClient注解用于指定从哪个服务中调用功能 ,名称与被调用的服务名保持一致。
@GetMapping注解用于对被调用的微服务进行地址映射。
@PathVariable注解一定要指定参数名称,否则出错
@Component注解防止,在其他位置注入CodClient时idea报错

8.2 Spring Cloud调用接口过程配合

Feign -----> Hystrix —> Ribbon —> Http Client(apache http components 或者 Okhttp) 具体交互流程上,如下图所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-az4vffvq-1614784096550)(../../../../../AppData/Roaming/Typora/typora-user-images/image-20210303184820464.png)]

​ 先接口化请求调用,对指定请求的地址进行设定,并交给Feign过来;Feign实际去请求远程提供的接口;如果中途出现异常由Hystrix来中断和熔断服务;如果请求是一个集群,当请求传递给Ribbon后,会根据各个因素和设定的规则来选择要请求的哪个服务器接口来处理,最后httpClient来获取请求并执行调用最后的方法并返回

9 Hystrix

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pIvinTfh-1614784096553)(../../../../../AppData/Roaming/Typora/typora-user-images/image-20210303184852327.png)]

9.1 设置hystrix超时时间

默认1000ms

hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=6000

9.2 熔断器的作用

在互联网系统中,当下游服务因访问压力过大而响应变慢或失败,上游服务为了保护系统整体的可用性,可以暂时切断对下游服务的调用。

这种牺牲局部,保全整体的措施就叫做熔断。

9.3 熔断器的三种状态

对于熔断机制的实现,Hystrix设计了三种状态:

1.熔断关闭状态(Closed)

服务没有故障时,熔断器所处的状态,对调用方的调用不做任何限制。

2.熔断开启状态(Open)

在固定时间内(Hystrix默认是10秒),接口调用出错比率达到一个阈值(Hystrix默认为50%),会进入熔断开启状态。

进入熔断状态后,后续对该服务接口的调用不再经过网络,直接执行本地的fallback方法。

3.半熔断状态(Half-Open)

在进入熔断开启状态一段时间之后(Hystrix默认是5秒),熔断器会进入半熔断状态。所谓半熔断就是尝试恢复服务调用,允许有限的流量调用该服务,并监控调用成功率。如果成功率达到预期,则说明服务已恢复,进入熔断关闭状态;如果成功率仍旧很低,则重新进入熔断开启状态。

CAP理论

服务注册中心本质上是为了解耦服务提供者和服务消费者。对于任何一个微服务,原则上都应存在或者支持多个提供者,这是由微服务的分布式属性决定的。更进一步,为了支持弹性扩缩容特性,一个微服务的提供者的数量和分布往往是动态变化的,也是无法预先确定的。因此,原本在单体应用阶段常用的静态LB机制就不再适用了,需要引入额外的组件来管理微服务提供者的注册与发现,而这个组件就是服务注册中心。

CAP理论是分布式架构中重要理论

一致性(Consistency) (所有节点在同一时间具有相同的数据)

可用性(Availability) (保证每个请求不管成功或者失败都有响应)

分隔容忍(Partition tolerance) (系统中任意信息的丢失或失败不会影响系统的继续运作)

P的理解,我觉得是在整个系统中某个部分,挂掉了,或者宕机了,并不影响整个系统的运作或者说使用,

而可用性是,某个系统的某个节点挂了,但是并不影响系统的接受或者发出请求,CAP 不可能都取,只能取其中2个

原因如果C是第一需求的话,那么会影响A的性能,因为要数据同步,不然请求结果会有差异,但是数据同步会消耗时间,期间可用性就会降低。

如果A是第一需求,那么只要有一个服务在,就能正常接受请求,但是对与返回结果变不能保证,原因是,在分布式部署的时候,数据一致的过程不可能想切线路那么快。

再如果,同事满足一致性和可用性,那么分区容错就很难保证了,也就是单点,也是分布式的基本核心,好了,明白这些理论,就可以在相应的场景选取服务注册与发现了

Eureka Server

当 Eureka Server 节点在短时间内丢失过多的心跳时,那么这个节点就会进入自我保护模式。(********Spring Cloud Netflix 在设计 Eureka 时就紧遵AP原则)

Eureka的集群中,只要有一台Eureka还在,就能保证注册服务可用(保证可用性),只不过查到的信息可能不是最新的(不保证强一致性)。除此之外,Eureka还有一种自我保护机制,如果在15分钟内超过85%的节点都没有正常的心跳,那么Eureka就认为客户端与注册中心出现了网络故障,此时会出现以下几种情况:

Eureka不再从注册表中移除因为长时间没有收到心跳而过期的服务;

Eureka仍然能够接受新服务注册和查询请求,但是不会被同步到其它节点上(即保证当前节点依然可用);

当网络稳定时,当前实例新注册的信息会被同步到其它节点中;

因此,Eureka可以很好的应对因网络故障导致部分节点失去联系的情况,而不会像zookeeper那样使得整个注册服务瘫痪。

Nacos:

Nacos是阿里开源的,Nacos 支持基于 DNS 和基于 RPC 的服务发现。在Spring Cloud中使用Nacos,只需要先下载 Nacos 并启动 Nacos server,Nacos只需要简单的配置就可以完成服务的注册发现。

Nacos除了服务的注册发现之外,还支持动态配置服务。动态配置服务可以让您以中心化、外部化和动态化的方式管理所有环境的应用配置和服务配置。动态配置消除了配置变更时重新部署应用和服务的需要,让配置管理变得更加高效和敏捷。配置中心化管理让实现无状态服务变得更简单,让服务按需弹性扩展变得更容易。

一句话概括就是Nacos = Spring Cloud注册中心 + Spring Cloud配置中心

Zuul网关

zuul是spring cloud中的微服务网关。

网关: 是一个网络整体系统中的前置门户入口。请求首先通过网关,进行路径的路由,定位到具体的服务节点上。

Zuul是一个微服务网关,首先是一个微服务。也是会在Eureka注册中心中进行服务的注册和发现。也是一个网关,请求应该通过Zuul来进行路由。

Zuul网关不是必要的。是推荐使用的。

使用Zuul,一般在微服务数量较多(多于10个)的时候推荐使用,对服务的管理有严格要求的时候推荐使用,当微服务权限要求严格的时候推荐使用。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rYDR06kH-1656163665564)(file:///C:\Users\xx\AppData\Local\Temp\ksohtml29196\wps1.jpg)]

Solr介绍

Solr是建立在Apache Lucene ™之上的流行,快速,开放源代码的企业搜索平台。Solr具有高度的可靠性,可伸缩性和容错性,可提供分布式索引,复制和负载平衡查询,自动故障转移和恢复,集中式配置等。Solr为许多世界上最大的互联网站点提供搜索和导航功能。

ES

ES全称ElasticSearch,是一个基于Lucene的搜索服务器。(其实就是对Lucene进行封装,提供了REST API的操作接口)

ElasticSearch作为一个高度可拓展的开源全文搜索和分析引擎,可用于快速的对大数据进行存储,搜索和分析。

ElasticSearch是基于Java开发的,并作为Apache许可条款下的开放源码发布,是一种流行的企业级搜索引擎。

根据DB-Engines排名显示,ElasticSearch是最受欢迎的企业级搜索引擎。

ElasticSearch和Logstash(数据收集、日志解析引擎)、Kibana(分析和可视化平台)一起开发的。这三个产品被设计成一个集成解决方案,称为“Elastic Stack”(以前被称为ELK技术栈)。

axios

axios是独立于vue的一个项目,基于promise用于浏览器和node.js的http客户端

在浏览器中可以帮助我们完成 ajax请求的发送

在node.js中可以向远程接口发送请求

1,什么是MyCat

??MyCat是目前最流行的分布式数据库中间插件,是一个开源的分布式数据库系统,是一个实现了MySQL协议的服务器,前端用户可以把它看作是一个数据库代理,用MySQL客户端工具和命令行访问,而其后端可以用MySQL原生协议与多个MySQL服务器通信,也可以用JDBC协议与大多数主流数据库服务器通信,其核心功能是分表分库,即将一个大表水平分割为N个小表,存储在后端MySQL服务器里或者其他数据库里。

redis中incr、incrby、decr、decrby属于string数据结构,它们是原子性递增或递减操作。

incr递增1并返回递增后的结果;

incrby根据指定值做递增或递减操作并返回递增或递减后的结果(incrby递增或递减取决于传入值的正负);

decr递减1并返回递减后的结果;

decrby根据指定值做递增或递减操作并返回递增或递减后的结果(decrby递增或递减取决于传入值的正负);

FreeMarker

FreeMarker 是一款 模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页,电子邮件,配置文件,源代码等)的通用工具。 它不是面向最终用户的,而是一个Java类库,是一款程序员可以嵌入他们所开发产品的组件。

模板编写为FreeMarker Template Language (FTL)。 在模板中,你可以专注于如何展现数据, 而在模板之外可以专注于要展示什么数据。 这种方式通常被称为 MVC (模型 视图 控制器) 模式,对于动态网页来说,是一种特别流行的模式。

shiro

是一个强大且易用的Java安全框架,执行身份验证、授权、密码和会话管理。使用Shiro的易于理解API,你可以快速、轻松地获取任何应用程序,从最小的移动应用程序到最大的网络和企业应用程序

*雪花算法*

简单描述:

+ 最高位是符号位,始终为0,不可用。

+ 41位的时间序列,精确到毫秒级,41位的长度可以使用69年。时间位还有一个很重要的作用是可以根据时间进行排序。

+ 10位的机器标识,10位的长度最多支持部署1024个节点。

+ 12位的计数序列号,序列号即一系列的自增id,可以支持同一节点同一毫秒生成多个ID序号,12位的计数序列号支持每个节点每毫秒产生4096个ID序号。

,其核心功能是分表分库,即将一个大表水平分割为N个小表,存储在后端MySQL服务器里或者其他数据库里。

redis中incr、incrby、decr、decrby属于string数据结构,它们是原子性递增或递减操作。

incr递增1并返回递增后的结果;

incrby根据指定值做递增或递减操作并返回递增或递减后的结果(incrby递增或递减取决于传入值的正负);

decr递减1并返回递减后的结果;

decrby根据指定值做递增或递减操作并返回递增或递减后的结果(decrby递增或递减取决于传入值的正负);

FreeMarker

FreeMarker 是一款 模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页,电子邮件,配置文件,源代码等)的通用工具。 它不是面向最终用户的,而是一个Java类库,是一款程序员可以嵌入他们所开发产品的组件。

模板编写为FreeMarker Template Language (FTL)。 在模板中,你可以专注于如何展现数据, 而在模板之外可以专注于要展示什么数据。 这种方式通常被称为 MVC (模型 视图 控制器) 模式,对于动态网页来说,是一种特别流行的模式。

shiro

是一个强大且易用的Java安全框架,执行身份验证、授权、密码和会话管理。使用Shiro的易于理解API,你可以快速、轻松地获取任何应用程序,从最小的移动应用程序到最大的网络和企业应用程序

*雪花算法*

简单描述:

+ 最高位是符号位,始终为0,不可用。

+ 41位的时间序列,精确到毫秒级,41位的长度可以使用69年。时间位还有一个很重要的作用是可以根据时间进行排序。

+ 10位的机器标识,10位的长度最多支持部署1024个节点。

+ 12位的计数序列号,序列号即一系列的自增id,可以支持同一节点同一毫秒生成多个ID序号,12位的计数序列号支持每个节点每毫秒产生4096个ID序号。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值