总结面试过程中问到的问题

总结面试过程中问到的问题

1:线程池参数以及执行流程

## 七大参数:
核心线程数,最大线程数,空闲线程存活时间,工作队列,线程工厂,拒绝策略,时间单位
corePoolSize: 线程池核心线程数最大值
maximumPoolSize: 线程池最大线程数大小
keepAliveTime: 线程池中非核心线程空闲的存活时间大小
unit: 线程空闲存活时间单位
workQueue: 存放任务的阻塞队列
threadFactory: 用于设置创建线程的工厂,可以给创建的线程设置有意义的名字,可方便排查问题。
handler: 线城池的饱和策略事件,主要有四种类型。
## 执行流程
提交一个任务,线程池里存活的核心线程数小于线程数corePoolSize时,线程池会创建一个核心线程去处
理提交的任务。
如果线程池核心线程数已满,即线程数已经等于corePoolSize,一个新提交的任务,会被放进任务队列
workQueue排队等待执行。
当线程池里面存活的线程数已经等于corePoolSize了,并且任务队列workQueue也满,判断线程数是否达
到maximumPoolSize,即最大线程数是否已满,如果没到达,创建一个非核心线程执行提交的任务。
如果当前的线程数达到了maximumPoolSize,还有新的任务过来的话,直接采用拒绝策略处理。
## 拒绝策略
CallerRunsPolicy呼叫着运行策略,通常叫做,调用者运行策略:是如果线程池的线程全部被用完的时候,
会把多余的任务返回给调用者去执行;
AbortPolicy终止策略:如果线程池线程被用完了,直接抛出异常 rejectedExecution从而终止任务;
DiscardPolicy丢弃策略:如果线程池的线程被用完了,不抛出异常,直接丢弃多余的任务;
DiscardOldestPolicy丢弃最老策略:如果线程池的线程被用完了,就把等待时间最久的任务丢弃掉;
#
AbortPolicy(默认):丢弃任务并抛出 RejectedExecutionException 异常。
CallerRunsPolicy:由调用线程处理该任务。
DiscardPolicy:丢弃任务,但是不抛出异常。可以配合这种模式进行自定义的处理方式。
DiscardOldestPolicy:丢弃队列最早的未处理任务,然后重新尝试执行任务。
# 线程周期
新建(new thread)----->就绪----->运行----->阻塞----->死亡
# 线程池
# 作用
降低资源消耗,提高响应速度,提高线程的可管理性,降低系统的稳定性,
# 类型
new CachedThreadPool():可缓存线程池
new FixedTheadPool():可定长度
new ScheduledThreadPool():可定时
new SingleTheadExecutor():单例
# 线程池执行流程
提交线程任务进入队列----->并发队列容器----->取出任务执行
# 多线程异步调用 CompletableFuture
# CompletableFuture 是什么
CompletableFuture是JDK1.8里面引入的一个基于事件驱动的异步回调类。
简单来说,就是当使用异步线程去执行一个任务的时候,我们希望在任务结束以后触发一个后续的动作,而
CompletableFuture就可以实现这个功能。
# 五种实现
第一种,thenCombine,把两个任务组合在一起,当两个任务都执行结束以后触发事件回调。
第二种,thenCompose,把两个任务组合在一起,这两个任务串行执行,也就是第一个任务执行完以后自动触
发执行第二个任务。
第三种,thenAccept,第一个任务执行结束后触发第二个任务,并且第一个任务的执行结果作为第二个任务
的参数,这个方法是纯粹接受上一个任务的结果,不返回新的计算值。
第四种,thenApply,和thenAccept一样,但是它有返回值。
第五种,thenRun,就是第一个任务执行完成后触发执行一个实现了Runnable接口的任务。

在这里插入图片描述

2:StringBuffer与StringBuilder的区别

StringBuffer是线程安全的,它相关方法都加了synchronized 关键字,StringBuilder线程不安全。
StringBuffer是从jdk1.0就开始了,StringBuilder-是从jdk1.5开始
使用原则:
如果要操作少量的数据,用String
单线程操作大量数据,用StringBuilder
多线程操作大量数据,用StringBuffe

3:Arraylist和Linkedlist区别

1:ArrayList的实现是基于数组,LinkedList的实现是基于双向链表。
2:get操作时,ArrayList比LinkedList的效率更高 (线程都不安全)
3: LinkedList比ArrayList更占内存,因为LinkedList的节点除了存储数据,还存储了两个引用,一个
指向前一个元素,一个指向后一个元素。
4:对于插入和删除操作,LinkedList优于ArrayList
# 长度
ArrayList 默认长度为10,当长度为11时会自动库容,自动扩容的新容量的大小是原容量的1.5倍,一般来
讲扩容后的最大容量为最大数组长度,即最大整数-8

