一、Java && JDK

1.ArrayList和LinkedList区别

  • Arraylist是基于数组内存连续,随机访问查询快,扩容机制:新建数组,拷贝旧数组,性能较慢,不是尾部插入的话后面需要复制
  • Linkedlist是基于双向链表内存分散,增删快,访问查询必须使用Iterator,需要遍历较慢,内部维护Node类,需要大量创建对象,性能慢

2.static和final的区别

关键词 修饰物 影响
final 变量 分配到常量池中,程序不可改变其值
final 方法 子类中将不能被重写
final 不能被继承
static 变量 分配在内存堆上,引用都会指向这一个地址而不会重新分配内存
static 方法块 虚拟机优先加载
static 可以直接通过类来调用而不需要new

3.lamda表达式

函数式接口:接口中只有一个抽象方法
匿名内部类可以用lamda表达式简写,都是在重写方法

interface A{void run(int a);
}
A a = i -> {System.out.println(i);};
//等价于
A a = new A() {@Overridepublic void run(int a) {}
};

4.如何判断对象可以被回收?

- 引用计数法在对象中添加一个引用计数器,当有地方引用这个对象的时候,引用计数器的值就+1,当引用失效的时候,计数器的值就-1,当引用计数器被减为零的时候,标志着这个对象已经没有引用了,可以回收了!有对象相互引用的时候不能被检测到->内存泄漏
- 可达性分析法通过一系列的称为 GC Roots 的对象作为起点, 然后向下搜索; 搜索所走过的路径称为引用链/Reference Chain, 当一个对象到 GC Roots 没有任何引用链相连时, 即该对象不可达, 也就说明此对象是不可用的,但它们到GC Roots是不可达的, 因此也会被判定为可回收的对象。- 垃圾回收算法:标记(碎片太多),拷贝(费内存),标记压缩(耗时长)

5.Java中的集合 HashMap HashSet TreeMap TreeSet

Hash:无序,Tree:有序需提供比较器
Map:键值对有伴随数据,Set:只有键无伴随数据HashMap和HashTable区别:HashTable是线程安全的
就是HashMap把所有方法加上synchronized
ConcurrentHashMap和HashMap区别:
Con 提供了分段锁,segments划分为多个HashTable,只有发生Hash冲突
才会线程阻塞,效率又高又安全,两次hash,第一次不加锁

6.http和https区别

Http协议运行在TCP之上,明文传输,客户端与服务器端都无法验证对方的身份;Https是身披
SSL(Secure Socket Layer)外壳的Http,运行于SSL上,SSL运行于TCP之上,是添加了加密和认证机制的
HTTP。二者之间存在如下不同:
端口不同:Http与Http使用不同的连接方式,用的端口也不一样,前者是80,后者是443;
资源消耗:和HTTP通信相比,Https通信会由于加减密处理消耗更多的CPU和内存资源;
开销:Https通信需要证书,而证书一般需要向认证机构购买;
Https的加密机制是一种共享密钥加密和公开密钥加密并用的混合加密机制。

7.哈希表

- 哈希表内部数组长度一般为质数,便于均匀散列
- 哈希函数一般为取模运算 key%数组长度,通过关键字计算数组下标 i=f(key) arr[i]=value
- 哈希冲突:不同的key通过哈希函数计算得到相同的下标值
- 解决办法:1.链表式解决:当相同的key在一个下表存储的时候,进化成链表结构(例如,数组长度7,key=22和key=15计算都应存到下表i=1的位置,这时候在1位置 22->15 用链表存储)2.开放地址-线性探测:新位置=模运算位置+i,一直往后探测3.开放地址-平方探测:新位置=模运算位置+i^24.开放地址-双哈希:新位置=模运算位置+i*hash2(key)
- 哈希表满了:存储了超过70%,再建一个新表,旧的数据按照哈希函数计算搬家
- 优缺点:优点效率高,O(1)。缺点:hash函数设计不好和表太满会影响效率

8.内存泄露和内存溢出

