Java基础

Java基础

1、final 在 Java 中有什么作用?

final 修饰的类叫最终类,该类不能被继承。

final 修饰的方法不能被重写。

final 修饰的变量叫常量,常量必须初始化,初始化之后值就不能被修改

2、String 属于基础的数据类型吗?

不属于

 

3、接口和抽象类有什么区别?

默认方法实现:抽象类可以有默认的方法实现;接口不能有默认的方法实现。

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

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

main 方法:抽象类可以有 main 方法,并且我们能运行它;接口不能有 main 方法。实现数量:类可以实现很多个接口;但是只能继承一个抽象类。

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

4HashMap 和 Hashtable 有什么区别?

存储:HashMap 运行 key 和 value 为 null,而 Hashtable 不允许。

线程安全:Hashtable 是线程安全的,而 HashMap 是非线程安全的。

推荐使用:在 Hashtable 的类注释可以看到,Hashtable 是保留类不建议使用,推荐在单线程环境下使

HashMap 替代,如果需要多线程使用则用 ConcurrentHashMap 替代。

 

5、如何决定使用 HashMap 还是 TreeMap?

对于在 Map 中插入、删除、定位一个元素这类操作,HashMap 是最好的选择,因为相对而言 HashMap 的

插入会更快,但如果你要对一个 key 集合进行有序的遍历,那 TreeMap 是更好的选择

 

6、ArrayList 和 LinkedList 的区别是什么?

数据结构实现:ArrayList 是动态数组的数据结构实现,而 LinkedList 是双向链表的数据结构实现。

随机访问效率:ArrayList 比 LinkedList 在随机访问的时候效率要高,因为 LinkedList 是线性的数据

存储方式,所以需要移动指针从前往后依次查找。

增加和删除效率:在非首尾的增加和删除操作,LinkedList 要比 ArrayList 效率要高,因为 ArrayList

增删操作要影响数组内的其他数据的下标。

综合来说,在需要频繁读取集合中的元素时,更推荐使用 ArrayList,而在插入和删除操作较多时,更推

荐使用 LinkedList。

 

7、线程池都有哪些状态?

RUNNING:这是最正常的状态,接受新的任务,处理等待队列中的任务。

SHUTDOWN:不接受新的任务提交,但是会继续处理等待队列中的任务。

STOP:不接受新的任务提交,不再处理等待队列中的任务,中断正在执行任务的线程。

TIDYING:所有的任务都销毁了,workCount 为 0,线程池的状态在转换为 TIDYING 状态时,会执行钩子

方法 terminated()。

TERMINATED:terminated()方法结束后,线程池的状态就会变成这个。

 

8、在 Java 程序中怎么保证多线程的运行安全?

方法一:使用安全类,比如 Java. util. concurrent 下的类。

方法二:使用自动锁 synchronized。

方法三:使用手动锁 Lock

 

9、怎么防止死锁?

尽量使用 tryLock(long timeout, TimeUnit unit)的方法(ReentrantLock、ReentrantReadWriteLock),

设置超时时间,超时可以退出防止死锁。

尽量使用 Java. util. concurrent 并发类代替自己手写锁。

尽量降低锁的使用粒度,尽量不要几个功能用同一把锁。

尽量减少同步的代码块

 

10、ThreadLocal 是什么?有哪些使用场景?

ThreadLocal 为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副

本,而不会影响其它线程所对应的副本。

ThreadLocal 的经典使用场景是数据库连接和 session 管理等。

 

11.单例防止反射漏洞攻击

private static boolean flag = false;

private Singleton() {

if (flag == false) {

flag = !flag;

} else {

throw new RuntimeException("单例模式被侵犯!");

}

}

public static void main(String[] args) {

}

12、Java 中操作字符串都有哪些类?它们之间有什么区别?

操作字符串的类有:String、StringBuffer、StringBuilder。

String 和 StringBuffer、StringBuilder 的区别在于 String 声明的是不可变的对象,每次操作都会生

成新的 String 对象,然后将指针指向新的 String 对象,而 StringBuffer、StringBuilder 可以在原

有对象的基础上进行操作,所以在经常改变字符串内容的情况下最好不要使用 String。

StringBuffer 和 StringBuilder 最大的区别在于,StringBuffer 是线程安全的,而 StringBuilder 是

非线程安全的,但 StringBuilder 的性能却高于 StringBuffer,所以在单线程环境下推荐使用

StringBuilder,多线程环境下推荐使用 StringBuffer。

 

13、String str="i"与 String str=new String(“i”)一样吗?