4:volatile关键字的作用

···shell
1:volatile修饰基本数据类型的时候能够保证多个线程读取的一致性,对于引用类型数组,以及bean,保证
引用的可见性不保证内容的可见性
2:volatile是java中的一个类型修饰符。它是被设计用来修饰被不同线程访问和修改的变量
···

5:map 的线程安全类

map线程安全类:ConcurrentHashMap线程安全,HashTable,Collections.synchronizedMap

6:HashMap与HashTable之间的区别

1.HashMap线程不安全、HashTable线程安全,但是使用HashTable在多线程的情况下效率比较偏低,所以
在多线程的情况下使用ConcurrentHashMap;
2.多线程的情况下使用HashTable能够保证数据安全性,是采用synchronized锁将整个HashTable中的数
组锁住,在多个线程中只允许一个线程访问Put或者Get,效率非常低。
3.多线程的情况下使用HashMap线程不安全,没有上锁,可能会发生一些数据冲突问题,但是效率比较高的。
4.HashMap可以允许存放key值为null,存放在数组第0个位置、HashTable不允许存放的key为null
hashmap: 1.7 之前是:数组加链表,1.8之后改为数组加链表加红黑树(链表太长导致的查询速度变慢的问
题)在链表长度大于8的时候,将后面的数据存在红黑树中,以加快检索速度。
hashmap中,当链表长度超过8,且table数组的长度不小于64时,链表会转化为红黑树
# 扩容机制
HashMap默认的初始容量是16 Hashtable 初始容量为:11,
负载因子默认都是0.75
当已用容量>总容量*负载因子的时候 可以使用resize() 方法进行扩容 hashMap的每次扩容都是当前容量
的翻倍 hashTable是当前容量翻倍+1
# 哈希冲突及解决方法
如果两个不同对象的hashCode相同,这种现象称为hash冲突
#开放定址法:就是一旦发生了冲突,就去寻找下一个空的散列地址,只要散列表足够大,空的散列地址总能
找到,并将记录存入
#链地址法:将哈希表的每个单元作为链表的头结点,所有哈希地址为i的元素构成一个同义词链表。即发生冲
突时就把该关键字链在以该单元为头结点的链表的尾部
#再哈希法:当哈希地址发生冲突用其他的函数计算另一个哈希函数地址,直到冲突不再产生为止
#建立公共溢出区:将哈希表分为基本表和溢出表两部分,发生冲突的元素都放入溢出表中
# 二叉树
二叉查找树的特点就是左子树的节点值比父亲节点小,而右子树的节点值比父亲节点大
二叉树的大部分子节点都比父节点值小,然后导致所有的数据偏向左侧,进而退化成链表,下图
# 平衡二叉树
又被称为 AVL 树,是为了解决二叉树退化成一棵链表而诞生的。特点(父节点的左右两棵子树的深度之差的
绝对值不超过1,其中左右子树的高度差是通过左旋右旋实现的)
# 红黑树
红黑树,它是一种特殊的二叉查找树。红黑树的每个节点上都有存储位表示节点的颜色,可以是红(Red)或黑
(Black)#每个节点只有两种颜色:红色和黑色
#根节点是黑色的
#每个叶子节点都是黑色的空节点(NIL),也就是说,叶子节点不存数据
#任何相邻的节点都不能同时为红色,也就是说,红色节点是被黑色节点隔开的
#从一个节点到该节点的子孙节点的所有路径上包含相同数目的黑节点
与平衡树不同的是,红黑树在插入、删除等操作,不会像平衡树那样,频繁着破坏红黑树的规则,所以不需要
频繁着调整。意思是查找效率相当,但是插入、删除效率高于平衡树,这也是我们为什么大多数情况下使用红
黑树的原因(但是需要注意的是,如果应用场景中对插入、删除不频繁,只是对查找要求较高,那么平衡二叉树
还是较优于红黑树的)
# 总结
二叉查找树(BST):解决了排序的基本问题,但是由于无法保证平衡,可能退化为链表;
平衡二叉树(AVL):通过旋转解决了平衡的问题,但是旋转操作效率太低;
红黑树:通过舍弃严格的平衡和引入红黑节点,解决了AVL旋转效率过低的问题,但是在磁盘等场景下,树仍
然太高,IO次数太多;
B树:通过将二叉树改为多路平衡查找树,解决了树过高的问题;
B+树:在B树的基础上,将非叶节点改造为不存储数据的纯索引节点,进一步降低了树的高度;此外将叶节点使
用指针连接成链表,范围查询更加高效。