内存泄漏:是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄漏似乎不会有大的影响,但内存泄漏堆积后的后果就是内存溢出。
内存溢出:内存不够用二者关系:
内存泄漏的堆积最终会导致内存溢出- 内存溢出原因:内存中加载的数据量过于庞大,如一次从数据库取出过多数据;集合类中有对对象的引用,使用完后未清空,使得JVM不能回收;代码中存在死循环或循环产生过多重复的对象实体;使用的第三方软件中的BUG;启动参数内存值设定的过小
- 内存溢出的解决方案:第一步,修改JVM启动参数,直接增加内存。(-Xms,-Xmx参数一定不要忘记加。)第二步,检查错误日志,查看“OutOfMemory”错误前是否有其 它异常或错误。第三步,对代码进行走查和分析,找出可能发生内存溢出的位置。第四步,使用内存查看工具动态查看内存使用情况
- 内存泄漏问题该如何解决分析器、详细日志、引用对象、泄漏警告、基准测试、代码审查

9.消息队列比对

Kafka ActiveMQ RabbitMQ RocketMQ
高性能高吞吐,单机容量有限百万 JMS规范,事务,数据量小单机万 erlang开发开源,学习成本高单机万 java实现高可用单机十万

10.类加载器

类加载器:把class文件加载到JVM方法区存为元数据模板 的 快递员
类加载过程:加载1.通过类全限定名(类标识+包名+类名)获取.class文件字节流2.将这个字节流标识的静态结构转化为方法区的数据结构(元数据模板)3.在堆内存中生成一个代表这个类的java.lang.Class对象链接验证 Verfy验证字节码文件符合当前虚拟机要求 CAFEBABY开头准备 Prepare为静态变量分配内存,赋值fina修饰的编译的时候就分配了,这里显式初始化这里不会为实例变量初始化,new才会分配内存解析 Resolve将常量池符号引用转换为直接引用初始化执行类构造器方法<cinit>() 保证父类<cinit>()这个方法是所有的static变量,static代码块 自动拼接起来的,按照源代码顺序执行虚拟机必须保证<cinit>()在多线程下同步执行 (单例模式可以用静态变量来实现)类加载器:BootstrapClassLoaderC++编写,是jvm的一部分并不继承ClassLoader没有父类加载器载扩展类和应用程序类 加载器,并指定为他们的父类加载器用来加载java核心类库,只加载javax sun开头的ExtClassLoaderJava编写继承自ClassLoader父类加载器为启动类加载器加载 jre/lib/ext目录扩展类AppClassLoaderJava编写继承自ClassLoader父类加载器为启动类加载器加载应用程序类双亲委派机制:为了保证安全性当遇到一个类需要加载当前类加载器会向上委派请求加载,上层父加载器加载就行了如果不归上层加载器加载的话,把任务还给底下的加载器加载

11.java对象分配

线程栈上分配 - 如果一个对象的作用域不会逃逸出方法之外,那可以将这个对象分配在栈上
TLAB分配
是否进入老年代
eden分配对象内存分配的两种方法:1.指针碰撞(Serial、ParNew等带Compact过程的收集器) 假设Java堆中内存是绝对规整的,所有用过的内存都放在一边空闲的内存放在另一边,中间放着一个指针作为分界点的指示器那所分配内存就仅仅是把那个指针向空闲空间那边挪动一段与对象大小相等的距离这种分配方式称为“指针碰撞”(Bump the Pointer)。 2.空闲列表(CMS这种基于Mark-Sweep算法的收集器) 如果Java堆中的内存并不是规整的,已使用的内存和空闲的内存相互交错那就没有办法简单地进行指针碰撞了虚拟机就必须维护一个列表,记录上哪些内存块是可用的在分配的时候从列表中找到一块足够大的空间划分给对象实例,并更新列表上的记录这种分配方式称为“空闲列表”(Free List)。

12.强软弱虚引用

强引用:普通对象引用
软引用:SoftReference<T> m = new SoftReference<>(new T());m->SoftReference对象 => T对象T对象被软引用指向,gc的时候内存不够首先被回收可以做缓存
弱引用:WeakReferencegc直接回收
虚引用:PhantomReference