不一样,因为内存的分配方式不一样。String str="i"的方式,Java 虚拟机会将其分配到常量池中;而

String str=new String(“i”) 则会被分到堆内存中

 

14、接口可以有实现方法吗

   可以从1.8以后

 

15、ArrayList 和 LinkedList 的区别是什么? 

数据结构实现:ArrayList 是动态数组的数据结构实现,而 LinkedList 是双向链表的数据结构实现。

随机访问效率:ArrayList 比 LinkedList 在随机访问的时候效率要高,因为 LinkedList 是线性的数据

存储方式,所以需要移动指针从前往后依次查找。

增加和删除效率:在非首尾的增加和删除操作,LinkedList 要比 ArrayList 效率要高,因为 ArrayList

增删操作要影响数组内的其他数据的下标。

综合来说,在需要频繁读取集合中的元素时,更推荐使用 ArrayList,而在插入和删除操作较多时,更推

荐使用 LinkedList。

 

16、怎么确保一个集合不能被修改?

Collections. unmodifiableCollection(Collection c)

Map<String, Object>unmodifiableMap = Collections.unmodifiableMap(map);

17、如何实现跨域?实现跨域有以下几种方案:

服务器端运行跨域 设置 CORS 等于 *;

在单个接口使用注解 @CrossOrigin 运行跨域

 

多线程

  1、线程和进程的区别是什么?

进程和线程的主要差别在于它们是不同的操作系统资源管理方式。进程有独立的地

址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一

个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的

地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程

序健壮,但在进程切换时,耗费资源较大,效率要差一些。但对于一些要求同时进

行并且又要共享某些变量的并发操作,只能用线程,不能用进程

2、Java 实现线程有哪几种方式?

1)继承 Thread 类实现多线程

2)实现 Runnable 接口方式实现多线程

3)使用 ExecutorService、Callable、Future 实现有返回结果的多线程、

3、启动线程方法 start()和 run()有什么区别?

只有调用了 start()方法,才会表现出多线程的特性,不同线程的 run()方法里面的代

码交替执行。如果只是调用 run()方法,那么代码还是同步执行的,必须等待一个

线程的 run()方法里面的代码全部执行完毕之后,另外一个线程才可以执行其 run()

方法里面的代码。

 

4、一个线程的生命周期有哪几种状态?它们之间如何流转的?

1、New(初始化状态)

new语句创建的线程处于新建状态,此时它和其他Java对象一样,仅仅在堆区中被分配了内存。如:Thread t = new MyThread();

2、Runnable(就绪状态)

当调用线程对象的start()方法,线程即进入就绪状态。处于就绪状态的线程,只是说明此线程已经做好了准备,Java虚拟机会为它创建方法调用栈和程序计数器。处于这个状态的线程位于可运行池中,等待获得CPU的使用权,并不是说执行了start()此线程立即就会执行。

3、Running(运行状态)

当就绪状态中的线程获得了CUP执行资源,执行run()中的代码,这样的线程我们称为运行状态的线程。

 

4、Blocked(阻塞状态)

处于运行中的线程,由于某种原因放弃对cpu的使用权,处于阻塞状态,直到其进入就绪状态,才有机会再次被cpu调用进入运行状态。

根据阻塞原因不同,阻塞分为三种:

等待阻塞:运行状态中的线程执行wait方法,进入等待队列,等待阻塞;Java虚拟机就会把线程放到这个对象的等待池中;

同步阻塞:线程获取同步锁失败(因为锁被其他线程占用),Java虚拟机就会把这个线程放到这个对象的锁池中;

其他阻塞:通过调用sleep方法或者join方法或者发出I/O请求时,线程会进入阻塞状态,当sleep()状态超时,或者join()等待线程终止或者超时,或者I/O处理完毕,线程重新转入就绪状态;

5、Terminated(终止状态)

正常结束,线程执行完

异常退出

异常退出,除了程序有问题导致的异常的退出,还可以使用共享变量的方式(定义个boolean标识等)退出,或者Interrupt中断线程,抛出异常,捕获异常break,跳出循环状态;

调用stop(),会造成死锁,线程不安全,不建议使用

 

5、线程中的 wait()和 sleep()方法有什么区别?

这个问题常问,sleep 方法和 wait 方法都可以用来放弃 CPU 一定的时间,不同点在

于如果线程持有某个对象的监视器,sleep 方法不会放弃这个对象的监视器,wait

方法会放弃这个对象的监视器

 

6、多线程同步有哪几种方法?

Synchronized 关键字,Lock 锁实现,分布式锁等