7:list 线程安全类

Vector和CopyOnWriteArrayList都是线程安全的List,底层都是数组实现的,Vector的每个方法都进行
了加锁,而CopyOnWriteArrayList的读操作是不加锁的,因此CopyOnWriteArrayList的读性能远高于
Vector,Vector每次扩容的大小都是原来数组大小的2倍,而CopyOnWriteArrayList不需要扩容

8:spring事务

## 原理
A(原子性)C(一致性)I(隔离性)D(持久性),分布式事务就是为了保证不同数据库的数据一致性(要么全部成
功,要么全部失败)
## 类型
事务分为:编程式事务和声明式事务,编程式需配置一大堆的配置文件(xml),而声明式事务实现极其简单,
所以在日常项目中,我们都会使用声明式事务 @Transactional 来实现事务,声明式事务使用极其简单,只
需要在类上或方法上添加 @Transactional 关键字,就可以实现事务的自动开启、提交或回滚了
@Transactional 会在方法执行前,会自动开启事务;在方法成功执行完,会自动提交事务;如果方法在执行
期间,出现了异常,那么它会自动回滚事务。
## 声明式事务@Transactional 失效的场景:
1:非 public 修饰的方法
2:timeout 超时
3:代码中有 try/catch
4:调用类内部 @Transactional 方法
5:数据库不支持事务

9:synchronized和lock

1:lock是一个接口,而synchronized是java的一个关键字
2:synchronized是java内置关键字,是在JVM层面实现的,系统会监控锁的释放与否,lock是JDK代码实现
的,需要手动释放,在finally块中释放。可以采用非阻塞的方式获取锁;
3:synchronized会自动释放锁(a 线程执行完同步代码会释放锁 ;b 线程执行过程中发生异常会释放
锁)Lock需在finally中手工释放锁(unlock()方法释放锁),否则容易造成线程死锁;
4:synchronize可以用在代码块上,方法上。lock只能写在代码里,不能直接修改方法。

10:redis