13.垃圾回收器

Serialstop-the-world 单线程,年轻代
Serial Oldstop-the-world 单线程,老年代
Parallel Scavenge多线程 年轻代
Parallel Old多线程 老年代
ParNew和CMS配合使用
CMSgc线程和主线程并发执行并发一直扫,扫描完了就回收三色标记法:gc从根部开始梳理对象黑色:被扫描到灰色:自己被标记,属性还没来得及标记白色:未被扫到的产生问题:错标,漏标remark阶段必须从头扫描一遍
G1优化cms的错标,漏标问题

二、多线程

1.多线程创建的方式

1. 继承Thread类,重写run方法,start方法启动
2. 实现Runnable接口,重写run方法,用Thread类代理启动或用ExcutorService线程池代理execute启动
3. 实现callable接口,从写call方法,是有返回值的,配合Future获取异步执行的结果,用ExcutorService线程池代理submit启动

2.线程的生命周期状态

创建->就绪->运行->销毁|     |<----阻塞

3.线程方法

sleep() 休眠,并不会释放对象锁
yield() 线程礼让方法,不一定成功,礼让后进入就绪状态不阻塞
join() 强行加入,其他线程进入阻塞状态
Thread.State 线程状态类
get/setPriority() 设置线程优先级
setDaemon()设置为守护线程,jvm级别
synchronized 线程同步,让别的线程阻塞
可重用锁:ReentrantLock,显示调用多线程并发协作模型:管程法和信号灯标志位法
获取对象锁后才能调用以下方法
wait() 线程一直等待,直到其他线程通知,与sleep不同,会释放锁
notify() 唤醒一个处于等待状态的线程
notifyAll() 唤醒同一个对象上所有调用wait()方法的线程﹐优先级别高的线程优先调度

4.如何避免死锁

两个线程拥有对方的锁又想获取对方资源
避免一个线程获取多个对象锁
破坏其中一个条件

发生的4个必要条件互斥:一个资源只能被一个进程使用请求与保持:一个进程因资源而阻塞,对方又拿住资源不放不剥夺条件:进程获得资源,未用完前,不能被强行剥夺循环等待:若干进程头尾相接循环等待资源

5.ThreadLocal

每个线程Thread中有一个 ThreadLocal.ThreadLocalMap threadLocals
可以存储当前线程中需要用到的值
set get remove 方法都是获取当前线程的threadLocals操作缺点:会造成内存泄露溢出,key是弱引用

6.线程池

线程池参数:核心线程数量非核心线程数量空闲线程存活时间空闲线程存活时间单位Runnable任务队列threadFactory 线程工厂handler 拒绝策略工作队列中的任务已到达最大限制  线程数量也达到最大限制新任务提交进来拒绝线程池创建:Executors.newCachedThreadPool  cpu100%核心线程0,非核心线程上限2^31-1,有多少个任务最多就有多少个线程,线程复用机制corePoolSize:0maximumPoolSize: Integer.MaxkeepAliveTimeSynchronousQueueExecutors.newFixedThreadPool    任务队列多内存溢出corePoolSize:nmaximumPoolSize:nkeepAliveTimeLinkBlockQueueExecutors.newSingleThreadExecutor   Fixed的单一版本  corePoolSize:1maximumPoolSize:1keepAliveTimeLinkBlockQueue自己 new ThreadPoolExecutor进入的任务首先用核心线程处理,如果没有核心线程了,任务进入队列队列满了,就用非核心线程处理,如果也满了就报错核心线程处理完后线程复用处理其他任务提交优先级:核心线程->队列->非核心线程执行优先级:核心线程->非核心线程->队列线程池拒绝策略:ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常ThreadPoolExecutor.DiscardPolicy:丢弃任务,但是不抛出异常ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新提交被拒绝的任务ThreadPoolExecutor.CallerRunsPolicy:由调用线程(提交任务的线程)处理该任务

7.锁

悲观锁坏事一定会发生,先做预防上锁
乐观锁坏事未必会发生,事后补偿- 自旋锁,乐观锁的实现