7、什么是死锁?如何避免死锁?

死锁就是两个线程相互等待对方释放对象锁。

8、线程怎样拿到返回结果?

实现Callable 接口。

9、violatile 关键字的作用?

Java中的volatile关键字主要用于确保多线程环境下的内存可见性和有序性,具体作用如下:

可见性: 当一个线程修改了被volatile修饰的变量值时,其他线程可以立即看到这个变量值的变化。这是因为volatile关键字会强制将当前线程对变量的修改操作立即刷新到主内存,并且任何线程在读取该变量之前都会从主内存中重新加载最新值,而不是使用线程缓存(工作内存)中的旧值。

禁止指令重排序: 编译器和CPU为了优化性能可能会进行指令重排序,但是在多线程环境下,这种重排序可能导致意料之外的结果。volatile关键字能够插入必要的内存屏障来保证对 volatile 变量的操作不会与其他普通变量的读写操作发生重排序,即确保程序执行的有序性。

原子性保障有限: volatile关键字虽然能确保单个读/写的原子性,但对于复合操作(如递增、递减等)并不提供原子性保证。若需要复合操作的原子性,应使用synchronized、AtomicInteger等工具。

10、怎么控制同一时间只有 3 个线程运行?

Semaphore。

 

11、线程池启动线程 submit()和 execute()  方法有什么不同?

execute 没有返回值,如果不需要知道线程的结果就使用 execute 方法,性能会好很

多。

submit 返回一个 Future 对象,如果想知道线程结果就使用 submit 提交,而且它能

在主线程中通过 Future 的 get 方法捕获线程中的异常

12、Synchronized 有哪几种用法?

锁类、锁方法、锁代码块。

13、怎么检测一个线程是否拥有锁?

java.lang.Thread#holdsLock 方法

14、sleep() 和 wait() 有什么区别?

类的不同:sleep() 来自 Thread,wait() 来自 Object。

释放锁:sleep() 不释放锁;wait() 释放锁。

用法不同:sleep() 时间到会自动恢复;wait() 可以使用 notify()/notifyAll()直接唤醒。

Wait不会自动唤醒

 

15、notify()和 notifyAll()有什么区别?

notifyAll()会唤醒所有的线程,notify()之后唤醒一个线程。notifyAll() 调用后,会将全部线程由等

待池移到锁池,然后参与锁的竞争,竞争成功则继续执行,如果不成功则留在锁池等待锁被释放后再次参

与竞争。而 notify()只会唤醒一个线程,具体唤醒哪一个线程由虚拟机控制

 

16、ThreadLocal 是什么?有哪些使用场景?

ThreadLocal 为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副

本,而不会影响其它线程所对应的副本

17、说一下类加载的执行过程?

类加载分为以下 5 个步骤:

加载:根据查找路径找到相应的 class 文件然后导入;

检查:检查加载的 class 文件的正确性;

准备:给类中的静态变量分配内存空间;

解析:虚拟机将常量池中的符号引用替换成直接引用的过程。符号引用就理解为一个标示,而在直接引用

直接指向内存中的地址;

初始化:对静态变量和静态代码块执行初始化工作

 

18、并行与并发区别

并发多个任务在同一个 CPU 核上,按细分的时间片轮流(交替)执行,从逻辑上来看那些任务是

同时执行。

并行单位时间内,多个处理器或多核处理器同时处理多个任务,是真正意义上的“同时进行”

 

19、什么是上下文切换?

多线程编程中一般线程的个数都大于 CPU 核心的个数,而一个 CPU 核心在任意时刻只能被一个线

程使用,为了让这些线程都能得到有效执行,CPU 采取的策略是为每个线程分配时间片并轮转的

形式。当一个线程的时间片用完的时候就会重新处于就绪状态让给其他线程使用,这个过程就属于

一次上下文切换。

20、如何在 Windows 和 Linux 上查找哪个线程cpu利用率最高?

任务管理器  top

21、 为什么我们调用 start() 方法时会执行 run() 方法,为什么我们不能直接调用

run() 方法?

new 一个 Thread,线程进入了新建状态。调用 start() 方法,会启动一个线程并使线程进入了就绪

状态,当分配到 时间片 后就可以开始运行了。 start() 会执行线程的相应准备工作,然后自动执行

run() 方法的内容,这是真正的多线程工作。

而直接执行 run() 方法,会把 run 方法当成一个 main 线程下的普通方法去执行,并不会在某个线

程中执行它,所以这并不是多线程工作。