# 缓存基本上分为三类:本地缓存、分布式缓存、多级缓存。
1:Redis五种数据类型分别是string(字符串),hash(哈希),list(列表),set(集合)及sort set (有序
集合)。
# redis 它的读的速度是110000次/s,写的速度是81000次/s
# bitmap是redis的一种扩展数据类型,主要用于二值状态统计,bigmap底层使用的是String的数据
结构,而String保存在计算机中的格式是二进制的字节数组,这样bitmap就充分利用了每个字节的bit位,
大大节省了内存开销。(设置人员在线: 根据token为key (0-1表示在线或者离线) setbit online 用户
1 1/getbit online 用户1)统计在线人员: bitcount online 0 0
#redis另三种特殊的数据结构:Geo、HyperLogLog、 BitMap
2:redis 是单线程的
3:Redis6.0之前是单线程的,Redis6.0之后开始支持多线程;
## 持久化方式redis三大策略
1:redis提供了两种持久化的方式,(默认RDB)分别是RDB(Redis DataBase)和AOF(Append Only
File)。
RDB,简而言之,就是在不同的时间点,将redis存储的数据生成快照并存储到磁盘等介质上;
AOF,则是换了一个角度来实现持久化,那就是将redis执行过的所有写指令记录下来,在下次redis重新启动
时,只要把这些写指令从前到后再重复执行一遍,就可以实现数据恢复了。
其实RDB和AOF两种方式也可以同时使用,在这种情况下,如果redis重启的话,则会优先采用AOF方式来进行
数据恢复,这是因为AOF方式的数据恢复完整度更高。
如果你没有数据持久化的需求,也完全可以关闭RDB和AOF方式,这样的话,redis将变成一个纯内存数据库,
就像memcache一样。
## 缓存穿透,击穿,雪崩
1:缓存穿透:指在redis缓存中不存在数据,这个时候只能去访问持久层数据库,当用户很多时,缓存都没有
命中就会照成很大压力
# 解决方案 :
(1)布隆过滤器(对可能查询的数据先用hash存储)
(2)缓存空对象:在没有的数据中存一个空,而这些空的对象会设置一个有效期)
2:缓存击穿:指在同一个时间内访问一个请求的请求数过多,而在这个时候缓存某个key失效了,这个时候就会
冲向数据库照成缓存击穿
# 解决方案:
(1)设置缓存永远不过期
(2)加互斥锁,使用分布式锁,保证每个key只有一个线程去查询后端服务,而其他线程为等待状态。这
种模式将压力转到了分布式锁上
3:缓存雪崩
缓存雪崩:在某个时间段,缓存集体过期、redis宕机
# 解决方案:
(1)给key的失效时间设置为随机时间,避免集体过期;双缓存;加互斥锁
# redis三大策略 :持久化策略(内存到磁盘上),过期(定期)策略,内存淘汰策略
# 过期(定期)策略
定期删除:过期key放入独立字典中,定期删除字典数据
定期删除策略:定期删除
惰性删除:过期了,删除,不返回任何数据
# 内存淘汰策略
noeviction:默认策略,不删除数据
allkeys-lru:所有key中,删除最近最少使用的数据
volatile-lru:设置过期时间的所有key中,选取最近最少使用的数据删除
volatile-random:在所有key中,随机删除设置过期时间key的数据
volatile-ttl:设置过期时间key中,删除存活时间最短的数据
获取当前内存淘汰策略:config get maxmemory-policy (可以看到当前使用的默认的noeviction策
略)
通过配置文件设置淘汰策略(修改redis.conf文件)maxmemory-policy allkeys-lru,通过命令修改淘
汰策略config set maxmemory-policy allkeys-lru
# redis 集群三种模式
主从复制模式:一主多从模式。一个主节点,多个从节点,那么主节点可以负责:读操作,写操作。 从节点只能
负责读操作,不能负责写操作。 这样就可以把读的压力从主节点分摊到从节点,以减少主节点的压力,当主节
点执行完写命令,会把数据同步到从节点。
11:sql 优化
12:mysql 引擎
## 思考
1. 如果主节点挂了,从节点会不会上位? 不会
2. 如果增加一个新的从节点,新从节点会不会把之前的数据同步过来。会
哨兵模式:由于主从模式,主节点单机后,从节点不会自动上位。 增加一个哨兵服务,该哨兵时刻监控
master,如果master挂了,哨兵会在从节点中选举一位为主节点#哨兵投票机制
集群化模式:不管上面的主从还是哨兵模式,都无法解决单节点写操作的问题。如果这时写操作的并发比较高。
这是可以实验集群化模式#去中心化模式
##原理:redis 集群中内置了 16384 个哈希槽,当需要在 Redis 集群中放置一个 key-value时,
redis 先对 key 使用 crc16 算法算出一个整数结果,然后把结果对 16384 求余数,这样每个 key 都
会对应一个编号在 0-16383 之间的哈希槽,redis 会根据节点数量大致均等的将哈希槽映射到不同的节
点。当你往Redis Cluster中加入一个Key时,会根据crc16(key) mod 16384计算这个key应该分布到哪
个hash slot中,一个hash slot中会有很多key和value。你可以理解成表的分区,使用单节点时的redis
时只有一个表,所有的key都放在这个表里;改用Redis Cluster以后会自动为你生成16384个分区表,你
insert数据时会根据上面的简单算法来决定你的key应该存在哪个分区,每个分区里有很多key。

11:sql 优化

1:避免使用select *
2:用union all代替union
3:小表驱动大表
in 适用于左边大表,右边小表。
exists 适用于左边小表,右边大表。
4:批量操作(java 代码for 循环插入)
5:多用limit (查询一条然后get(0),尽量使用 limt 1# 索引失效 去重,一些函数计算,%like, 会导致索引失效
通过关键字explain 可以查看一条sql是否用到了索引(type 没用到就是ALL)
MySQL中使用SHOW INDEX能够查看数据表中是否建立了索引

12:mysql 引擎

# mysql 引擎
InnoDB 和 MyISAM
# 区别
InnoDB 支持事务,MyISAM 不支持,
InnoDB 支持外键,而 MyISAM 不支持。
InnoDB 不支持全文索引,而 MyISAM 支持全文索引
InnoDB 默认用的是行级锁,也支持表级锁 而 MyISAM 默认用的是表级锁,不支持行级锁;
# 如何选择:
1:是否要支持事务,如果要请选择 innodb,如果不需要可以考虑MyISAM;
2:如果表中绝大多数都只是读查询,可以考虑 MyISAM,如果既有读写也挺频繁,请使用 InnoDB。
3:系统奔溃后,MyISAM 恢复起来更困难,能否接受;
4:MySQL5.5 版本开始 Innodb 已经成为 Mysql 的默认引擎(之前是MyISAM)# 索引
索引本身也是一种数据结构,MySQL 中存储索引用的一般都是 B + 树
MySQL的索引主要分为两种:
1、聚集索引(clustered index)
2、非聚集索引(non-clustered index)
# 什么是分库分表 (水平拆分--把数据拆分出来[进行取模--偶数放到一个表,奇数放到一个表],垂直拆
分--把多个字段拆分出来)
分库:将一个库的数据拆分到多个相同的库中,访问的时候访问一个库
分表:把一个表的数据放到多个表中,操作对应的某个表就
13==和equals的区别
14:抽象类与接口的区别
15:mybatis #{}和${}的区别
16:mybatis 一级缓存和二级缓存
分库分表框架:shardingsphereJDBC
# Autowired,Resource区别
@Autowired 是一个 spring 的注解
@Resource 是一个J2EE (java自己)的注解
@Autowird注解默认通过byType方式注入,而@Resource注解默认通过byName方式注入