8.ReentrantLock和synchronized对比

synchronized 非公平锁0.jvm层面实现,细粒度和灵活度差1.经过编译,会在同步块前后形成monitorenter和monitorexit这个两个字节码指令在执行monitorenter指令时,首先要尝试获取对象锁,把锁的计算器加1monitorexit锁的计算器减1
ReentrantLock0.api层面,细粒度和灵活度好1.等待线程可中断 lock.lockInterruptibly()2.公平锁,多个线程等待同一个锁时,必须按照申请锁的时间顺序获得锁Synchronized锁非公平锁ReentrantLock默认的构造函数是创建的非公平锁可以通过参数true设为公平锁,但公平锁表现的性能不是很好。

三、数据库

1.事务的四大特性?

事务特性ACID:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)。
原子性,是指事务包含的所有操作要么全部成功,要么全部失败回滚。undologundolog中会形成一个链表,链首是最新的旧记录,链尾是最旧的旧记录一致性,是指一个事务执行之前和执行之后都必须处于一致性状态。比如a与b账户共有1000块,两人之间转账之后无论成功还是失败,它们的账户总和还是1000。
隔离性,跟隔离级别相关,如read committed,一个事务只能读到已经提交的修改。MVCC锁(多版本并发控制)当前读-读取的都是最新版本的数据select lock in share mode,update,delete,insert, select for update加锁快照读-读取的是历史版本数据普通select快照读的时候生成一个readview视图,包含三个字段| trx_list | up_limit_id | low_limit_id |活跃事务id集合   活跃事务最小id   活跃事务中即将分配的下一id每一行数据的隐藏字段DB_TRX_ID 创建这条记录或最后修改记录的事务idDB_ROLL_PTR 回滚指针,指向数据上一版本 (undolog链表形成)DB_ROLL_ID  隐藏主键,如果没有主键的的话|---|---|---|---|---|根据【可见性算法  事务id和读视图查询】得到读取的是哪个版本的数据MVCC最终结论:在RC隔离级别里,每次进行快照读操作的时候都会重新生成新的readview,所以每次可以查询到最新的结果记录在RR隔离级别里,只有当前事务在第一次进行快照读的时候才会生成readview,之后进行的快照读操作都会沿用之前的readview幻读:快照读和当前读一起使用的时候会产生幻读for update加锁可以解决持久性,是指一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的,即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作。redolog 是一个往里面追加的文件,空闲的时候再把数据写进数据库,保证事务持久化成功两阶段提交先写redolog (处于prepare状态)|再写binlog|提交事务 redolog置为commit提交
日志系统:binlog 二进制日志 -> 数据同步恢复undolog 回滚日志redolog 前滚日志slowlog 慢日志errorlog 错误日志

1.1 MySQL事务隔离级别

事务隔离级别 脏读 不可重复读 幻读
读未提交(read-uncommitted)
不可重复读(read-committed)
可重复读(repeatable-read)
串行化(serializable)

2.redis setnx

可以实现分布式锁,当且仅当key不存在才能存入成功。在springRedisTemplate中用setIfAbsent

3.redis为什么快

基于内存:Redis是使用内存存储,没有磁盘IO上的开销。数据存在内存中,读写速度快。
单线程实现( Redis 6.0以前):Redis使用单个线程处理请求,避免了多个线程之间线程切换和锁资源争用的开销。
IO多路复用模型:Redis 采用 IO 多路复用技术。Redis 使用单线程来轮询描述符,将数据库的操作都转换成了事件,不在网络I/O上浪费过多的时间。
高效的数据结构:Redis 每种数据类型底层都做了优化,目的就是为了追求更快的速度。

4.Redis 数据类型有哪些?

1、String:最常用的一种数据类型,String类型的值可以是字符串、数字或者二进制,但值最大不能超过512MB。
2、Hash:Hash 是一个键值对集合。
3、Set:无序去重的集合。Set 提供了交集、并集等方法,对于实现共同好友、共同关注等功能特别方便。
4、List:有序可重复的集合,底层是依赖双向链表实现的。
5、SortedSet:有序Set。内部维护了一个score的参数来实现。适用于排行榜和带权重的消息队列等场景。