调用 start 方法方可启动线程并使线程进入就绪状态,而 run 方法只是 thread 的一个普通方法

调用,还是在主线程里执行

22、 Java 中用到的线程调度算法是什么?

有两种调度模型:分时调度模型和抢占式调度模型。

分时调度模型是指让所有的线程轮流获得 cpu 的使用权,并且平均分配每个线程占用的 CPU

的时间片这个也比较好理解。

Java虚拟机采用抢占式调度模型,是指优先让可运行池中优先级高的线程占用CPU,如果可

运行池中的线程优先级相同,那么就随机选择一个线程,使其占用CPU。处于运行状态的线

程会一直运行,直至它不得不放弃 CPU。

23、如何停止一个正在运行的线程?

使用退出标志,使线程正常退出,也就是当run方法完成后线程终止。

使用stop方法强行终止,但是不推荐这个方法,因为stop和suspend及resume一样都是过期

作废的方法。

使用interrupt方法中断线程

Kafka

kafka ack三种应答机制 

Ack=0  =1  =all

kafka重复消费解决方案有哪些

 

使用消费者组  使用消费者偏移量  使用幂等性处理  使用消息去重技术  

1. kafka 可以脱离 zookeeper 单独使用吗?为什么?

kafka 不能脱离 zookeeper 单独使用,因为 kafka 使用 zookeeper 管理和协调 kafka 的节点服务器。

 

2. kafka 有几种数据保留的策略?  

kafka 有两种数据保存策略:按照过期时间保留和按照存储的消息大小保留。

 

3. kafka 同时设置了 7 天和 10G 清除数据,到第五天的时候消息达到了 10G,这个时候 kafka 将如

何处理?

这个时候 kafka 会执行数据清除工作,时间和大小不论那个满足条件,都会清空数据。

 

4. 什么情况会导致 kafka 运行变慢? 

cpu 性能瓶颈

磁盘读写瓶颈

网络瓶颈

 

5. 使用 kafka 集群需要注意什么?

集群的数量不是越多越好,最好不要超过 7 个,因为节点越多,消息复制需要的时间就越长,整个群组

的吞吐量就越低。

集群数量最好是单数,因为超过一半故障集群就不能用了,设置为单数容错率更高。

  1. 说一下堆栈的区别?

功能方面:堆是用来存放对象的,栈是用来执行程序的。

共享性:堆是线程共享的,栈是线程私有的。

空间大小:堆大小远远大于栈。

 

数据库 mysql

1.一张自增表里面总共有 7 条数据,删除了最后 2 条数据,重启 MySQL 数据库,又插入了一条数

据,此时 id 是几?

表类型如果是 MyISAM ,那 id 就是 8。

表类型如果是 InnoDB,那 id 就是 6。

InnoDB 表只会把自增主键的最大 id 记录在内存中,所以重启之后会导致最大 id 丢失。

 

2..MySQL 的内连接、左连接、右连接有什么区别?

内连接关键字:inner join;左连接:left join;右连接:right join。

内连接是把匹配的关联数据显示出来;左连接是左边的表全部显示出来,右边的表显示出符合条件的数

据;右连接正好相反。

 

3说一下乐观锁和悲观锁? 

乐观锁:每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在提交更新的时候会判断一下在

此期间别人有没有去更新这个数据。

悲观锁:每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个

数据就会阻止,直到这个锁被释放。

数据库的乐观锁需要自己实现,在表里面添加一个 version 字段,每次修改成功值加 1,这样每次修改

的时候先对比一下,自己拥有的 version 和数据库现在的 version 是否一致,如果不一致就不修改,这

样就实现了乐观锁。

 

4、如何做 MySQL 的性能优化?

为搜索字段创建索引。

避免使用 select *,列出需要查询的字段。

垂直分割分表。

选择正确的存储引擎。

 

 

6、唯一索引比普通索引快吗, 为什么

   唯一索引不一定比普通索引快, 还可能慢.

1. 查询时, 在未使用 limit 1 的情况下, 在匹配到一条数据后, 唯一索引即返回, 普通索引会继续匹配

下一条数据, 发现不匹配后返回. 如此看来唯一索引少了一次匹配, 但实际上这个消耗微乎其微.

2. 更新时, 这个情况就比较复杂了. 普通索引将记录放到 change buffer 中语句就执行完毕了. 而对

唯一索引而言, 它必须要校验唯一性, 因此, 必须将数据页读入内存确定没有冲突, 然后才能继续操

. 对于写多读少的情况, 普通索引利用 change buffer 有效减少了对磁盘的访问次数, 因此普通