13:==和equals的区别

==操作符专门用来比较变量的值是否相同
1:基本数据类型:比较的是他们的值是否相同。
2:引用数据类型:比较的是他们的内存地址是否同一地址。
equals方法常用来比较对象的内容是否相同
equals 不能比较基本数据类型

14:抽象类与接口的区别

1、抽象类和接口都不能直接实例化。如果要实例化,抽象类变量必须指向实现所有抽象方法的子类对象,接口
变量必须指向实现所有接口方法的类对象。
2、抽象类要被子类继承,接口要被类实现。
3、接口只能做方法申明,抽象类中可以做方法申明,也可以做方法实现。
4、接口里定义的变量只能是公共的静态的常量,抽象类中的变量是普通变量。
5、抽象类里的抽象方法必须全部被子类所实现,如果子类不能全部实现父类抽象方法,那么该子类只能是抽
象类。同样,实现接口的时候,如不能全部实现接口方法,那么该类也只能为抽象类。
6、抽象方法只能申明,不能实现。
7、抽象类里可以没有抽象方法
8、如果—个类里有抽象方法,那么这个类只能是抽象类
9、抽象方法要被实现,所以不能是静态的,也不能是私有的。
10、接口可以继承接口,并且可多继承接口,但类只能单—继承。
11、接口可以通过匿名内部类实例化。接口是对动作的抽象,抽象类是对根源的抽象。抽象类表示的是,这个对
象是什么。而接口表示的是,这个对象能做什么。
12、关键字:abstract, interface

15:mybatis #{}和${}的区别

1#{}是预编译处理,$ {}是字符串替换。
2、MyBatis在处理#{}时,会将SQL中的#{}替换为?号,使用PreparedStatement的set方法来赋值;
MyBatis在处理 $ { } 时,就是把 ${ } 替换成变量的值。
3、使用 #{} 可以有效的防止SQL注入,提高系统安全性。
SQL注入的防护方法 (xss)
1、使用安全的API
2、对输入的特殊字符进行Escape转义处理
3、使用白名单规范用户输入
4、使用黑名单规范用户输入,如不允许用户输入select等SQL类字符串
5、服务器端在提交数据库进行SQL查询前,对 特殊字符进行过滤、转义、替换、删除操作
6、所有的SQL语句采用预编译和绑定变量
7、使用安全设备进行防护,如WAF

16:mybatis 一级缓存和二级缓存

一级缓存:SqlSession级别的缓存,缓存的数据只在SqlSession内有效。(默认开启)
mybatis一级缓存的范围有SESSION和STATEMENT两种,默认是SESSION17:nginx
如果不想使用一级缓存,可以把一级缓存的范围指定为STATEMENT,这样每次执行完一个Mapper中的语
句后都会将一级缓存清除。
如果需要更改一级缓存的范围,可以在Mybatis的配置文件中,在下通过localCacheScope指定。
<setting name="localCacheScope" value="STATEMENT"/>
二级缓存:mapper级别的缓存,同一个namespace公用这一个缓存,所以对SqlSession是共享的,二级缓存
需要我们手动开启。
查询顺序:二级缓存-->一级缓存-->数据库

17:nginx