5.Redis有哪些持久化方式,优缺点?

1、RDB(Redis DataBase:通过创建快照来获取存储在内存里面的数据在某个时间点上的副本。
2、AOF(Append Only File:将被执行的写命令写到AOF文件的末尾。
AOF文件过大
AOF重写:重复命令或者可以合并的命令,减少AOF日志尺寸,减少内存占用,加快数据库恢复时间
即使 BGREWRITEAOF 执行失败,也不会有任何数据丢失,因为旧的 AOF 文件在 BGREWRITEAOF 成功之前不会被修改。
从 Redis 2.4 开始,AOF 重写由 Redis 自行触发, BGREWRITEAOF 仅仅用于手动触发重写操作。

6.Redis的过期删除策略

1、惰性删除:只会在取值的时候删除,对cpu友好,占用过多内存
2、定期删除:定期抽取一批数据检查进行删除,通过频率策略优化cpu,对内存友好

7.Redis分布式锁如何实现

先拿setnx来争抢锁,抢到之后,再用expire给锁加一个过期时间防止锁忘记了释放。
如果在setnx之后执行expire之前进程意外crash或者要重启维护了,那会怎么样?
set指令有非常复杂的参数,这个应该是可以同时把setnx和expire合成一条指令来用的!Boolean result =
stringRedisTemplate.opsForValue().setIfAbsent(lockKey,"zhuge",10,TimeUnit.SECONDS);问题1:上锁期间服务器挂了,没法释放锁,其他请求不能得到锁解决:设置锁的超时时间
问题2:上锁期间,超时时间到了锁被释放,业务代码还没执行完解决:锁续命,启动另外一个线程监听时间快到了续命,业务执行完手动删除锁加入线程id,当前线程加的锁只能当前线程删除生产上用redisson实现分布式锁
问题3:redis主从节点切换过程中锁失效解决:用zookeeper,redlock,半数节点一致数据才算加锁成功

8.数据库索引

- 索引是排好序的数据结构,只是一个快速查找表,用来迅速知道物理位置
- MySQL索引早期用的二叉树,现在用B+Tree,也可以选择Hash结构(不支持范围查询)什么是B+Tree:首先,每个节点都可以存储多个元素每个父节点都出现在子节点中,位于最大或最小,所以所有叶子节点包含全量信息,叶子节点才存储数据(数据行的物理位置)并且每个叶子节点都有序指向下一个叶子,形成一个有序链表
- MySQL存储引擎有MyISAM和InnoDB(针对表)MyISAM:有三个文件:.MYD存储数据   .MYI存储索引(非聚集)    .FRM存储设计结构执行SQL:判断列有没有建立过索引,有的话到MYI文件查找索引(存储数据行位置),再到MYD文件查询数据行InnoDB:有两个文件:.ibd存储数据和索引(聚集,按照B+Tree建的)   .FRM存储设计结构 叶子节点包含了完整的数据记录注意:主键索引树存储的是数据,其他字段的索引存储的值是主键id。需要回表进行查找
- 多个字段建联合索引:最左前缀匹配原则,B+Tree每个节点 按照第一个字段排序,不能排就按照第二个字段排序必须要按照有序性,才能很好的匹配,不遵循此原则可能会全表扫描,效率慢例如:(name,age,pos)作为联合索引,查询的时候where name='xxx'在前,否则不会走索引

9.MySQL优化

- SQL前面加上explain可以查看sql执行计划来优化type(system,const,range,index,all)key 索引是否命中
- 不超过3个表的关联操作。尽量单表查询走索引,利用Java程序来编织数据,提高性能
- 使用联合索引的时候 where后的条件顺序尽量按照最左匹配原则来查询
- 尽量按照业务加上非空约束,索引类型为UNIQUE的时候,字段一定要用非空约束,否则不会走索引,B+Tree是不会用空值建立索引的
- 不要使用IN NOT IN <> IS NULL 都不会走索引like 'xxx%' 前缀匹配才会走范围索引
- 索引字段尽可能少占用存储空间
- 索引字段基数尽可能多
- 索引字段并不是越多越好

10.缓存数据库双写不一致

删除缓存-更新数据库-再更新缓存 用分布式锁
用redisson中的读写锁,读与写,写与写 互斥 (用于读多写少)

11.缓存雪崩,穿透,失效

缓存雪崩:大量缓存数据同时间失效,导致用户直接发起大量请求到数据库,产生瓶颈。
1、生成随机失效的缓存时间数据;
2、让缓存节点分布在不同的物理节点上;
3、生成不失效的缓存数据;
4、定时任务更新缓存数据;缓存穿透:用户请求数据,例如ID为负数,不存在缓存里,也不存在数据库里,会造成缓存穿透。
1、无意义数据放入缓存,下一次相同请求就会命中缓存;
2、IP过滤;
3、参数校验;
4、布隆过滤器;缓存失效:由于缓存热点键到时失效导致用户请求直接访问数据库
1、用久缓存;
2、分布式锁a.单体应用—>互斥锁—>zookeeper ,redis实现。

四、Spring

0.spring的理解

  • 控制反转(IOC):Spring容器使用了工厂模式为我们创建了所需要的对
    象,我们使用时不需要自己去创建,直接调用Spring为我们提供的对象即可,这就是控制反转的思想。
  • 依赖注入(DI):Spring使用Java Bean对象的Set方法或者带参数的构造方法为我们在创建所需对象
    时将其属性自动设置所需要的值的过程就是依赖注入的基本思想。
  • 面向切面编程(AOP):在面向对象编程(OOP)思想中,我们将事物纵向抽象成一个个的对象。而在面向切面编程中,我们将一个个对象
    某些类似的方面横向抽象成一个切面,对这个切面进行一些如权限验证,事物管理,记录日志等公用操
    作处理的过程就是面向切面编程的思想。

1.Spring中的Bean

  • Definition
    Bean的建立,由BeanFactory读取Bean定义文件,并生成各个实例。
    Setter注入,执行Bean的属性依赖注入
  • Pre-initialized
    如果bean实现了BeanNameAware,BeanFactoryAware,BeanPostProcessors,InitializingBean等接口,则执行其方法,还有initMethod()方法
  • 工作
  • Destory
    实现DisposableBean接口则执行其方法,还有执行destroyMethod()方法
Bean创建过程原理:根据Userservice.class调用无参构造生成对象,推断构造方法是否可用对这个对象进行依赖注入,属性赋值初始化前 @PostConstruct初始化 实现InitializingBean接口初始化时自动调用 afterPropertiesSet()方法初始化后,判断是否有AOP生成代理对象 userServiceProxy extends Userservice代理对象里注入一个 UserService target -> 就是之前生成的普通对象代理对象先执行切面方法,再执行target的被代理方法(逻辑业务)代理对象就是beanspring事务为@Transactional注解的方法所在类生成一个代理对象,也是aop1.事务管理器创建一个连接conn2.conn.autocommit = false3.target.run() //执行被代理的方法 sql1  sql2...4.conn.commit() or conn.rollback()事务失效:普通对象调用自己的子方法,子方法上有事务注解,就会失效。要用代理对象(自己注入自己)调用那个子方法,代理开启事务的逻辑才会执行才不会失效。
综上所述:理解spring底层 使用了 代理模式 切入bean开启了事务、bean上有Aop 都会生成一个代理对象。执行代理方法的时候,有一些额外的逻辑切入进来执行了深刻理解bean的aop,target(普通对象)被代理后,有一些额外的逻辑切入进去了@Configuration也是使用了 --代理模式--回调:BeanPostProcessorBeanNameAware

2.SpringGateway网关作用

黑名单拦截
日志
参数校验
鉴权
限流
负载均衡
路由转发
监控
灰度分流
多协议支持
熔断、降级、重试、数据聚合等服务降级:突发高并发流量的时候,保证核心业务支付下单等正常,非核心评论,查询什么的降级,快速失败服务熔断:某个下游服务出现异常,达到一定阈值后断掉下游服务。保证上有服务不会阻塞被拖垮Hystrix是分布式容错机制,阻止故障连锁反应导致雪崩

3.高并发如何限流

计数器法,每隔一段时间处理多少个请求
漏桶算法,桶中只有几个线程来处理请求
令牌桶算法,一个线程往桶中放令牌,新来的请求拿到令牌才能被处理。调整桶大小和放入频率控制流量

4.SpringBoot自动配置

@SpringBootApplication包含三个注解:@SpringBootConfiguration 自动配置@ComponentScan 扫描包路径@EnableAutoConfiguration 自动装配@Configuration和@Bean定义配置类,把类路径放到META-INF/spring.factories文件中由spring spi机制自动扫描注册到ioc容器中

5.SpringBoot启动后

6.什么是Hystrix

阻止故障连锁反应雪崩,实现熔断
快速失败,优雅降级
实时监控和警告资源隔离:线程隔离:给每一个command(服务)分配一个单独的线程池信号量隔离:拿到信号量才能继续往后调用
熔断降级:

五、设计模式

1.七大原则

1.开闭原则:对扩展开放,对修改关闭
2.里氏替换原则:继承必须确保超类所拥有的性质在子类中仍然成立
3.依赖倒置原则:要面向接口编程,不要面向实现编程。抽象不依赖细节,细节依赖抽象
4.单一职责原则:控制类的粒度大小、将对象解耦、提高其内聚性。
5.接口隔离原则:要为各个类建立它们需要的专用接口
6.迪米特法则:只与你的直接朋友交谈,不跟“陌生人”说话。提高模块独立,降低耦合
7.合成复用原则:尽量先使用组合或者聚合等关联关系来实现,其次才考虑使用继承关系来实现。

2.单例模式

构造器必须私有,保证内存中只有一个类实例饿汉式:定义为静态常量,由jvm的类装载器装在的时候来实例化保证线程安全
懒汉式(线程安全):需要的时候才new,需要double check,上锁private static volatile P inst;if(inst==null){synchronized(P.class){if(inst==null){inst = new P();}}}return inst;有一个问题:new的时候会发生指令重排,有可能其他线程获取的是null解决:这时在用volatile修饰单例引用。volatile告诉程序jvm寄存器内的不是安全的,去主存读取单例不安全,因为有反射可以破坏枚举类默认是单例,且反射不能破坏
静态内部类,也是用jvm类装载器实例化 来保证线程安全

3.工厂模式

调用者和实现类解耦
简单工厂模式:帮调用者new,不符合开闭原则
工厂方法模式:代码复杂,好扩展
抽象工厂模式:把工厂也抽象成工厂的工厂,工厂里的“产品”面向接口编程

4.建造者模式

对象的建造和表示分离。
具体的建造者是相互独立,利于系统扩展
侧重于对象创建的步骤

5.原型模式

clone()
浅拷贝:对象是两个,但是他们的属性的引用可能是同一个
深拷贝:连属性也要拷贝

【更新中】Java后端开发面试八股内卷文相关推荐

  1. Java 后端开发面试总结:25 个技术专题(最全面试攻略)

    另送福利: java 面试准备 准确的说这里又分为两部分: 1.Java 刷题 2.算法刷题 Java 刷题:此份文档详细记录了千道面试题与详解:  !     私信我回复[03]即可免费获取 很多人 ...

  2. 金九银十!阿里面试官告诉你面试Java后端开发面试会被问到什么问题?面试稳了!

    前言 面试java后端开发,基本上会问你一些理论基础,以及你对一些技术点的理解,或者说深一点问一问你所掌握的深浅如何? 如果之前有实习经验,还会问一些你做过的项目,以及你在其中担任的角色,就是说你负责 ...

  3. JAVA后端开发面试经典

    1.String的不可变性 一但一个字符串在堆内存创建,它是不能被改变的,我们应该注意所有的关于String类的方法不是改变一个字符串本身,而是重新返回一个新的字符串. 如果我们需要一个频繁的改变一个 ...

  4. Java后端开发面试宝典(JavaSE+数据结构+MySQL+线程+网络+JVM)

    欢迎大家点赞+收藏哦 JavaSE篇 1. Java面向对象的思想 2. 面向对象与面向过程 3. 面向对象的三大特性 4. 类与对象 5. 抽象类和接口的区别 6.Java中的异常体系 7. Jav ...

  5. Java后端开发面试7大核心总结,为你保驾护航金九银十!

    前言 本篇分享的面试题内容包括:Java基础面试题.Spring面试点.MySQL数据库.JVM核心知识点.Spring Cloud面试题.Redis相关.Java多线程与并发系列等. 一.Java基 ...

  6. 维恩贝特面试java后端开发面试经验

    1 自我介绍 2 链表和数组区别 3 sort方法实现 4 知道哪些排序 5 给定的空间小于要排序的数据 如何排序 5 synchronized 的使用 以及底层实现 6 lock和synchroni ...

  7. Java后端开发面试编程题

    题目: 老板一共需要给某个员工发奖金n元,可以选择一次发1元,也可以选择一次发2元,也可以选择一次发3元.请问老板给这位员工发放完n元奖金共有多少种不同的方法? 数据范围:1 <= n < ...

  8. 谈一个普通211计算机研究生学渣的Java后端开发的面试之路

    谈一个普通211计算机研究生学渣的Java后端开发的面试之路 为什么写这篇博客? 2020年是特殊的一年,新冠肺炎肆虐全球,疫情造成的影响远比人们想象的严重,所产生的蝴蝶效应让很多不可能变成可能,奥运 ...

  9. 面试 — 京东(Java后端开发)

    京东一面 - Java后端开发 2022.04.12 视频面试 1h 项目: 介绍一下你做的这几个项目? 为什么采用RabbitMQ?理由是什么? 为什么进行分库分表?数据量多大?分库分表带来了哪些问 ...

最新文章

  1. 2014年10月18日
  2. c语言考试经典编程题目及答案,经典练习C语言编程的题目及答案整理
  3. 转挣扎的菜鸟 - 当OD不能装载也不能附加程序时
  4. GDCM:处理DICOM文件的示例
  5. 平板电脑安装软件_概述嵌入式工业平板电脑的安装方法和注意事项!
  6. hadoop的python框架指南_Python之——用Mrjob框架编写Hadoop MapReduce程序(基于Hadoop 2.5.2)...
  7. 阿卡接口_阿卡vs风暴
  8. svn中status为missing的文件的处理方式
  9. Linux磁盘读写速率测试
  10. 申通回应被京东“封杀”;Kotlin 1.4.0 发布 | 极客头条
  11. CISCO的NAT配置笔记
  12. windows下namp的基本操作命令
  13. java实现在线预览--poi实现word、excel、ppt转html
  14. 后端+数据库(pycharm+mysql):使用 “flask”制作的调查量表/问卷
  15. Google(谷歌)博客搜索中文测试版发布
  16. python硬件编程实践感悟_7年编程的心得感悟,这么是多么痛的领悟
  17. 程序的依赖和引用是什么?
  18. 基于改进U-GAT-IT的人像手绘风格转换系统(源码&教程)
  19. 决定人生高度的,不是智力,而是体力
  20. GAIN: Missing Data Imputation using Generative Adversarial Nets学习笔记

热门文章

  1. 基于Java的电影订票网站的设计与实现
  2. 【存储】软件定义存储,看这一篇就够了!
  3. 《计算广告》第3版重磅出版!上一版豆瓣评分8.8
  4. 论如何搞死一台Linux
  5. 一篇关于JSPatch, 线上直接改BUG的利器,OC语法转换时遇到的坑
  6. 学成在线 第9天 讲义-课程预览 Eureka Feign Ribbon
  7. Nodejs https请求
  8. 人工智能 垂直领域 行业_垂直与水平AI创业公司
  9. “蜗居”家中等风来河北再度雾霾锁城 市民
  10. 微信支付提示:同一笔交易不能多次提交