索引性能要高于唯一索引.

 

8、一千万条数据的表, 如何分页查询

 数据量过大的情况下, limit offset 分页会由于扫描数据太多而越往后查询越慢. 可以配合当前页最后

一条ID进行查询, SELECT * FROM T WHERE id > #{ID} LIMIT #{LIMIT} . 当然, 这种情况下ID必须

是有序的, 这也是有序ID的好处之

 

9、BLOB 和TEXT 有什么区别?

BLOB 是一个二进制对象, 可以容纳可变数量的数据。TEXT 是一个不区分大小写的 BLOB。

BLOB 和 TEXT 类型之间的唯一区别在于对 BLOB 值进行排序和比较时区分大小写, 对 TEXT 值不区分

大小写

 

10、MySQL的delete与truncate区别?

回答:delete语句执行删除的过程是每次从表中删除一行,并且同时将该行的删除操作作为事务记录在日志中保存以便进行回滚操作,不清空AUTO_INCREMENT记录数;

truncate则直接将表删除并重新建表,不会把单独的删除操作记录记入日志保存,删除行是不能恢复的,AUTO_INCREMENT将置为0,效率比delete高。

 

11、Oracle是怎么样分页的?

回答:Oracle中使用rownum来进行分页,这个是效率最好的分页方法,hibernate也是使用rownum来进行Oracle分页的;

select * from

select round r,a from tabName where round <= 20)

where r > 10

 

12、说说Oracle中经常使用到得函数?

回答:Length长度 、lower 小写、upper 大写、to_date 转化日期、to_char 转化字符,Ltrim 去左边空格、substr 取字符串、add_month 增加或者减掉月份、to_number 转变为数字

 

13、数据库语句优化有哪些?

1、对查询进行优化,应尽量避免全表扫描,首先应考虑在where 及 order by 涉及的列上建立索引。

2、应尽量避免在where 字句中对字段进行null 值判断,否则将导致引擎放弃使用索引二进行全表扫描。

3、应尽量避免在where 字句中使用or 来连接条件,否则将导致引擎放弃使用索引二进行全表扫描。

4、应尽量避免在where字句中使用!=或<>操作符,否则引擎将放弃使用索引二进行全表扫描。

5、in 和 not in 也要慎用,否则会导致全表扫描。

6、索引并不是越多越好,索引固然可以提高相应的select 的效率,但同时也降低了 insert 及 update 的效率,因为insert 或update时有可能会重建索引,所以怎样建索引需要慎重考虑,视具体情况而定。一个表的索引数最好不要超过6个,若太多则应考虑一些不常用到的列上建的索引是否有必要。

7、查询结果不要用 * 来查询所有字段,要明确指明结果字段。

8、根据查询条件,简历索引,如果查询条件不止一个时,使用组合索引。

9、在查询条件表达式的左侧尽量不要使用函数,否则索引失效。

10、如果有like话,尽量避免%xxx%两侧都有%的条件,单侧%可以使用索引,多侧不可以。

 

Redis

1一个字符串类型的值能存储最大容量是多少?  512m

2、Redis 为什么是单线程的?

因为 cpu 不是 Redis 的瓶颈,Redis 的瓶颈最有可能是机器内存或者网络带宽。既然单线程容易实现,

而且 cpu 又不会成为瓶颈,那就顺理成章地采用单线程的方案了

 

3、Redis 支持的数据类型string(字符串)、list(列表)、hash(字典)、set(集合)、zset(有序 集合)

 

4、Redis 的持久化机制是什么?各自的优缺点?

Redis 提供两种持久化机制 RDB 和 AOF 机制:

1、RDBRedis DataBase》持久化方式: 是指用数据集快照的方式半持久化模式) 记录 redis 数据库的所

有键值对,在某个时间点将数据写入一个临时文件, 持久化结束后, 用这个临时文件替换上次持久化的

文件, 达到数据恢复。

优点:

1、只有一个文件 dump.rdb, 方便持久化。

2、容灾性好, 一个文件可以保存到安全的磁盘。

3、性能最大化, fork 子进程来完成写操作, 让主进程继续处理命令, 所以是 IO 最大化。使用单独子

进程来进行持久化,主进程不会进行任何 IO 操作,保证了 redis 的高性能) 4.相对于数据集大时, 比

AOF 的启动效率更高。

缺点:

1、数据安全性低。RDB 是间隔一段时间进行持久化,如果持久化之间 redis 发生故障, 会发生数据丢

失。所以这种方式更适合数据要求不严谨的时候)

 

 