# 优点
跨平台、配置简单、反向代理、高并发连接,官方监测能-支持5万并发
# 为什么Nginx性能这么高?
因为他的事件处理机制:异步非阻塞事件处理机制:运用了epoll模型,提供了一个队列,排队解决
# 单线程还是多线程
Nginx:采用单线程来异步非阻塞处理请求(管理员可以配置Nginx主进程的工作进程的数量),不会为每个请
求分配cpu和内存资源,节省了大量资源,同时也减少了大量的CPU的上下文切换,所以才使得Nginx支持更
高的并发。
# 请求
nginx接收一个请求后,首先由listen和server_name指令匹配server模块,再匹配server模块里的
location,location就是实际地址
# nginx 限流
Nginx限流就是限制用户请求速度,防止服务器受不了,Nginx的限流都是基于漏桶流算法
# 限流有3种
正常限制访问频率(正常流量):限制一个用户发送的请求,我Nginx多久接收一个请求。Nginx中使
用ngx_http_limit_req_module模块来限制的访问频率,限制
的原理实质是基于漏桶算法原理来实现的。在nginx.conf配置文件中可以使用limit_req_zone命令及
limit_req命令限制单个IP 的请求处理频率。
突发限制访问频率(突发流量):Nginx提供burst参数结合nodelay参数可以解决流量突发的问
题,可以设置能处理的超过设置的请求数外能额外处理的请求数。
限制并发连接数:Nginx中的ngx_http_limit_conn_module模块提供了限制并发连接数的功
能,可以使用limit_conn_zone指令以及limit_conn执行进行配置
# 漏桶算法
漏桶算法是网络世界中流量整形或速率限制时经常使用的一种算法,它的主要目的是控制数据注入到网络的速
率,平滑网络上的突发流量。漏桶算法提供了一种机制,通过它,突发流量可以被整形以便为网络提供一个稳定
的流量。也就是我们刚才所讲的情况。漏桶算法提供的机制实际上就是刚才的案例:突发流量会进入到一个漏
桶,漏桶会按照我们定义的速率依次处理请求,如果水流过大也就是突发流量过大就会直接溢出,则多余的请
求会被拒绝。所以漏桶算法能控制数据的传输速率。
18:springCloud
19 :k8s 组件
# 令牌桶算法
令牌桶算法是网络流量整形和速率限制中最常使用的一种算法。典型情况下,令牌桶算法用来控制发送到网络
上的数据的数目,并允许突发数据的发送。Google开源项目Guava中的RateLimiter使用的就是令牌桶控制
算法。令牌桶算法的机制如下:存在一个大小固定的令牌桶,会以恒定的速率源源不断产生令牌。如果令牌消耗
速率小于生产令牌的速度,令牌就会一直产生直至装满整个令牌桶。
# Nginx负载均衡的算法怎么实现的?策略有哪些?
轮询(默认),权重 weight,ip_hash( IP绑定),fair(第三方插件),url_hash(第三方插件)
# nginx的四大功能是什么?
正向代理,反向代理,负载均衡,动静分离
正向代理:正向代理代替客户端去发送请求(我们请求一个地址发现无法联网,可以通过正向代理--翻墙)
假如公司服务器的软件在内网部署访问不了internet,就可以配置一台正向代理服务器,通过正向代理
服务器上网。
反向代理:反向代理代替服务端接受请求(项目部署在两个tomcat上通过nginx 反向代理配置去访问)
在高并发场景下,一个tomcat服务器可能承受不了那么高的并发量和访问量,所以需要多个服务器分担
这个工作,而nginx在高并发的场景下表现是尤为突出的,此时nginx就可以代理多个服务器去接收用户请求,
最后交给其中一个服务器处理.

18:springCloud

## pringCloud由什么组成
Nacos (注册中心,配置中心)
Spring Cloud Eureka:服务注册与发现
Spring Cloud Zuul/GetWay:服务网关
Spring Cloud Ribbon:客户端负载均衡
Spring Cloud Feign:声明性的Web服务客户端
Spring Cloud Hystrix,Sentinel:断路器
#服务熔断
(一般是指软件系统中,由于某些原因使得服务出现了过载现象,为防止造成整个系统故障,从而采用的一种保
护措施)
#服务降级
(是在服务器压力陡增的情况下,利用有限资源,根据当前业务情况,关闭某些服务接口或者页面,以此释放服
务器资源以保证核心任务的正常运行)
Spring Cloud Confifig:分布式统一配置管理
# 新建的子模块调用 远程调用其他模块接口,若依把调用接口这部分放到了 api 模块中,并没有启动类
# @ComponentScan 注解的作用是扫描 @SpringBootApplication 所在的 Application 类所在的
包(basepackage)下所有的 @component 注解(或拓展@component 的注解)标记的 bean,并注册到
spring 容器中。
我那个远程调用的api模块里面都没有启动类,我怎么把生命的bean注入到springboot里面呢。
解决 Spring Boot 中不能被默认路径扫描的配置类:
在Spring中也有一种类似与Java SPI的加载机制。它在META-INF/spring.factories文件中配置接口的
实现类名称,然后在程序中读取这些配置文件并实例化。

19 :JVM

