Java 基础面试题
Java 全栈面试题
Java基础
1、JVM内存结构
1 )、堆(主要用来存储对象)
2 )、栈(先进后出、一般存局部变量(int, short, long, byte, float, double, boolean, char)和对象句柄)
3 )、方法区(又叫静态区,跟堆一样,被所有的线程共享。方法区包含所有的class和static变量,运行时常量池都分配在 Java 虚拟机的方法区之中(String))
4 )、PC 寄存器(每个线程启动的时候,都会创建一个PC(Program Counter,程序计数器)寄存器。PC寄存器里保存有当前正在执行的JVM指令的地址。 每一个线程都有它自己的PC寄存器,也是该线程启动时创建的。保存下一条将要执行的指令地址的寄存器是 :PC寄存器。PC寄存器的内容总是指向下一条将被执行指令的地址,这里的地址可以是一个本地指针,也可以是在方法区中相对应于该方法起始指令的偏移量)
2、什么是GC
1)、垃圾回收机制(用来清理堆区对象,无栈区对象句柄内存空间)
3、& 和 && 的区别
1)、&是不带短路的,&&带短路
4、集合Set如何保证值不重复
1)、HashSet底层是用的哈希算法(实际调用的方法是equals和hashcode方法)
5、HashMap和Hashtable有什么区别?
1)、HashMap 可以Key和Value是null、HashTable则不可以(Key、Value)
2)、HashMap 线程不安全、HashTable线程安全
6、Set 保证添加顺序的集合类是哪个?
1)、LinkedHashSet (底层是哈希+双链表所以记录了插入顺序)
7、HashMap、HashTable、ConcurrentHashMap 区别
1)、HashMap(底层数组+链表、初始空间16)
2)、HashTable(底层数组+链表、效率低、初始空间11)
3)、ConcurrentHashMap(底层分段数组+链表、线程安全、JDK1.5之后提供的(取代HashTable)、使用了final和volatile特性实现了无堵塞的Map)
锁分段技术:首先将数据分成一段一段的存储,然后给每一段数据配一把锁,当一个线程占用锁访问其中一个段数据的时候,其他段的数据也能被其他线程访问。
ConcurrentHashMap提供了与Hashtable和SynchronizedMap不同的锁机制。Hashtable中采用的锁机制是一次锁住整个hash表,从而在同一时刻只能由一个线程对其进行操作;而ConcurrentHashMap中则是一次锁住一个桶。
ConcurrentHashMap默认将hash表分为16个桶,诸如get、put、remove等常用操作只锁住当前需要用到的桶。这样,原来只能一个线程进入,现在却能同时有16个写线程执行,并发性能的提升是显而易见的。
8、ArrayList 初始空间大小?
1)、10
9、ArrayList 数组已满扩容
1)、0.5倍
9、ArrayList和Linkedlist区别
1)、ArrayList(底层数组、查询,修改 快 (因为不改动坐标))
2)、Linkedlist(底层双链表、删除、新增 快 (因为链表结构两边动一下就OK))
10、Servlet 中 service方法作用是什么?
1)、通过源码可以查看 sevice方法是分发请求的 如果是get则调用doget方法、post则调用dopost方法
2)、service方法是顶级接口里的方法
11、Servlet 生命周期
1)、init 初始化方法 - service 逻辑方法 - destory 销毁
12、接口在JDK版本迭代中有什么变化
1)、1.7(Switch可以使用String类型、Catch多个异常、泛型实例的创建可以通过类型推断来简化 可以去掉后面new部分的泛型类型,只用<>就可以了、)
2)、1.8(接口的默认和静态方法、Lambda 表达式)
13、比较经典的一个面试题吧 String str = new String("adwa");创建了几个对象
1)、2个
14、String str = "a"+"b" 创建了几个对象
1)、3个
15、业务场景:两个对象属性名一样 如何快速复制对象A里面属性值到对象B中
1)、反射
16、List<String> strList = new ArrayList<String>() ; 存入int类型的值 怎么保存?
1)、反射(反射动态擦除泛型)
2)、这个面试题 其实主要考的就是泛型的理解
17、类加载顺序
1)、父类static
2)、子类static
3)、初始化父类的其他成员变量
4)、父类构造方法
5)、初始化子类的其他成员变量
6)、子类构造方法
19、动态代理和Cglib代理区别
1)、动态代理(实现接口)
2)、Cglib(是asm开源包,以实现子类的方式来生成代理对象)
20、Java 都有哪些代码块
1)、普通代码块
2)、构造代码块
3)、静态代码块
4)、同步代码块
21、JDBC 预编译和不预编译的区别
1)、预编译 (简单理解:提前编译好了Sql 比较节省时间)
2)、不预编译(就是在执行的时候才会去编译Sql)
22、switch 在哪个版本中加入了 String 类型
1)、1.7
23、用最有效率的方法计算2乘以8
1 )、位运算
24、Java 如何跳出多重循环
1)、可以加标记A,break A
25、什么是断言
1)、也就是所谓的assertion,是jdk1.4后加入的新功能。它主要使用在代码开发和测试时期,用于对某些关键数据的判断,如果这个关键数据不是你程序所预期的数据,程序就提出警告或退出。
26、反射创建对象用哪个方法
1)、newInstance
27、获取class对象的方式
1)、.class
2)、getClass()
3)、forName
28、反射如何拿到私有字段
1)、暴力反射(getDeclaredFields 可以拿到所有的字段包括私有)
29、什么是可变参
1)、形式参数比如String... strs 这叫可变参 底层维护的是个数组
30、jvm参数的设置和jvm调优
1)、答案
31、什么是年轻代内存溢出
1)、答案
32、内部类:静态内部类和匿名内部类的使用和区别
1)、静态内部类
2)、匿名内部类
33、反射机制会不会有性能问题?
1)、会有性能问题(但是得执行几百万次以上 才会感觉到,所以可以忽略)
34、finally块一定会执行吗?
1)、不一定(正常来说执行了try里面内容 finally才会执行,但是执行了try里面内容 finally也是不一定就一定会执行)
35、正常情况下,当在try块或catch块中遇到return语句时,finally语句块在方法返回之前还是之后被执行?
1)、在 try return 语句执行之后 返回之前执行,如果finally里面也有return 则 覆盖try里面的return
36、字节流和字符流区别是什么?
1)、字节流(字节流操作的直接就是文件)
2)、字符流(字符流操作的是缓冲区,缓冲区在操作文件)
在硬盘上的所有文件都是以字节形式存在的(图片,声音,视频),而字符值在内存中才会形成。
37、递归读取文件夹下的文件,代码怎么实现
1)、这个。。。。就是考递归的写法
38、检查型异常和非检查型异常的区别
1)、检查型异常在Java中所有不是RuntimeException派生的Exception都是检查型异常。当函数中存在抛出检查型异常的操作时该函数的函数声明中必须包含throws语句。调用改函数的函数也必须对该异常进行处理,如不进行处理则必须在调用函数上声明throws语句。
2)、非检查型异常:在Java中所有RuntimeException的派生类都是非检查型异常,与检查型异常相对抛出非检查型异常可以不在函数声明中添加throws语句,调用函数上也不需要强制处理。即可以不使用try...catch进行处理,但是如果有异常产生,则异常将由JVM进行处理,也会导致程序中断。
39、@RequestBody 请求方式是Post Content-Type - application/x-www-form-urlencoded 能接到数据吗
1)、接不到(@RequestBody 这个只能接受 Content-Type - application/json 数据)
40、Http 请求方式是Post 可以用@RequestParam 接受到参数吗?
1)、可以 但是必须是Content-Type - application/x-www-form-urlencoded 因为这是属于表单提交 提交上去格式为?name=123&qwe=123
41、@RequestParam 和 @RequestBody 区别是什么
1)、@RequestParam 接受请求头数据
2)、@RequestBody 接受请求体
42、@RequestParam 默认required属性是true还是false
1)、true,如果不传 返回Http 400 Bad Request
43、@RequestBody 只能用在Post 请求吗?
1)、不是,也可以用在get请求 把数据写到请求体里面
44、什么是守护线程
1)、守护线程是执行后台作业的线程。可以通过设置setDaemon方法把线程设置成守护线程
45、线程锁 synchronized 加到方法上 那么实例里有两个都是同步方法,共享一道锁吗?
1)、是的 这是实例锁 当线程拿到锁相当于拿到该实例所有同步方法的权限,其余线程都在外面等待
46、线程锁 synchronized 同步方法,和同步静态方法的区别
1)、同步方法 实例锁
2)、同步静态方法 class锁
47、线程锁 synchronized方法块 和 静态方法 使用synchronized方法块 参数 有啥差别?
1)、一个是使用this (普通方法)
2)、一个是使用.class(静态方法)
48、调用 object 的 wait、notity、notityall需要注意什么?
1)、需要拿到线程锁 否则直接抛出异常
49、线程调用wait和sleep有啥区别?
1)、sleep 不释放锁,使用这个方法 线程不会在实例的等待队列中
2)、wait 释放锁 被唤醒后 , 会继续抢锁
50、线程 start和run方法区别
1)、start 是 启动线程并且调用run方法
2)、run是调用实例方法
51、volatile 作用
1)、volatile关键字的作用是强制从公共堆栈中取得变量的值,而不是从线程私有数据栈中取得变量的值、不会引发重排序问题 建议写操作放到最后对volatile字段赋值
52、i++ 是原子操作吗
1)、不是
53、栈内存是只有一块还是每个线程都有一块?
1)、每个线程都有一块
54、synchronized 添加了同步和不添加除了互斥性还有什么其他特点?
1)、在拿到锁的时候会清空本地缓存(寄存器)会去共享空间拿最新值
2)、在放锁的时候会将本地缓存修改直接放到共享空间
55、线程可见性和重排序分别什么意思?
1)、可见性就是本地缓存和共享空间 数据不一样 ,其他线程修改的值 本线程没有立刻知道一般通过volatile和synchronized解决
2)、重排序就是代码实际写的顺序在编译的时候可能会打乱
56、为什么重写了equals方法必须重写hashcode方法?
1)、简单说就是确保是同一个对象
57、.java 编译后 一对一生成 .class文件吗?
1)、如果类中包含静态代码块,或者内部类 则是一对多关系,如果部署服务器,这.java文件必须把所对应的.class一并升级
58、多线程编写应该避免什么?
1)、死锁
2)、对共同对象数据 的访问控制,说白了就是加锁,利用多线程是为了更好的完成业务需求,但是同时也应该避免掉并发造成的串改共同数据
59、Synchronized 修饰的方法 如果是两个不同实例 可以同时访问吗?
1)、可以 因为修饰的是实例
60、什么是线程池?
1)、创建线程要花费昂贵的资源和时间,如果任务来了才创建线程那么响应时间会变长,而且一个进程能创建的线程数有限。
为了避免这些问题,在程序启动的时候就创建若干线程来响应处理,它们被称为线程池,里面的线程叫工作线程。
从JDK1.5开始,Java API提供了Executor框架让你可以创建不同的线程池。比如单线程池,每次处理一个任务;数目固定的线程池或者是缓存线程池(一个适合很多生存期短的任
务的程序的可扩展线程池)。
61、内存泄漏与溢出的区别
1)、内存泄漏是指分配出去的内存无法回收了。
2)、内存溢出是指程序要求的内存,超出了系统所能分配的范围,从而发生溢出。比如用byte类型的变量存储10000这个数据,就属于内存溢出。
3)、内存溢出是提供的内存不够;内存泄漏是无法再提供内存资源。
62、数据库连接池大小设置为多少合适(最大) 详情:https://www.cnblogs.com/dtyy/p/14191969.html
1)、连接数 = ((核心数 * 2) + 有效磁盘数)。比如:服务器 CPU 是 4核 i7 的,连接池大小应该为 ((4 * 2) + 1) = 9 ~ 10个。具体需要根据实际业务场景做调整。
63、Java 子类是否可以覆盖父类的静态方法
1)、不可以,子类调用就是调用子类静态方法,父类也是调用自身
64、创建线程有几种方式
1)、继承Thread类
2)、实现Runnable接口(JDK 1.1提供,无返回值,不能抛出异常,实现方法是run)
3)、实现Callable接口(JDK 1.5提供,有返回值,能抛出异常,实现方法是call)
4)、Executor工具类创建线程池
65、实现Runnable接口和Callable接口有什么区别
1)、Runnable接口run方法无返回值,Callable接口call方法有返回值,是个泛型,和Futrue和FutureTask配合用来获取异步执行结果
2)、Runable接口run方法只能抛出运行时的异常,且无法捕获处理;Callable接口call方法允许抛出异常,可以获取异常信息。
66、JVM 新生代、老年代、永久代区别 详情:https://www.cnblogs.com/honey01/p/9475726.html
TIPS:在JVM内存中 堆被分为两个区域,新生代和老年代,新生代 ( Young ) 又被划分为三个区域:Eden、From Survivor、To Survivor。
堆大小 = 新生代 + 老年代。其中,堆的大小可以通过参数 –Xms、-Xmx 来指定。
JVM 每次只会使用 Eden 和其中的一块 Survivor 区域来为对象服务,所以无论什么时候,总是有一块Survivor区域是空闲着的。
因此,新生代实际可用的内存空间为 9/10 ( 即90% )的新生代空间。
1)、新生代:新生代几乎是所有 Java 对象出生的地方,即 Java 对象申请的内存以及存放都是在这个地方。Java 中的大部分对象通常不需长久存活,具有朝生夕灭的性质。 当一个对象被判定为 "死亡" 的时候,GC 就有责任来回收掉这部分对象的内存空间。新生代是 GC 收集垃圾的频繁区域。
2)、老年代:当新生代对象经历了15次GC后依然存活(每次GC操作会给数字+1。 默认为:15,可以通过参数 -XX:MaxTenuringThreshold 来设定),就会进入老年代 但这也不是一定的,对于一些较大的对象 ( 即需要分配一块较大的连续内存空间 ) 则是直接进入到老年代。
3)、永久代:就是方法区,存放类信息,java 1.7后 出现常量池,常量都进入了常量池中,要么版本之前都存放在方法区内。(可通过-XX:PermSize和-XX:MaxPermSize来指定最小值和最大值。) ,查询相关资料 永久代也会有GC操作
66、JVM 永久代、元空间区别 详情:https://blog.csdn.net/pange1991/article/details/81941597
2)、永久代:永久代的内存是在虚拟机中,如果加载类很多很多,容易出现永久代内存溢出 PermGen space
3)、元空间:JDK 1.8中并不存在永久代的概念,替换成了元空间,元空间和永久代主要区别就是,元空间存放的位置在本机内存,所以不用考虑空间大小限制
66、JVM 串行、并行、并发GC
1)、串行:垃圾回收线程和用户线程交替执行,且垃圾回收线程是单线程的,在执行垃圾回收线程时需要暂停用户线程,出现stop the world。GC线程是单线程的并非说明环境是单CPU下,在多核CPU下进行GC的时候只会使用单核CPU。
2)、并行:并行是多条垃圾回收线程并行工作,这里肯定是在多核CPU环境下,多条垃圾回收线程同时执行,此时用户线程处于暂停。
3)、并发:并发是垃圾回收线程和用户线程同时执行,也是在多核CPU环境下,垃圾回收线程和用户线程并发执行,也就是同一个时刻CPU0上执行用户线程,CPU1上有可能执行垃圾回收线程;
67、为什么说Java平台是独立性的
1)、因为java运行依赖的是虚拟机,虚拟机每个平台都有版本,因此java和平台没有关系,所以独立性
68、线程池大小配置多少合适
1)、https://www.cnblogs.com/cherish010/p/8334952.html
69、ConcurrentHashMap 和 HashTable 区别 (效率上)
1)、ConcurrentHashMap 采用锁分段技术,一次锁的数据很少。
2)、HashTable 一次锁一张表
70、ConcurrentHashMap 1.7 和 1.8版本区别
1)、详情
71、JDK 提供创建线程池方式
1)、Executors.newSingleThreadExecutor(),查看底层源码,它工作队列使用的是:LinkedBlockingQueue 这玩意会导致内存 100% (会把任务一股脑全丢进队列)
1)、Executors.newFixedThreadPool(),查看底层源码,它工作队列使用的是:LinkedBlockingQueue 这玩意会导致内存 100% (会把任务一股脑全丢进队列)
1)、Executors.newCachedThreadPool(),查看底层源码,会发现这线程总数量设置的Integer.MAX_VALUE,这会导致CPU 100%
框架
1、SpringMvc 运行原理
1)、用户发送请求至前端控制器DispatcherServlet。
2)、DispatcherServlet收到请求调用HandlerMapping处理器映射器。
3)、处理器映射器找到具体的处理器(可以根据xml配置、注解进行查找),生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。
4)、DispatcherServlet调用HandlerAdapter处理器适配器。
5)、HandlerAdapter经过适配调用具体的处理器(Controller,也叫后端控制器)。
6)、Controller执行完成返回ModelAndView。
7)、HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet。
8)、DispatcherServlet将ModelAndView传给ViewReslover视图解析器。
9)、ViewReslover解析后返回具体View。
10)、DispatcherServlet根据View进行渲染视图(即将模型数据填充至视图中)。
11)、DispatcherServlet响应用户。
2、SpringMvc 有个类把视图和数据都合并的一起的,叫什么?
1)、ModelAndView
3、如何向前端返回数据
1)、@reponseBody
2)、PrintWriter
3)、ResponseEntity
4、Spring IOC 初始化步骤
1)、Resource定位
2)、通过返回的resource对象,进行BeanDefinition的载入
3)、将BeanDefiniton注册到容器中
5、什么是 IOC(控制反转)
1)、简单理解就是:没有 IOC 自己创建对象,自己释放对象,编码者控制的对象的生命周期、加了 IOC 也就是控制反转 字面的意思 就是将自己干的这些事情 对象创建啊 什么的 转给了 IOC 容器去干 IOC容器帮你生成对象
6、什么是 DI (依赖注入)
1)、依赖注入:就是将 IOC 里面的容器 通过调用getBean的方法 通过反射机制来找到Bean并且生成Bean然后注入到类中
7、IOC 容器 底层是?
1)、IOC容器底层是一个 HashMap 将对象的依赖关系都存入这个HashMap中 (源码:DefaultListableBeanFactory类中可以看到 Map对象(beanDefinitionMap) )+ 反射
8、IOC 什么是 BeanDefiniton
1)、描述对象依赖关系的类(简单理解)
9、IOC BeanFactroy和ApplicationContext区别
1)、BeanFactroy (IOC容器系列顶层接口定义了IOC容器行为、初始化是第一次调用getBean时初始化Bean)
2)、ApplicationContext(是BeanFactroy的实现类(不是直接下级,具体的看IOC容器集成体系)包含BeanFactroy所有功能,并且新增:MessageSource, 提供国际化的消息访问 、事件传播 等功能(一共4个)、容器启动初始化Bean 区别就是BeanFactroy 在问题排查调用到这个类才能发现有问题 而ApplicationContext 在容器初始化就能检测到问题) )
10、Spring框架 底层都用了哪些设计模式
1)、详情
11、Spring AOP 底层是用哪种代理
1)、如果目标类实现了接口 那么用的就是动态代理
2)、如果目标类没有实现接口 那么用的就是Cglib
12、Spring IOC Bean生命周期
1)、创建实例 >> 初始化 >> 使用 >>销毁 (根据Bean的定义加载Bean的单例实例(默认单例可以通过@Scope来进行修改)然后依次加载依赖该Bean的依赖Bean、然后如果指定了initMethod方法执行初始化方法、使用、容器关闭调用DestroyMethod )
13、Spring IOC 核心容器
1)、BeanFactroy
14、Spring 框架哪些用法使用了AOP
1)、事务
15、Spring 事务传播行为
1)、PROPAGATION_MANDATORY(表示该方法必须运行在一个事务中。如果当前没有事务正在发生,将抛出一个异常)默认
2)、PROPAGATION_NESTED(表示如果当前正有一个事务在进行中,则该方法应当运行在一个嵌套式事务中。被嵌套的事务可以独立于封装事务进行提交或回滚。如果封装事务不存在,行为就像PROPAGATION_REQUIRES一样。)
3)、PROPAGATION_NEVER(表示当前的方法不应该在一个事务中运行。如果一个事务正在进行,则会抛出一个异常。)
4)、PROPAGATION_NOT_SUPPORTED(表示该方法不应该在一个事务中运行。如果一个现有事务正在进行中,它将在该方法的运行期间被挂起。)
5)、PROPAGATION_SUPPORTS(表示当前方法不需要事务性上下文,但是如果有一个事务已经在运行的话,它也可以在这个事务里运行。)
6)、PROPAGATION_REQUIRES_NEW(表示当前方法必须在它自己的事务里运行。一个新的事务将被启动,而且如果有一个现有事务在运行的话,则将在这个方法运行期间被挂起。)
7)、PROPAGATION_REQUIRES(表示当前方法必须在一个事务中运行。如果一个现有事务正在进行中,该方法将在那个事务中运行,否则就要开始一个新事务。)
16、Spring 事务隔离级别
1)、ISOLATION_DEFAULT(使用后端数据库默认的隔离级别。)默认
2)、ISOLATION_READ_UNCOMMITTED(允许读取尚未提交的更改。可能导致脏读、幻影读或不可重复读。)
3)、ISOLATION_READ_COMMITTED(允许从已经提交的并发事务读取。可防止脏读,但幻影读和不可重复读仍可能会发生。)Oracle 默认
4)、ISOLATION_REPEATABLE_READ(对相同字段的多次读取的结果是一致的,除非数据被当前事务本身改变。可防止脏读和不可重复读,但幻影读仍可能发生。)Mysql 默认
5)、ISOLATION_SERIALIZABLE(完全服从ACID的隔离级别,确保不发生脏读、不可重复读和幻影读。这在所有隔离级别中也是最慢的,因为它通常是通过完全锁定当前事务所涉及的数据表来完成的。)
17、Spring 事务回滚规则
1)、在默认设置下,事务只在出现运行时异常(runtime exception)时回滚,而在出现受检查异常(checked exception)时不回滚
2)、也可以声明在出现特定受检查异常时像运行时异常一样回滚。同样,也可以声明一个事务在出现特定的异常时不回滚,即使那些异常是运行时一场。
18、Spring 单例和JVM单例区别
1)、Spring 默认Bean是单例的 只是这个单例是相对于IOC容器里的Bean的单例
2)、JVM这个单例模式 则是相对于整个虚拟机的
19、Spring @Autowired 和 @Resource 区别
1)、@Autowired (按照类型找Bean)
2)、@Resource (可以同时按照类型和Name找Bean)
20、Spring 默认Scope
1)、单例
21、Spring bean 如何声明其他Scope
1)、@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
21、Spring Boot 有几种嵌入式容器
1)、Tomcat(默认)
2)、jetty(Jetty更适合开发一些长连接Web应用,如Web聊天)
3)、Undertow(Jboss)(Undertow是一个高性能非阻塞的Servlet容器,并发性能很好,但是不支持JSP)
22、Spring Boot application.yml 和 application.properties 配置文件区别
1)、加载顺序不同 先加载yml
2)、写法也不同 application.yml 我感觉这种的更直观
23、Spring Boot 和 Spring Mvc的关系是
1)、包含的关系 Springboot在自动装配的时候 自动包含了SpringMvc
24、Spring Boot 自动配置核心包是
1)、spring-boot-autoconfigure-1.4.1.RELEASE.jar
25、Spring Boot 启动原理(自动装配原理)
1)、@SpringBootApplication (@SpringBootApplication 注解,查找 META-INF/spring.factories 文件 根据条件自动装配类)
跳转:https://www.cnblogs.com/yi1036943655/p/10035557.html
26、Spring Boot 优点
1)、自动装配
2)、配置少
3)、内置服务器
4)、Actuator
5)、打包 .jar(当然war也可以) 可以在服务器直接使用 java -jar 启动
6)、起步依赖(start 节省了一个个找模块jar的烦恼)
27、如何修改Spring Boot 内置嵌入式容器
1)、修改Pom文件将tomat依赖换成对应的容器依赖
28、什么是Spring 条件注解
1)、@Conditional(有好多种 一般就是满足什么条件下加载Bean 类似于if)
29、Spring Boot 都提供哪些起步依赖
1)、spring-boot-starter-web
2)、spring-boot-starter-jdbc
3)、spring-boot-starter-security
4)、spring-boot-starter-data-jpa
还有好多 详情:https://www.cnblogs.com/yi1036943655/p/10035557.html
30、Spring Aop 定义方法后置通知 如果目标方法抛出异常 后置通知是否执行?
1)、不执行(后置通知是在方法成功返回之后 才会调用)
31、Spring Aop分为哪两种模式?
1、编程式Aop(提供Aop功能封装的类是 ProxyFactory)
TargetImpl taget = new TargetImpl(); ProxyFactory aopFactory = new ProxyFactory(taget ); aopFactory.addAdvisor(yourAdvisor); aopFactory.addAdvice(yourAdvice); TargetImpl targetProxy = (TargetImpl)aopFactory .getProxy();
2、声明式Aop(比较常用的写法,定义切点就可以了 提供Aop功能封装的类是 ProxyFactoryBean)
32、Spring Aop默认实现类
1)、DefaultAopProxyFactory
33、Spring Mvc 和 Struts2 区别
1)、Spring Mvc (核心是Servlet、单例(IOC)、针对Handler中的处理请求的方法进行mappring)
2)、Struts2 (核心是 过滤器、多例、针对Action类型进行mapping)
34、Mybatis $和#区别
1)、$(仅仅为一个纯碎的 string 替换,在动态 SQL 解析阶段将会进行变量替换、order by 中就需要使用 $.)
2)、#(解析成jdbc预编译语句、一个#代表一个占位符、可以很大程度上防止sql注入、并且类型转换。一般使用#)
35、Mybatis 缓存
1)、一级缓存(作用域在session 当 Session flush 或 close 之后,该Session中的所有 Cache 就将清空。)
2)、二级缓存(HashMap存储,不同在于其存储作用域为 Mapper(Namespace),并且可自定义存储源,如 Ehcache。)
对于缓存数据更新机制,当某一个作用域(一级缓存Session/二级缓存Namespaces)的进行了 C/U/D 操作后,默认该作用域下所有 select 中的缓存将被clear。
36、Mybatis 和 Habernate 区别
1)、Mybatis (比较容易上手、sql好优化、比较适合大型项目)
2)、Habernate(上手难度比较高、操作不好会产生很多多余内存空间、完整的对象/关系映射解决方案、使用Hql会查询出所有的字段(也可以使用自定义sql)、比较适合小型项目(个人理解))
37、Spring Data JPA 和 Habernate 区别
1)、JPA(Spring 对 JPA的一个整合)
2)、Habernate(是JPA规范的一个实现)
38、Habernate 对象状态
1)、transient 瞬时状态(新创建的对象没纳入session管理的对象)
2)、persistent 持久化状态(数据库中有)
3)、detached 离线状态(数据库中有,但是session中不存在该对象)
39、Habernate 缓存
1)、一级缓存(session)
2)、二级缓存(sessionFactory)
3)、查询缓存(sessionFactory级别,缓存一样的Hql语句)
40、Mysql 查询缓存
1)、sql 没变化 并且表数据和列、都无任何变化、会将查询的sql缓存下来
41、Redis和memcached:什么时候选择redis,什么时候选择memcached,内存模型和存储策略是什么样的
1)、首先在类型上选择 如果说需要除了K/V这种模式储存数据需要更丰富的储存类型就选择redis,因为redis有五种数据类型
2)、然后呢 redis 支持持久化 memcached 是不支持持久化的
3)、memcached 在内存 存储方面 会比redis快 memcached 适合做缓存,redis则适合做数据存储
42、Redis 持久化两种不同配置文件区别
1)、详解
43、Redis 主从复制机制?
1)、详解
44、微服务优缺点
1)、负责业务拆分成若干小业务
2)、微服务系统的微服务单元具有很强的横向扩展能力
3)、服务和服务之间通过Http来进行协议通信,服务可以采用任何语言和技术开发
4)、每个服务单元都是独立部署,微服务的修改和部署对其他服务没有影响
缺点
5)、微服务的复杂度
6)、分布式事务
7)、服务的瓜分
8)、服务的部署
45、消息队列点对点和发布/订阅模式的区别
1)、点对点(生产者只有一个消费者 单独给这个消费者发送消息)
2)、订阅(所有订阅了这个消费者 都会收到消息)
46、Rabbit Mq 交换机 几种类型 每种都有什么区别
1)、Direct exchange(直连交换机)
2)、Fanout exchange(扇型交换机)
3)、Topic exchange(主题交换机)
4)、Headers exchange(头交换机)
47、Rabbit Mq 和 ActiveMQ、Kafka 区别
1)、ActiveMQ (老牌的消息队列,Java编写,协议是JMS,采用多线程并发,资源消耗比较大、现在更新比较少,使用的也比较少,支持协议很多)
2)、Rabbit Mq (使用者多,协议是AMQP、网上案例比较多,数据存放在内存上,安全性和一致性支持较好)
3)、Kafka (数据很庞大(大数据) 日志分析,用户行为分析,支持动态扩容,它数据存储在队列上,实际是放到磁盘上,(某个文件)坏处就是不能保证消息的可靠性)
48、Hibernate 什么是懒加载
1)、集合、对象、(简单理解就是加载需要的属性,目前不需要的不加载,当调用属性或者集合的时候在加载)
49、Mybatis 如何快速执行插入操作(应该不全 我记得有个特殊的写法)
1)、foreach
2)、batch
50、Redis 有几种类型 详解
1)、String: 这是最常用的一个类型,是Key Value形式
2)、Hash: 一般用于储存对象,当然使用String也可以序列化储存,但是要来回反序列化
3)、List: 一般用于做消息队列
4)、Set: 一般用于处理交集、并集、差集,或者点赞等不重复集合操作
5)、Zset:一般用于排行榜
51、Redis 和 Memcached 区别
1)、redis使用单线程模型,数据顺序提交,redis支持主从模式,mencache只支持一致性hash做分布式
2)、redis支持数据落地,rdb定时快照和aof实时记录操作命令的日志备份,memcache不支持
3)、redis数据类型丰富,有string,hash,set,list, sort set,而memcache只支持简单数据类型
53、Spring Mvc 工作原理(底层源码分析(个人理解,欢迎大神一起讨论学习))
1)、SpringMvc最重要的类,就是DispatcherServlet,请求全部进入该类的doDisPatch方法,该方法内根据请求信息(requestMapping),进行查找HandlerMap是否有对应的HandlerExceutionChain , 如果有 则对该Controller进行校验,如果合法,则通过HandlerAdapter调用该Controller信息,并且返回ModelAndView
54、Spring IOC 容器默认是哪个(这个只是书上看到,并不准确哈。网上没找到)
1)、XML开头那个容器类
55、消息队列 如何保证消息发送成功
1)、详解
60、 Spring框架中需要引用哪些jar包,以及这些jar包的用途
1)、spring-core.jar:包含spring框架基本的核心工具类,其他组件都要使用这个包里面的类,是其他组件的核心;
2)、spring-bean.jar:是所有的应用都要用到的,包含访问配置文件、创建和管理bean以及进行IoC和DI操作所需的相关类;
3)、spring-aop.jar:包含使用AOP特性时所需的类;
4)、spring-context.jar:为spring核心提供了大量扩展;
5)、spring-dao.jar:包含spring DAO、spring Transaction进行数据访问的所有类;
6)、spring-hibernate.jar:包含spring对hibernate 2以及hibernate 3进行封装的所有类;
7)、spring-jdbc.jar:包含spring对JDBC数据库访问进行封装的所有类;
8)、spring-orm.jar:包含多DAO特性集进行了扩展;
9)、spring-remoting.jar:包含支持EJB、JMS、远程调用Remoting方面的类;
10)、spring-support.jar:包含支持缓存Cache、JAC、JMX、邮件服务、任务计划Scheduling方面的类;
11)、spring-web.jar:包含web开发时,用到spring框架时所需的核心类;
12)、spring-webmvc.jar:baohan Spring MVC框架相关的所有类;
13)、spring-mock.jar:包含spring一整套mock类来辅助应用的测试。
61、Spring 事务 方法内抛出异常但是被catch 那么这事务回滚吗?
1)、事务底层源码 TransactionAspectSupport类中invokeWithinTransaction方法可以看到 开启使用调用目标方法 如果抛出异常抛到spring源码这个层面来被catch才会导致事务回滚 否则是当正常结束
62、Spring 事务 事务方法A 调用非事务方法 那么是属于统一事务吗?
1)、是
63、什么情况下使用消息队列
1)、这个问题就是同步异步(同步的 用户等待时间过长用户体验度不好,所以使用异步后台处理前台更快给用户响应)
64、Spring Mvc HandlerExceutionChain 这个类作用?
1)、封装了 controller 和 拦截器链 在源码中SimpleURLHandlerMapping中定义了一个映射关系和Controller对应的HandlerMap
65、Spring Cloud Eureka 如何指定访问服务
1)、region: beijing
availability-zones: beijing: zone-2,zone-1 利用分区来进行规划
2)、metadata-map: zone:
zone-1 标识属于哪个分区
详情:https://www.cnblogs.com/junjiang3/p/9061867.html
66、Spring Cloud Eureka 服务发现注解 @EnableDiscoveryClient 和 @EnableEurekaClient 区别
1)、@EnableEurekaClient (网上说源码包含了 @EnableDiscoveryClient 注解 这个我没找到哈。。。。 可能我版本不够新,如果注册中心是Eureka 则推荐 该注解,基于spring-cloud-netflix)
2)、@EnableDiscoveryClient(如果是其他注册中心,则用该注解,基于spring-cloud-commons)
67、Eureka 配置项 hostName 和 instanceId 有什么区别
1)、hostName 配置的是 服务列表 houst 主机名
2)、instanceId 配置的是 status 那一栏服务的名字 默认的是有一个规则的 看源码可以查到
67、Eureka 的工作原理
1)、Applecation-server :服务提供者,Application-cliene:服务消费者
68、Hystrix @HystrixCommand 属性fallbackMethod 配置 返回值和参数和源方法不一致可以吗?
1)、可以方法名不一致,但是返回值和参数必须和加了注解的HystrixCommand保持一致
69、Hystrix 配置的@HystrixCommand 熔断方法 如果说这个方法内 调用若干个服务 是特定服务的调用熔断进入熔断方法还是都会进入?(这个可能我研究不深)
1)、都会进入(可能有指定的。但是我这研究不深 所以目前先这么写 ,知道的大佬 指点一下哈)
70、Hystrix 和 Feign 集成 fallbackFactory 和 fallback 属性的区别
1)、fallbackFactory 范围更大一点 可以得到具体的Exception异常信息
2)、fallback 这个范围小 得不到具体的信息
71、Zuul 配置了服务名映射,还可以使用serverId访问吗?
1)、可以
72、Zuul 底层使用的是 ribbon做的负载均衡 如何关闭?
1)、ribbon.eureka.enabled:false(这个配置有问题,可能是遗留的bug 如果使用的yml后缀的配置文件,则写一行)
73、Zuul如何制定负载均衡服务
#禁用掉ribbon的负载均衡 这个配置有问题 如果在yml文件配置则最好这么写
ribbon.eureka.enabled: false
#配置serviceId为SERVICE-HI的负载均衡名单
SERVICE-HI:
ribbon:
listOfServers: http://localhost:8763
74、Ribbon 、 Feign 、Zuul 都继承了 Hystrix格子的集成方式 是什么?
1)、Ribbon 通过@HystrixCommand 注解里面的一个属性 执行fallback方法
2)、Feign 通过一个属性关联一个类 去执行fallback
3)、Zuul 是通过一个服务 来指定 application名字 进行熔断
75、Dubbo 和 Spring Cloud 区别
1)、相同点:SpringCloud 和Dubbo可以实现RPC远程调用框架,可以实现服务治理
2)、不同点:
Spring Cloud:是一套目前比较网站微服务框架了,整合了分布式常用解决方案遇到了问题注册中心Eureka、负载均衡器Ribbon ,客户端调用工具Rest和Feign,分布式配置中心Config,服务保护Hystrix,网关Zuul Gateway ,服务链路Zipkin,消息总线Bus等。
Dubbo:内部实现功能没有SpringCloud强大(全家桶),只是实现服务治理,缺少分布式配置中心、网关、链路、总线等,如果需要用到这些组件,需要整合其他框架。
76、Zookeeper 集成在 Dubbo中相当于 Spring Cloud 的 Eureka
1)、Dubbo 服务发现是 Zookeeper 实现
77、原本的Zookeeper
1)、Zookeeper是用来保证分布式一致性的一个软件,不是为了服务发现注册而设计的。
只不过它的特性也可以被二次开发成服务发现注册中心罢了。这是在概念上的区别,具体的区别太多了。在Duboo这里被改造成做注册用了。
78、什么是服务降级
79、Eureka 服务提供者关闭服务不发送心跳,Eureka会立刻清除该服务在列表中吗?
1)、不会
80、Spring中单例、多例以及安全性和有状态bean、无状态bean区别
1)、跳转
2) 、链接2
3) 、官网 Bean 五种 scope
81、Spring中通过注解@Autowired注入service有两个实现类,现在打算注入某一个类,应该如何操作
1)、@Qualifier (需要在实现类上@service(value='a'))
2)、@Resource(service名称)
82、Feign 封装的 Ribbon , Ribbon 底层是 json
1)、说白了。用feign远程调用,那么要保证属性名一致。类型不一致是可以的
83、Redis 缓存击穿和穿透
1)、击穿:指查询一个一定不存在的数据,由于缓存是不命中时需要从数据库查询,查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到数据库去查询,造成缓存穿透。
解决方案:最简单粗暴的方法如果一个查询返回的数据为空(不管是数据不存在,还是系统故障),我们就把这个空结果进行缓存,但它的过期时间会很短,最长不超过五分钟。
2)、穿透:redis 和 db层都没有 解决办法:将不符合规则数据直接拦截,或者检测到多次访问该数据,将key 放入redis里
84、Redis 缓存雪崩
1)、雪崩就是 上面那2个导致的,redis不好用了 未发生作用,所有请求命中了数据库层,导致db层压力很大
85、Maven 中 package 和 install 区别
1)、package命令完成了项目编译、单元测试、打包功能,但没有把打好的可执行jar包(war包或其它形式的包)布署到本地maven仓库和远程maven私服仓库
1)、install命令完成了项目编译、单元测试、打包功能,同时把打好的可执行jar包(war包或其它形式的包)布署到本地maven仓库,但没有布署到远程maven私服仓库
1)、deploy命令完成了项目编译、单元测试、打包功能,同时把打好的可执行jar包(war包或其它形式的包)布署到本地maven仓库和远程maven私服仓库
86、Redis 提供八种数据淘汰策略
1)、volatile-lru:从已设置过期时间的数据集中挑选最近最少使用的数据淘汰。
2)、volatile-ttl:从已设置过期时间的数据集中挑选将要过期的数据淘汰。
3)、volatile-random:从已设置过期时间的数据集中任意选择数据淘汰。
4)、volatile-lfu:从已设置过期时间的数据集挑选使用频率最低的数据淘汰。
5)、allkeys-lru:从数据集中挑选最近最少使用的数据淘汰
6)、allkeys-lfu:从数据集中挑选使用频率最低的数据淘汰。
7)、allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰
8)、no-enviction(驱逐):禁止驱逐数据,这也是默认策略。意思是当内存不足以容纳新入数据时,新写入操作就会报错,请求可以继续进行,线上任务也不能持续进行,采用no-enviction策略可以保证数据不被丢失。
87、多个AOP的顺序怎么定
1)、可通过配置order(越小越先执行)
88、Redis 分布式锁原理
1)、Redis 实现分布式锁 主要解决微服务环境,只能让一台机器执行的业务场景,主要使用Redis的setnx命令(原子性)来加锁(只能有一台实例加锁成功),然后执行业务,接下来放锁,(要加上释放时间,避免实例宕机) 详情
89、Spring @Configuration原理
1)、加了该注解会被cglib代理
1)、默认该类下返回bean是单例(第二次调用底层会判断上次执行节点,会不执行new对象 返回以创建对象)
SQL
1、什么情况索引不会命中,会造成全表扫描
1)、详解
2、建立索引的条件
1)、不经常修改的列
2)、列的可选值多的(性别这种就不能建立索引)
3)、经常出现在where、order by、group by的列
3、sql优化
1)、表关联根据数据量大小,先关联后关联是不一样的
2)、那些可以过滤掉最大数量记录的条件必须写在WHERE子句的最末尾
3)、还有数据类型 一定要是合理的,别数字类型加了个“”进行查询
4)、利用索引,注意sql是不是引发了全表扫描
4、内连接加where和正常加where的区别
1)、内连接加where(就是先赛选一下表里数据在匹配)
2)、正常where 就是过滤表数据
5、mysql 常用函数
1)、日期啊,格式化啊、字符串连接、聚合函数、CASE When then、MD5
6、Oracle 表空间
1)、
7、Oracle 特有的函数
1)、
8、Mysql 默认账户 可以直接远程登录吗
1)、不可以远程登录、
9、什么是乐观锁,悲观锁,共享锁,排它锁
1)、乐观锁(数据库未实现,需要自己实现,一般都是通过一列来进行标识)
2)、悲观锁(数据库实现,操作之前先上锁)
3)、共享锁(对于多个不同的事务,对同一个资源共享同一个锁)
4)、排它锁(就是资源自己锁住,不容许修改,update、insert、delete会自动加排它锁)
10、mysql查询字段区不区分大小写?
1)、不区分
11、mysql 字段类型做比较或者链接两个表的时候 必须类型统一吗?
1)、不是必须
12、mysql 函数和存储过程区别
1)、函数(更像是加在where里的一个条件,比较简单一点,一般都是结合select来使用)
2)、存储过程(就是复杂的纯sql编写的一个逻辑,一般都是独立使用)
13、SQL注入的原理以及如何预防,并举例
1)、Mybatis 的 $和# 就是一个预防sql注入的写法
2)、还有数据库层框架的 占位传入参数 不直接写在连接字符串
3)、使用正则啊 过滤掉用户输入的非法内容
14、Union All 和 Union的区别
1)、Union All 两个表 分别查询出来多少数据就显示多少数据
2)、Union 就是说 两个表的查询语句 查询出来的数据 需要进行个去从
15、数据库 如果说A B表 关联外建是abc 那么 AB表共同有个列为C 我现在inner join后 我限制A表 C列为D值,那么B表会同样限制表数据吗? B表abc外建值一样 但是B表 C列的值并不是D能否都查出来?
1)、不会,可以查出来
15、mysql like 模糊查询 命中索引吗?
1)、% %不命中索引
2)、% 开头不命中索引
3)、结尾是%命中索引
16、mysql 索引类型
1)、聚簇索引(主键)
2)、二级索引
3)、覆盖索引
17、什么是覆盖索引
1)、简单说:就是检索在索引上的列 叫覆盖索引,执行计划 type = using index
18、什么是二级索引(辅助索引)
1)、简单说:就是数据结构data引用的是主键 结构是:1(索引值) - 1(主键)
19、什么是聚簇索引
1)、聚簇索引的叶子节点存储了一行完整的数据(我理解是储存的是在索引列上的列的值) 当然key是 主键
19、mysql隔离级别
1)、READ UNCOMMITTED(未提交读) 在READ UNCOMMITTED级别,事务中修改,即使没有提交,对其他事务也都是可见的,事务可以读取到未提交的数据,这也呗称为脏读,这个级别会导致很多问题,在实际应用中一般很少使用
2)、READ COMMITTED(提交读) 大多数数据库系统默认的隔离级别都是 READ COMMITTED(但mysql不是)。READ COMMITED满足前面提到的隔离型的简单定义;一个事务只能看到已经提交的事务所做的修改。换句话说,一个事务从开始直到提交之前,所做的任何修改对其他事务都是不可见的。这个级别也叫做不可重复读
3)、REPEATABLE READ(可重复读) 事务A在读到一条数据之后,此时事务B对该数据进行了修改并提交,那么事务A再读该数据,读到的还是原来的内容。详情参考:https://www.cnblogs.com/myseries/p/10931595.html ,另外可重复读会导致幻读,Mysql 利用 Mvcc(间隙锁)解决了幻读的问题
4)、SERIALIZABLE(可串行化) SERIALIZABLE 是最高的隔离级别,它通过强制事务串行执行,避免了前面说的幻读的问题,简单说:SERIALIZABLE 会读取的每一行数据上都加锁,可能导致大量超时和锁争用的问题,实际应用中很少使用这个隔离级别,除非特别需要保证数据一致性。
20、count(*)和count(字段名)的比较
1)、count(*) 是结果集的条数
2)、count(字段) 这个是字段列不为null的条数
20、数据库字段(类型)上优化
1)、更小通常更好:一般情况下,应该尽量使用可以正确储存数据的最小数据类型
2)、简单就好:简单数据类型的操作通常需要更少的cpu周期。例如整型比字符操作代价更低,因为字符集校对规则(排序规则)使字符比较比整型更复杂这里有两个例子:一个是应该使用Mysql内建类型而不是字符串来存储日期和时间,另一个是应该使用整数存储ip地址。
3)、尽量避免使用Null:如果计划在列上建索引,就应该避免设计成可为Null的列
20、DATATIME、TIMESAMP 区别
1)、DATATIME 默认值是null 时间范围是:’1000-01-01 00:00:00.000000’ 到 ‘9999-12-31 23:59:59.999999’。
2)、TIMESAMP 只使用 DATATIME 一半的存储空间,并且会根据时区变化,具有自动更新能力,默认值当前时间 时间范围:’1970-01-01 00:00:01.000000’ 到 ‘2038-01-19 03:14:07.999999’
20、int(1)、int(11) 区别
1)、Mysql 可以为整数类型制定宽度,例如int(11),对大多数应用来说这是没有意义的,它不会限制值的合法范围,只是规定了Mysql的交互工具(例如Mysql命令行客户端)用来显示字符的个数。对于存储和计算来说是一样的
21、varchar、char 区别
1)、varchar 类型用于存储可变长字符,是常见的字符串类型。它比定长类型更节省空间,因为它仅使用必要的空间。(例如:越短的字符串使用越少空间)
2)、char 类型用于存储定长字符,
22、当数据表中A、B字段做了组合索引,那么单独使用A或单独使用B会有索引效果吗?(使用like查询如何有索引效果)
1)、看A、B两字段做组合索引的时候,谁在前面,谁在后面,如果A在前,那么单独使用A会有索引效果,单独使用B则没有,反之亦然。同理,使用like模糊查询时,如果只是使用前面%,那么有索引效果,如果使用双%号匹配,那么则无索引效果
23、什么是回表(面试有人问我,记录一下)
1)、如果语句是 select * from T where k=5,即普通索引查询方式,则需要先搜索 k 索引树,得到 ID 的值为 500,再到 ID 索引树搜索一次。这个过程称为回表。(可能是技术不够哈 我觉得这玩意和辅助索引一样)
常用设计模式
1)、单例模式:懒汉式、饿汉式、双重校验锁、静态加载,内部类加载、枚举类加载。保证一个类仅有一个实例,并提供一个访问它的全局访问点。
2)、代理模式:动态代理和静态代理,什么时候使用动态代理。
3)、适配器模式:将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
4)、装饰者模式:动态给类加功能。
5)、观察者模式:有时被称作发布/订阅模式,观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。
6)、策略模式:定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。
7)、外观模式:为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
8)、命令模式:将一个请求封装成一个对象,从而使您可以用不同的请求对客户进行参数化。
9)、创建者模式:将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。
10)、抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
Docker
1、docker -v 挂载单个文件和挂载数据卷区别
1)、-v 挂载单个文件 是将宿主机上文件 挂载到容器内部(宿主机必须有相同文件)
2)、-v 挂在数据卷 是将宿主机上数据卷 挂载到容器内部
Http
1、Get请求和Post请求区别
1)、GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息。而POST数据不会显示在URL中。是放在Request body中。
2)、对参数的数据类型,GET只接受ASCII字符,而POST没有限制。
3)、GET请求参数会被完整保留在浏览器历史记录里;相反,POST请求参数也不会被浏览器保留
4)、GET请求只能进行url编码( application/x-www-form-urlencoded),而POST支持多种编码方式
5)、GET请求会被浏览器主动缓存,而POST不会,除非手动设置
6)、GET在浏览器回退时是无害的,而POST会再次提交请求
其他
1、强、弱、最终一致性 详解:https://blog.csdn.net/qq_43183527/article/details/101929099
1)、强一致性:对于关系型数据库,要求更新过的数据能被后续的访问都能看到,这是强一致性
2)、弱一致性:如果能容忍后续的部分或者全部访问不到,则是弱一致性
3)、最终一致性 :如果经过一段时间后要求能访问到更新后的数据,则是最终一致性。
Zookeeper
1、客户端对服务器列表处理机制是什么
1)、客户端对服务器列表进行拆分,然后对每一个进行链接,成功连接上则连接成功。这会引发出问题,比如列表里链接服务器1都成功了 那么服务器2-5岂不是永远链接失败?使用Collections工具类shuffle方法对列表进行打散,然后获取第一位进行链接,形成一个环
2、什么是会话转移
1)、会话转移是指客户端会话从一台服务器机器转移到了另一台服务器机器上。假如客户端和服务器S1之间连接断开后,如果尝试重连后,成功连接上新的服务器S2并且延续了有效会话,那么就可以说会话从S1转移到了S2上。
3、什么是会话管理
1)、Zookeeper的会话管理主要是由SessionTracker负责的,其采用了一种特殊的会话管理方式,我们称之为“分桶策略”。所谓的分桶策略,是指将类似的会话放在同一个区域中进行管理,以便于Zookeeper对会话进行不同区块的隔离处理以及同一区块的统一处理,分配原则是每个会话的“下次超时时间点(ExpirationTime)”
4、CONNECTIO_LOSS(连接断开) 和 SESSION_EXPIRED(Session 过期)两类连接异常
1)、有时会因为网络闪断导致客户端与服务器断开连接,或是因为客户端当前链接服务器出现问题导致连接断开,我们统称这类问题为“客户端与服务器连接断开”现象,即CONNECTION_LOSS。在这种情况下,Zookeeper客户端会自动从地址列表中重新逐个选取新的地址并尝试进行重新连接,直到最终成功连接上服务器
2)、SESSION_EXPIRED 是指会话过期,通常发生在CONNECTIO_LOSS期间。客户端和服务器连接断开之后,由于重连期间耗时过长,超过了会话超时时间(sessionTimeout)限制后还没有成功连接上服务器,那么服务器认为这个会话已经结束了,就会开始进行会话清理。但是另一方面,该客户端本身不知道会话已经失效,并且其客户端状态还是DISCONNECTED。之后,如果客户端重新连接上服务器,那么很不幸,服务器会告诉客户端会话已经失效。在这种情况下,用户就需要重新实力化一个Zookeeper对象
5、能否创建临时父节点
1)、会报错,父节点必须是持久节点
6、监听子节点变化,那么孙子辈变化是否可以监听
1)、不可以
7、监听子节点变化,那么子节点属性值变化是否可以监听
1)、不可以,只监听数量
8、zk有几种集群模式
1)、集群
2)、单机
3)、伪集群
9、znode类型
1)、持久节点
2)、持久顺序节点
3)、临时节点
4)、临时顺序节点
10、zk服务器角色
1)、Leader
2)、Follower
3)、Observer(不参与投票,只提供读)
11、zk 默认端口
1)、2181
12、zk是否支持动态扩容
1)、不支持,并且十分麻烦需要每个都修改配置文件
13、zk常用命令
1)、ls ,create ,delete ,setdata
14、zk如何进行Leader选举(不区分刚启动、和已有Leader挂的情况)
1)、需要明白2个概念一个是myid(serverid 当配置zk集群的时候配置的myid文件数值)、zxid(事务id)。流程如下:每个Server会给自己投一票(每次投票内容包含myid,zxid)的形式来投给自己 --- 接受来自各个服务器的投票 --- 处理投票(会进行别人的投票和自己的投票PK, 规则是优先检查zxid ,如果相同,则比较myid,比较大的则作为lead服务器),更新自身投票并发出 --- 统计投票(过半则当选) --- 更改服务器状态
15、zk主要功能
1)、Zookeeper 主要功能就是做分布式协调的
16、Eureka和Zookeeper的Cap理论
1)、Eureka是基于AP(可用性,分区一致性)。zookeeper是基于CP(一致性,分区容错性)。
17、Zookeeper 实现分布式锁原理
1)、"【从Paxos到Zookeeper 分布式一致性原理与实践】" 从该书,了解到的分布式锁实现,是在节点下创建节点,因为节点的唯一性,不管多少客户端,只能有一个创建成功,那么谁创建成功谁就获取到了锁
2)、创建临时顺序节点,判断自己节点是否是最小的,如果是最小的 就当自己获取到锁,如果不是最小的,就对上一个节点注册监听。详解
Kafka
1、Kafka 组件有什么
1)、Producer 生产者
2)、Consumer 消费者
3)、Broker kafka实例
4)、zookeeper
5)、Topic 主题
2、如何防止 Kafka 的消息不丢失
1)、生产者:1、使用同步发送 2、把ack设为1或者all,并且设置同步的分区数 >= 2
1)、消费者:把自动提交改成手动提交
3、Kafka 怎么保证消息的顺序消费
1)、消息发给一个分区,一个分区只有一个消费者进行消费。
4、Kafka 怎么避免重复消费
1)、在防止消息丢失方案中,如果生产者发送完消息后,因为网络抖动,没有收到ack,但实际broke已经收到了,此时生产者会进行重试,于是broker就会收到多条相同的消息,而造成消费者的重复消费,
怎么解决:
1、生产者关闭重试:会造成丢消息(不建议)
2、消费者解决非幂等性消费问题
解决方案:
1:在数据库中创建联合主键,防止相同的主键创建出多条记录,
2:使用分布式锁,以业务id为锁。保证只有一条记录能够创建成功
5、Kafka 副本
1)、可以理解为就是备份
6、多播和单播区别
1)、多播(多个地方消费):是指多个消费组里 最新的消费者可以接收到消息 多消费者接收
2)、单播(只有一个地方消费):是指一个消费组里 最新的消费组可以接收到消息 一个消费者接收
7、ack配置(在同步发送的前提下,生产者在获得集群返回的ack之前会一直堵塞)
1)、ack = 0: kafka-cluster 不需要任何broker收到消息,就立即返回ack给生产者,最容易丢消息,效率是最高的
2)、ack = 1(默认): 多副本之间的leader已经收到消息,并把消息写入到本地的log中,才会返回ack给生产者,性能和安全性是最均衡的
3)、ack = -1/all 。 里面有默认的配置min.insync.replicas=2(默认为1,推荐配置大于等于2,如果这个走默认配置,那么和ack = 1 无任何区别),此时就需要leader和一个follower同步完后,才会返回ack给生产者(此时集群中有2个broker已经完成了数据接收),这种方式最安全,但是性能最差
8、分区
1)、分区的概念就是为了将数据给分开存储,否则几个T的数据都在一个topic下会很大。默认的主题__consumer_offsets(整个kafka集群里只有一份),kafka内部创建了__consumer_offsets主题包含了50个分区。这个主题用于存放消费者某个主题的偏移量。因为每个消费者都会自己维护着消费的主题的偏移量,也就是说每个消费者会把消费者的主题的偏移量自助上报给kafka的默认的主题:__consumer_offsets。因此kafka为了提升这个主题的并发性,默认设置了50个分区,提交到哪个分区:通过hash函数:hash(consumerGroupId) % __consumer_offsets主题的分区数提交到该主题的内容是:key是consumerGroupid+topid+分区号,value是当前offset值文件中保存的消息,默认保存7天,七天到后消息会被删除。一个分区最多只能被一个消费组里的一个消费者所消费
9、HW和LEO
1)、LEO是某个副本最后消费的位置(log-end-offset)
2)、HW是已完成同步的位置。消息在写入Broker时,切每个Broker完成这条消息同步后,HW才会变化。在这之前消费者是消费不到这条消息的,在同步完成之后,HW更新之后,消费者才能消息到这条消息,这样的目的是防止消息的丢失
10、ISR(可能理解不对)
1)、我理解的就是当leader挂掉后,那么会从ISR集合中选一个当leader,他是一个同步和已同步的实例节点集合(如果性能较差 会被踢出)