2、AOFAppend-only file》持久化方式: 是指所有的命令行记录以 redis 命令请求协议的格式完全持久

化存储)保存为 aof 文件。

优点:

1、数据安全, aof 持久化可以配置 appendfsync 属性, 有 always, 每进行一次命令操作就记录到

aof 文件中一次。

2、通过 append 模式写文件, 即使中途服务器宕机, 可以通过 redis-check-aof 工具解决数据一致性

问题。

3、AOF 机制的 rewrite 模式。AOF 文件没被 rewrite 之前( 文件过大时会对命令进行合并重写), 可

以删除其中的某些命令( 比如误操作的 flushall))

缺点:

1、AOF 文件比 RDB 文件大, 且恢复速度慢。

2、数据集大的时候, 比 rdb 启动效率低

 

5、redis 过期键的删除策略

  1 redis 过期键的删除策略、定时删除:在设置键的过期时间的同时,创建一个定时器 timer). 让定时器在键的过期时间来临时,

立即执行对键的删除操作。

2、惰性删除:放任键过期不管,但是每次从键空间中获取键时,都检查取得的键是 否过期, 如果过期

的话, 就删除该键;如果没有过期, 就返回该键。

3、定期删除:每隔一段时间程序就对数据库进行一次检查,删除里面的过期键。至 于要删除多少过期

键, 以及要检查多少个数据库, 则由算法决定。

 

6、Redis 的同步机制了解么?

答:Redis 可以使用主从同步,从从同步。第一次同步时,主节点做一次 bgsave, 并同时将后续修改

操作记录到内存 buffer, 待完成后将 rdb 文件全量同步到复制节点, 复制节点接受完成后将 rdb 镜像

加载到内存。加载完成后, 再通知主节点将期间修改的操作记录同步到复制节点进行重放就完成了同步

过程。

 

Mybatis

1、通常一个 Xml 映射文件,都会写一个 Dao 接口与之对应, 请问,这个 Dao 接口的工作原理是什么?Dao 接口里的方法, 参数不同时,方法能重载吗?

Dao 接口,就是人们常说的 Mapper 接口,接口的全限名,就是映射文件中的 namespace的值,接口的方法名,就是映射文件中 MappedStatement 的 id 值,接口方法内的参数,就是传递给 sql 的参数。Mapper 接口是没有实现类的,当调用接口方法时,接口全限名+方法名拼接字符串作为 key 值,可唯一定位一个 MappedStatement,举例:

com.mybatis3.mappers.StudentDao.findStudentById,可以唯一找到 namespace 为

com.mybatis3.mappers.StudentDao 下面 id = findStudentById 的

MappedStatement。在 Mybatis 中,每一个<select>、<insert>、<update>、<delete>

标签,都会被解析为一个 MappedStatement 对象。

 

Dao 接口里的方法,是不能重载的,因为是全限名+方法名的保存和寻找策略。

Dao 接口的工作原理是 JDK 动态代理,Mybatis 运行时会使用 JDK 动态代理为 Dao接 口 生 成 代 理 proxy 对 象 , 代 理 对 象 proxy 会 拦 截 接 口 方 法 , 转 而 执 行MappedStatement 所代表的 sql,然后将 sql 执行结果返回。

 

2、Xml 映射文件中,除了常见的 select|insert|update|delete 标签之外,还有哪些标签?

sql 的 9 个 标 签 ,

trim|where|set|foreach|if|choose|when|otherwise|bind 等 , 其 中 为 sql 片

段标签,通过标签引入 sql 片段,为不支持自增的主键生成策略标签

 

3、简述 Mybatis 的 Xml 映射文件和 Mybatis 内部数据结构之间的映射关系?

Mybatis 将所有 Xml 配置信息都封装到 All-In-One 重量级对象 Configuration 内部。在 Xml 映射文件中,<parameterMap>标签会被解析为 ParameterMap 对象,其每个子元素会被解析为 ParameterMapping 对象。<resultMap>标签会被解析为ResultMap 对象,其每个子元素会被解析为 ResultMapping 对象。每一个<select>、<insert>、<update>、<delete>标签均会被解析为 MappedStatement 对象,标签

内的 sql 会被解析为 BoundSql 对象。

 

4、Mybatis优缺点

优点

与传统的数据库访问技术相比,ORM有以下优点:

基于SQL语句编程,相当灵活,不会对应用程序或者数据库的现有设计造成任何影响,SQL写在

XML里,解除sql与程序代码的耦合,便于统一管理;提供XML标签,支持编写动态SQL语句,并