什么是JVM?
答:JVM是Java虚拟机的缩写,是Java编程语言的核心组件之一。它是一个在计算机上运行Java字节码的虚拟机,可以将Java源代码编译成字节码,然后在任何安装了Java Runtime Environment(JRE)的计算机上运行。

JVM的主要功能是什么?
答:JVM的主要功能包括:

将Java源代码编译成字节码
执行字节码
存储和管理内存
管理线程
提供垃圾收集和内存泄漏检测机制
什么是JIT(Just-In-Time)编译器?
答:JIT编译器是一种将频繁使用的字节码编译成本地机器代码以提高性能的编译器。在Java虚拟机中,JIT编译器会对新代码进行编译,并将频繁使用的字节码编译成本地机器代码,以提高程序运行速度。

JVM有哪些版本?
答:JVM有多个版本,其中最新的是Java SE 17。每个版本都有不同的功能和性能特性。例如,Java SE 17提供了更好的垃圾收集和内存管理功能,以及更高效的编译器。

JVM的内存管理机制是什么?
答:JVM的内存管理机制主要包括以下几个方面:

垃圾收集:JVM负责管理内存垃圾,即不再使用的对象和数组。垃圾收集器会定期扫描堆内存,将不再使用的对象和数组移动到垃圾回收器中,以便释放内存空间。
内存分配:JVM负责分配内存,包括堆内存和栈内存。当程序需要使用新的数据时,JVM会为其分配堆内存;当程序执行完毕后,JVM会回收不再使用的堆内存,以便释放内存空间。
内存管理:JVM还提供了内存管理机制,以防止内存泄漏和缓冲区溢出等问题。例如,JVM提供了垃圾回收器来检测内存泄漏,并在发现问题时采取相应的措施。
什么是Java程序的“堆”?
答:Java程序的“堆”是指用于存储对象实例的数据结构。在Java中,每个对象都有一个对应的堆。堆是一个动态数据结构,可以根据需要动态扩展或收缩。在程序运行时,JVM会自动管理堆内存,并将不再使用的对象和数组移动到垃圾回收器中。

什么是“垃圾收集器”?
答:“垃圾收集器”是指用于自动管理内存垃圾的程序。在Java虚拟机中,垃圾收集器会定期扫描堆内存,并将不再使用的对象和数组移动到垃圾回收器中。垃圾回收器可以选择将这些对象和数组移动到持久性存储中(如磁盘),或者直接释放内存空间。

JVM有哪些类型的垃圾收集器?
答:JVM有多种类型的垃圾收集器,包括标记-清除、复制和标记-整理等不同类型。其中,标记-清除垃圾收集器是最常用的一种,它通过标记-清除算法来自动管理内存垃圾。复制垃圾收集器是将一个对象复
JVM的垃圾回收器如何工作?
答:JVM的垃圾回收器会定期扫描堆内存,并将不再使用的对象和数组移动到垃圾回收器中。具体而言,垃圾收集器会检测以下三种情况:
存活对象:垃圾收集器会检查堆内存中是否还存在一些正在被使用的对象,如果有,它们会被标记为活动对象。活动对象是指正在被引用、未被释放的对象。
不再使用对象:当垃圾收集器确认所有活动对象都已被销毁时,它会将所有未被使用的对象标记为“垃圾”,并将它们移动到垃圾回收器中。这些对象变为垃圾的原因可能是由于程序员没有正确地释放它们,或者由于程序运行时产生了大量的对象。
垃圾回收:当垃圾收集器发现有大量的垃圾时,它会将这些垃圾回收到持久性存储中(如磁盘),或者直接释放内存空间。这个过程称为垃圾回收(Garbage Collection)。
什么是“年龄”(Age)?
答:在Java中,“年龄”(Age)是指一个对象或数据结构在JVM中的副本数量。年龄通常用于衡量对象或数据结构被垃圾回收器回收的频率。年龄较大的对象或数据结构可能更难被回收,因为它们需要更多的时间和资源来被垃圾回收器发现和处理。

JVM的“年龄”(Age)有什么用处?
答:JVM的“年龄”(Age)通常用于衡量对象或数据结构被垃圾回收器回收的频率。年龄较大的对象或数据结构可能更难被回收,因为它们需要更多的时间和资源来被垃圾回收器发现和处理。这意味着,较老的对象或数据结构可能需要更长时间才能被重新利用。

JVM有哪些本地方法?
答:JVM有许多类型的本地方法(Native Methods),它们使用C或C++编写并调用JVM方法。这些方法主要用于实现高级功能,例如即时编译(JIT)和扩展平台无关性。JVM提供了多个本地方法,以支持不同平台上的Java程序。