可重用  ,与JDBC相比,减少了50%以上的代码量,消除了JDBC大量冗余的代码,不需要手动开关连接

很好的与各种数据库兼容(因为MyBatis使用JDBC来连接数据库,所以只要JDBC支持的数据库

MyBatis都支持)

提供映射标签,支持对象与数据库的ORM字段关系映射;提供对象关系映射标签,支持对象关系组件维护,能够与Spring很好的集成

缺点

SQL语句的编写工作量较大,尤其当字段多、关联表多时,对开发人员编写SQL语句的功底有一定要求

SQL语句依赖于数据库,导致数据库移植性差,不能随意更换数据库

 

5、mapper传递参数的几种方式

方法1:顺序传参法

方法2:@Param注解传参法

方法3:Map传参法

方法4:Java Bean传参法

 

6、Mybatis如何执行批量操作,(批量操作方式有那几种)  

使用foreach标签

使用ExecutorType.BATCH

 

7、当实体类中的属性名和表中的字段名不一样 ,怎么办

  1种: 通过在查询的SQL语句中定义字段名的别名,让字段名的别名和实体类的属性名一致

2种: 通过 <resultMap> 来映射字段名和实体类属性名的一一对应的关系

 

 

 

8、Mybatis的Xml映射文件中,不同的Xml映射文件,id是否可以 重复?

  不同的Xml映射文件,如果配置了namespace,那么id可以重复;如果没有配置namespace,那么id不能重复;毕竟namespace不是必须的,只是最佳实践而已。

原因就是namespace+id是作为Map<String, MappedStatement>的key使用的,如果没有namespace,就剩下id,那么,id重复会导致数据互相覆盖。有了namespace,自然id就可以重复,namespace不同,namespace+id自然也就不同。

 

9、如果在xml中实现 if else或者switch 应该用什么标签

10、mybatis中foreach标签属性主要有哪些。都有什么作用

 

 

Springcloud

  1. spring cloud 的核心组件有哪些?

Eureka:服务注册于发现。

Feign:基于动态代理机制,根据注解和选择的机器,拼接请求 url 地址,发起请求。

Ribbon:实现负载均衡,从一个服务的多台机器中选择一台。

Hystrix:提供线程池,不同的服务走不同的线程池,实现了不同服务调用的隔离,避免了服务雪崩的问题。

Zuul:网关管理,由 Zuul 网关转发请求给对应的服务。

2、SpringCloud的优缺点

优点:

1.耦合度比较低。不会影响其他模块的开发。

2.减轻团队的成本,可以并行开发,不用关注其他人怎么开发,先关注自己的开发。

3.配置比较简单,基本用注解就能实现,不用使用过多的配置文件。

4.微服务跨平台的,可以用任何一种语言开发。

5.每个微服务可以有自己的独立的数据库也有用公共的数据库。

6.直接写后端的代码,不用关注前端怎么开发,直接写自己的后端代码即可,然后暴露接口,通过组件进行

服务通信。

缺点:

1.部署比较麻烦,给运维工程师带来一定的麻烦。

2.针对数据的管理比麻烦,因为微服务可以每个微服务使用一个数据库。

3.系统集成测试比较麻烦

 

3、什么是服务熔断?什么是服务降级?

在复杂的分布式系统中,微服务之间的相互呼叫可能会导致服务堵塞的各种原因。在高并发场景下,服务堵塞意味着线程堵塞,导致当前线程不可用,服务器线程全部堵塞,导致服务器崩溃。

由于服务之间的呼叫关系是同步的,它将导致整个微服务系统的服务雪崩。为了解决微服务的调用响应时间过长或不可用,占用越来越多的系统资源,导致雪崩效应,需要进行服务熔断和服务降级。

 

所谓服务熔断,是指某个服务故障或异常在一起,类似于显示世界“保险丝”当异常情况被触发时,整个服务将被直接熔断,而不是等到服务加班。

 

服务熔断相当于我们电闸的保险丝,一旦发生服务雪崩,整个服务将被熔断。通过维护自己的线程池,当线程达到阈值时,将启动服务降级。如果其他请求继续访问,则直接返回fallback的默认值。

 

4、SpringBoot和SpringCloud有什么联系和区别?

      SpringBoot是Spring推出的基于Maven的解决方案,用于解决传统框架配置文件的冗余和复杂的装配组件,旨在快速构建单个微服务;SpringCloud专注于解决各微服务、服务间通信、熔断、负载平衡等之间的协调配置问题。

 

不同的技术维度,而Spring Cloud依赖于Spring Boot,Spring Boot不依赖Spring Cloud,甚至可以和Dubbo优秀的综合开发。

 

 SpringBoot 是 Spring 的⼀套快速配置脚⼿架,可以基于SpringBoot 快速开发单个微服务,Spring Cloud是⼀个基于SpringBoot实现的云应⽤开发⼯具;

SpringBoot专注于快速、⽅便集成的单个微服务个体,Spring Cloud关注全局的服务治理框架;

 SpringBoot使⽤了默认⼤于配置的理念,很多集成⽅案已经帮你选择好了,能不配置就不配置;

 Spring Cloud很⼤的⼀部分是基于SpringBoot来实现,可以不基于SpringBoot吗?不可以。

 

5、网关的作用是什么

统一管理微服务请求,权限控制、负载均衡、路由转发、监控、安全控制黑名单和白名单等

 

6、Ribbon和Feign调用服务的区别

1、 调用方式同:Ribbon需要我们自己构建Http请求,模拟Http请求然后通过RestTemplate发给其他服务,步骤相当繁琐

2、 而Feign则是在Ribbon的基础上进行了一次改进,采用接口的形式,将我们需要调用的服务方法定义成抽象方法保存在本地就可以了,

不需要自己构建Http请求了,直接调用接口就行了,不过要注意,调用方法要和本地抽象方法的签名完全一致。

 

7、SpringBoot的自动配置原理是什么

主要是Spring Boot的启动类上的核心注解SpringBootApplication注解主配置类,有了这个主配置

类启动时就会为SpringBoot开启一个@EnableAutoConfiguration注解自动配置功能。

有了这个EnableAutoConfiguration的话就会:

1. 从配置文件META_INF/Spring.factories加载可能用到的自动配置类

2. 去重,并将exclude和excludeName属性携带的类排除

3. 过滤,将满足条件(@Conditional)的自动配置类返回

 

8、 Spring Boot 是否可以使用 XML 配置 ?

Spring Boot 推荐使用 Java 配置而非 XML 配置,但是 Spring Boot 中也可以使用 XML 配置,通

@ImportResource 注解可以引入一个 XML 配置。

 

9、如何使用 Spring Boot 实现全局异常处理?

Spring 提供了一种使用 ControllerAdvice 处理异常的非常有用的方法。 我们通过实现一个

ControlerAdvice 类,来处理控制器类抛出的所有异常

 

10、网关与过滤器有什么区别

网关是对所有服务的请求进行分析过滤,过滤器是对单个服务而言。

 

11、常用网关框架有那些?

Nginx、Zuul、Gateway

 

12、@Resource和@Autowired 两者都是做bean的注入时使用,其实@Resource并不是Spring的注解,它的包是java.annotation.Resource,需要导入,但是Spring支持该注解的注入。@Autowired为Spring提供的注解,需要导入包org.springframework.beans.factory.annotation.Autowired;只按照byType注入。

 

13、Spring依赖注入有哪些?各有什么优缺点?Spring依赖注入有哪些?各有什么优缺点?

1属性注入

优点

属性注入的优点就是实现简单,使用简单。

缺点

不能注入不可变对象,也就是不能注入final修饰的对象

兼容性不好,只适合IoC容器

由于写法简单,也更容易违背单一设计原则

2 Setter注入

优点

相比于属性注入,Setter注入更符合单一设计原则,因为每次都只传递了一个对象。

缺点

和属性注入一下,Setter注入不能注入不可变对象

注入的对象可能被修改(因为可能有其他人调用这个set方法)

3 构造方法注入

优点

与前两者方式不同,构造方法注入可以注入不可变的对象。这是因为在JavaSE中,创建final修饰的对象时,要么直接赋值,要么在构造方法中赋值,必须满足其一。

由于构造方法只执行了一次,注入的对象不会被改变。

可以保证注入对象完全被初始化。

兼容性更好

缺点

如果有多个注入会显得比较臃肿,但是出现这种情况我们应该考虑一下当前类是否符合程序的单一设计原则。

 

14、Mybatis和hibernate的区别?

 

 

15、SpringMVC的底层是基于什么实现的?

Spring MVC是基于servlet功能实现的,通过实现Servlet接口的DispatcherServlet来封装其核心功能实现,过将请求分派给处理程序,同时带有可配置的处理程序映射、视图解析、本地语言、主题解析以及上传下载文件支持

 

 

13、说下你在项目开发中碰到的坑,以及怎么解决的

 

posted @ 2025-04-29 09:27  七彩鱼丸  阅读(21)  评论(0)    收藏  举报