20:K8S

什么是Kubernetes?
K8s是一个开源的容器编排系统,它可以自动部署、管理和扩展应用程序。它基于Linux内核,可以在大型集群中管理数百个容器,并实现高可用性和高性能。

Kubernetes的核心特性是什么?
Kubernetes的核心特性包括:可扩展性、可用性、自动扩展和故障恢复。它使用监控和自我管理的无人值守方式来部署和管理容器,可以处理大规模的应用程序部署和扩展。此外,它还可以实现自动容器增长和存储虚拟化,从而提高资源利用率和减少管理开销。

为什么要使用Kubernetes?
使用Kubernetes可以提高应用程序的可靠性和性能。它可以实现无人值守的部署和扩展,减少人工干预,提高部署效率和资源利用率。此外,它还可以自动处理故障和恢复,保证应用程序的连续性和可用性。

你如何解决Kubernetes的高延迟问题?
解决Kubernetes的高延迟问题可以采取以下措施:

优化网络:使用更快的网络连接和更好的网络设置,可以减少延迟。
实现负载均衡:使用K8s的负载均衡算法,可以在多个实例之间分配负载,减少单个实例的负载。
增加服务器数量:通过增加服务器数量,可以增加服务器的处理能力,从而减少延迟。
优化部署:通过优化部署流程,可以减少部署时间,从而减少延迟。
什么是Kubeless?
Kubeless是指使用Kubernetes as a Service(CaaS)的方式来部署应用程序。它可以将Kubernetes集群作为一种服务来提供,从而降低了部署成本和管理开销。使用Kubeless可以简化应用程序的部署和管理,并提高了应用程序的可靠性和性能。

你如何解决Kubernetes的安全问题?
解决Kubernetes的安全问题可以采取以下措施:

使用HTTPS:使用HTTPS可以加密通信,防止中间人攻击。
使用token:使用K8s的token技术,可以对用户进行身份验证,防止未经授权的访问。
使用RBAC(基于角色的访问控制):使用K8s的RBAC技术,可以根据用户的角色授予不同的访问权限,防止未经授权的访问。
监控和日志:使用K8s的监控和日志功能,可以及时发现和处理安全问题,防止攻击者获取敏感信息。
你如何解决Kubernetes的资源利用率问题?
解决Kubernetes的资源利用率问题可以采取以下措施:

实现计算节点和存储节点的负载均衡:通过实现计算节点和存储节点的负载均衡,可以将负载均衡到多个节点上,从而提高资源利用率。
使用内存池和存储池:通过使用内存池和存储池,可以预先分配资源,避免频繁的请求和响应,从而提高资源利用率。
避免过度扩展:通过避免过度扩展,可以在应用程序增长时逐步增加节点,从而避免资源浪费和性能下降。
优化部署流程:通过优化部署流程,可以减少部署时间,从而减少资源消耗和利用率问题。
什么是kops?
Kops是Kubernetes的容器编排工具。它可以自动部署、管理和扩展应用程序,并支持多种编排策略,例如Kops、Deployment和StatefulSet等。Kops通过集中管理容器的创建、部署和扩展,可以提高效率和减少错误。

你如何解决Kubernetes的可用性问题?
解决Kubernetes的可用性问题可以采取以下措施:

实现多副本部署:通过实现多副本部署,可以确保应用程序的数据备份和恢复能力,从而提高可用性。
使用etcd作为数据存储:etcd是一个分布式键值存储系统,可以存储大量的数据和配置信息,从而提高数据可靠性和容错性。
实现数据分区和故障恢复:通过实现数据分区和故障恢复,可以在数据损坏或故障时快速恢复数据,从而提高可用性。
监控和日志:通过监控和日志功能,可以及时发现并处理故障,从而提高可用性。
什么是Label Selector?
Label Selector是Kubernetes中的一个功能,它可以根据标签选择要部署的应用程序。它可以根据应用程序的名称、标签、属性等信息来选择要部署的应用程序。Label Selector通常与Pod的资源选择结合使用,可以快速地找到需要部署的应用程序。

你如何解决Kubernetes的部署流程问题?
解决Kubernetes的部署流程问题可以采取以下措施:

使用持续集成和持续交付(CI/CD)工具:CI/CD工具可以自动化应用程序的构建、测试和部署流程,从而提高效率和减少错误。
使用Docker Compose或Kubernetes YAML:使用Docker Compose或Kubernetes YAML等配置文件可以简化应用程序的部署流程,并提高代码的可读性和可维护性。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值