一、Java 基础
1.JDK 和 JRE 有什么区别?
-
JDK:java开发工具包,提供了java的开发环境和运行环境
-
JRE:java运行环境,为java运行提供了环境
JDK是包含JRE的,同时还包含了编译java源码的编译器javac,还包含了很多java程序调试和分析的工具。如果只是运行java安装JRE就可以了,如果是要编写java那就要安装JDK
2. == 和 equals 的区别是什么?
==
基本类型:比较的是值是否相同
引用类型:比较的是引用是否相同(引用保存的内容)
equals
本质上还是==,只不过string和integer等类重写了equals方法,把它们变成了值比较
==对于基本数据类型是值比较,对于引用数据类型是引用比较;而equals默认情况是引用比较(object类中的equals方法比较的是引用),但是如果重写了equals的类则比较的是值
3.两个对象的 hashCode()相同,则 equals()也一定为 true,对吗?
hashcode()相同的两个对象的equals()不一定相同,但equals()相同的两个对象他们的hashcode()一定相同
错,在散列表中,hashcode()相等表示两个键值对的哈希值相等,而哈希值相等不能得到键值对相等
4.final 在 java 中有什么作用?
-
final修饰的类不能被继承
-
final修饰的方法不能被重写
-
final修饰的变量不能被修改(被final修饰的变量叫常量,必须初始化)
- 引用类型变量其引用指向的地址不可发生改变,但指向地址内的数据可以改变
5.java 中的 Math.round(-1.5) 等于多少?
等于-1,在数轴上取值,向右取整,整数采用四舍五入,负数直接舍弃小数点后的数值
6.String 属于基础的数据类型吗?
不属于,它是一个引用类型
7.java 中操作字符串都有哪些类?它们之间有什么区别?
-
String
声明的对象是不可变的,每次操作都会产生新的string对象,将引用指向新的strin对象
-
StringBuffer
在原有的对象上进行操纵,线程安全,多线程环境下使用
-
StringBuilder
在原有的对象上进行操作,非线程安全,性能要高于StringBuffer,单线程环境下使用
8.String str="i"与 String str=new String(“i”)一样吗?
不一样,两者分配内存的方式不一样。
前者str保存的是i字符串保存在字符串常量池中的地址,而后者str保存的是string对象在堆内存中的地址,但是堆内存中的string对象保存的是i字符串在字符串常量池中的地址。
9.如何将字符串反转?
使用StringBuffer或StringBuilder的reverse()方法
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append("asd123");
StringBuffer reverse = stringBuffer.reverse();
System.out.println(reverse);
10.String 类的常用方法都有那些?
indexOf(); //返回指定字符的下表
charAt(); //返回指定下表的字符
replace(); //字符串替换
trim(); //去除两端的空白字符
split(); //分割字符串,返回一个分割后的字符串数组
getBytes(); //返回字符串的byte类型数组
length(); //返回字符串的长度
toLowerCase(); //将字符串转成小写字母
toUpperCase(); //将字符串转成大写字母
subString(); //截取字符串
equals(); //字符串比较
11.抽象类必须要有抽象方法吗?
不是,抽象类不一定非要有抽象方法,抽象类还可以有具体方法,
12.普通类和抽象类有哪些区别?
-
抽象类是多个普通类抽象出来的类,具有这些类中共有的属性和行为。
-
抽象类可以包含抽象方法,普通类不能包含抽象方法。
-
抽象类不可以实列化,普通类可以被实列化。
13.抽象类能使用 final 修饰吗?
不能,如果使用了final关键字进行修饰的话,抽象类就无法被继承,一个不能被继承的抽象类是没有存在的意义的,无法被继承就无法被实列化。
14.接口和抽象类有什么区别?
接口中只有抽象方法,而抽象类可以有具体的方法
接口中全部是以public关键字进行修饰的,抽象类可以使用四种修饰方法的关键字进行修饰
15.java 中 IO 流分为几种?
按功能分:输入流和输出流
按类型分:字节流和字符流
16.BIO、NIO、AIO 有什么区别?
- BIO:Block IO 同步阻塞式 IO,就是我们平常使用的传统 IO,它的特点是模式简单使用方便,并发处理能力低。
- NIO:New IO 同步非阻塞 IO,是传统 IO 的升级,客户端和服务器端通过 Channel(通道)通讯,实现了多路复用。
- AIO:Asynchronous IO 是 NIO 的升级,也叫 NIO2,实现了异步非堵塞 IO ,异步 IO 的操作基于事件和回调机制。
17.Files的常用方法都有哪些?
Files.exists(); //检测文件中路径是否存在
Files.createFile(); //创建文件
Files.createDirectory(); //创建文件夹
Files.delete(); //删除一个文件或目录
Files.copy(); //复制文件
Files.move(); //移动文件
Files.size(); //查看文件个数
Files.read(); //读取文件
Files.write(); //写入文件
二、容器
18.java 容器都有哪些?
Collection接口下的List,Set,Queue还有map
19.Collection 和 Collections 有什么区别?
- collection是一个集合接口,提供了对集合对象进行基本操作的通用接口方法。collection接口在Java类库中有很多具体的实现。
- collections则是集合类的一个工具类,其中提供一系列静态方法用于对集合中元素进行排序、搜索以及线程安全等各种操作。
20.List、Set、Map 之间的区别是什么?
- list有序可重复
- set无序不可重复
- map键无序不可重复
21.HashMap 和 Hashtable 有什么区别?
- HashMap:非线程安全,键值可以为null,初始容量为16,扩容倍数是原容量的2倍
- HashTable :线程安全,键值都不能为null,初始容量为11,扩容=》原容量*2+1
22.如何决定使用 HashMap 还是 TreeMap?
对于在Map中插入、删除和定位元素这类操作,HashMap是最好的选择
对于需要一个有序的key集合进行遍历,TreeMap更好
- HashMap增删操作对集合没有影响很小,而TreeMap进行这类操作后需要重新给键排序
- 需要遍历集合时二分查找很合适,但前提需要遍历一个已排序的集合
23.说一下 HashMap 的实现原理?
HashMap是基于哈希表的Map接口非同步实现,此实现提供所有可选的映射操作,允许null值与null键。不保证映射的顺序,特别是不保证该顺序恒久不变。
HashMap是一个“链表散列”的数据结构,即数组和链表的结合体。
向HashMap中存入元素时,首先根据key的HashCode重新计算hash值,根据hash值得到这个元素在数组中的下标,若下标位置已经存放了其他元素,那么在这个位置上的元素将以链表的形式存放,先加入的放在链尾,新加入的放在链头,若数组中这个位置没有元素,那就将元素放到数组这个位置。
jdk1.8之后对HashMap的实现做了优化,当链表中的节点数据超过八个之后,该链表会转为红黑树来提高查询效率,时间复杂度由原来的O(n)到O(logn)
24.说一下 HashSet 的实现原理?
- HashSet底层是由HashMap实现的
- HashSet的值存放在HashMap的key部分
- HashMap的value统一为PRESENT
25.ArrayList 和 LinkedList 的区别是什么?
-
ArrayList
-
对数据的查询效率高
-
底层是数组
-
由于底层是数组,所以每个数组单元大小一致,知道首地址的大小和下标以及存储单元大小可以快速计算出指定下标元素的地址,对于查询特定位置的元素效率很高
-
增删操作比较麻烦,但是对于尾部的元素的增删执行效率还是很高的
-
适用于经常查询的List集合
-
-
LinkedList
-
对数据的增删操作效率高
-
底层是双向链表
-
适用于经常进行增删操作的List集合
-
26.如何实现数组和 List 之间的转换?
- List转换成数组:调用ArrayList的toArray方法
- 数组转换成List:调用Arrays的asList方法
27.ArrayList 和 Vector 的区别是什么?
- Vector是同步的,ArrayList不是
- ArrayList比 Vector快,它因为有同步,不会过载
- ArrayList更加通用,因为我们可以使用Collections工具类轻易地获取同步列表和只读列表
28.Array 和 ArrayList 有何区别?
- Array可以容纳对象和基本类型,而ArrayList只能容纳对象
- Array是指定大小,ArrayList是固定大小
- Array没有ArrayList提供的功能多,比如addAll、removeAll和iterator等
29.在 Queue 中 poll()和 remove()有什么区别?
都是从队列中取出一个元素,poll()在获取元素失败的时候回返回null,但是remove()失败时会抛出异常
30.哪些集合类是线程安全的?
- vector:就比arraylist多了个同步化机制,因为效率较低,现在已经不太建议使用。
- statck:堆栈类,先进后出。
- hashtable:就比hashmap多了个线程安全。
- enumeration:枚举,相当于迭代器。
31.迭代器 Iterator 是什么?
迭代器是一种设计模式,它是一个对象,可以遍历并选择序列中的对象,而开发人员不需要了解该序列的底层结构。迭代器通常被称为“轻量级”对象,因为创建它的代价小。
32.Iterator 怎么使用?有什么特点?
java中的iterator功能比较简单,只能单向移动
- 使用iterator()方法要求容器返回一个iterator。
- 迭代器一开始指向的是第一个元素前的一个位置
- 每当调用一次next()方法,迭代器就会向下移动一个位置,并返回该位置的元素
- hasNext()方法判断下一个位置是否还有元素,如果没有返回true,但迭代器不会向下移动
- remove()方法删除的是当前位置的元素,所以不能在使用next()方法之前删除,比如刚开始的迭代器是指向的是第一个元素之前的位置,该位置为空,没有元素,不能进行删除操作
- 在迭代元素过程中,要使用迭代器的remove()方法删除元素
- 集合发生改变,迭代器必须重新获取
33.Iterator 和 ListIterator 有什么区别?
- Iterator可用来遍历Set和List集合,但是ListIterator只能用来遍历List。
- Iterator对集合只能是前向遍历,ListIterator既可以前向也可以后向。
- ListIterator实现了Iterator接口,并包含其他的功能,比如:增加元素,替换元素,获取前一个和后一个元素的索引,等等。
34.怎么确保一个集合不能被修改?
-
使用Collections.unmodifiableList() 方法可以让List集合不能被修改
-
使用Collections.unmodifiableMap()方法可以让Map集合不能被修改
三、多线程
35.并行和并发有什么区别?
- 并行是指两个或者多个事件在同一时刻发生;而并发是指两个或多个事件在同一时间间隔发生。
- 并行是在不同实体上的多个事件,并发是在同一实体上的多个事件。
36.线程和进程的区别?
- 线程:
- 进程:
进程是程序运行和资源分配的基本单位,一个程序至少有一个进程,一个进程至少有一个线程。进程在执行过程中拥有独立的内存单元,而多个线程共享内存资源,减少切换次数,从而效率更高。线程是进程的一个实体,是cpu调度和分派的基本单位,是比程序更小的能独立运行的基本单位。同一进程中的多个线程之间可以并发执行。
37.守护线程是什么?
是个服务线程,准确地来说就是服务其他的线程
38.创建线程有哪几种方式?
39.说一下 runnable 和 callable 有什么区别?
40.线程有哪些状态?
41.sleep() 和 wait() 有什么区别?
sleep():方法是线程类(Thread)的静态方法,让调用线程进入睡眠状态,让出执行机会给其他线程,等到休眠时间结束后,线程进入就绪状态和其他线程一起竞争cpu的执行时间。
因为sleep() 是static静态的方法,他不能改变对象的机锁,当一个synchronized块中调用了sleep() 方法,线程虽然进入休眠,但是对象的机锁没有被释放,其他线程依然无法访问这个对象。
wait():wait()是Object类的方法,当一个线程执行到wait方法时,它就进入到一个和该对象相关的等待池,同时释放对象的机锁,使得其他线程能够访问,可以通过notify,notifyAll方法来唤醒等待的线程
42.notify()和 notifyAll()有什么区别?
- notify:随机唤醒一个 wait 线程
- notifyAll:唤醒所有 wait 线程
43.线程的 run()和 start()有什么区别?
每个线程都是通过某个特定Thread对象所对应的方法run()来完成其操作的,方法run()称为线程体。通过调用Thread类的start()方法来启动一个线程。
44.创建线程池有哪几种方式?
45.线程池都有哪些状态?
Running、ShutDown、Stop、Tidying、Terminated。
46.线程池中 submit()和 execute()方法有什么区别?
47.在 java 程序中怎么保证多线程的运行安全?
线程安全在三个方面体现:
- 原子性:提供互斥访问,同一时刻只能有一个线程对数据进行操作,(atomic,synchronized);
- 可见性:一个线程对主内存的修改可以及时地被其他线程看到,(synchronized,volatile);
- 有序性:一个线程观察其他线程中的指令执行顺序,由于指令重排序,该观察结果一般杂乱无序,(happens-before原则)。
48.多线程锁的升级原理是什么?
49.什么是死锁?
死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。
50.怎么防止死锁?
死锁的四个必要条件:
- 互斥条件:进程对所分配到的资源不允许其他进程进行访问,若其他进程访问该资源,只能等待,直至占有该资源的进程使用完成后释放该资源
- 请求和保持条件:进程获得一定的资源之后,又对其他资源发出请求,但是该资源可能被其他进程占有,此事请求阻塞,但又对自己获得的资源保持不放
- 不可剥夺条件:是指进程已获得的资源,在未完成使用之前,不可被剥夺,只能在使用完后自己释放
- 环路等待条件:是指进程发生死锁后,若干进程之间形成一种头尾相接的循环等待资源关系
这四个条件是死锁的必要条件,只要系统发生死锁,这些条件必然成立,而只要上述条件之 一不满足,就不会发生死锁。
52.说一下 synchronized 底层实现原理?
synchronized可以保证方法或者代码块在运行时,同一时刻只有一个方法可以进入到临界区,同时它还可以保证共享变量的内存可见性。
Java中每一个对象都可以作为锁,这是synchronized实现同步的基础:
- 普通同步方法,锁是当前实例对象
- 静态同步方法,锁是当前类的class对象
- 同步方法块,锁是括号里面的对象
四、反射
57.什么是反射?
反射主要是指程序可以访问、检测和修改它本身状态或行为的一种能力
Java反射:
在Java运行时环境中,对于任意一个类,能否知道这个类有哪些属性和方法?对于任意一个对象,能否调用它的任意一个方法
Java反射机制主要提供了以下功能:
- 在运行时判断任意一个对象所属的类。
- 在运行时构造任意一个类的对象。
- 在运行时判断任意一个类所具有的成员变量和方法。
- 在运行时调用任意一个对象的方法。
58.什么是 java 序列化?什么情况下需要序列化?
简单说就是为了保存在内存中的各种对象的状态
什么情况下需要序列化:
a)当你想把的内存中的对象状态保存到一个文件中或者数据库中时候;
b)当你想用套接字在网络上传送对象的时候;
c)当你想通过RMI传输对象的时候;
五、对象拷贝
61.为什么要使用克隆?
62.如何实现对象克隆?
63.深拷贝和浅拷贝区别是什么?
- 浅拷贝只是复制了对象的引用地址,两个对象指向同一个内存地址,所以修改其中任意的值,另一个值都会随之变化,这就是浅拷贝
- 深拷贝是将对象及值复制过来,两个对象修改其中任意的值另一个值不会改变,这就是深拷贝
六、Java Web
64.jsp 和 servlet 有什么区别?
- jsp编译后就是servlet
- jsp擅长表现于页面显示,servlet更擅长于逻辑控制
65.jsp 有哪些内置对象?作用分别是什么?
JSP有9个内置对象:
- request:封装客户端的请求,其中包含来自GET或POST请求的参数;
- response:封装服务器对客户端的响应;
- pageContext:通过该对象可以获取其他对象;
- session:封装用户会话的对象;
- application:封装服务器运行环境的对象;
- out:输出服务器响应的输出流对象;
- config:Web应用的配置对象;
- page:JSP页面本身(相当于Java程序中的this);
- exception:封装页面抛出异常的对象。
66.说一下 jsp 的 4 种作用域?
- page代表与一个页面相关的对象和属性。
- request代表与Web客户机发出的一个请求相关的对象和属性。一个请求可能跨越多个页面,涉及多个Web组件;需要在页面显示的临时数据可以置于此作用域。
- session代表与某个用户与服务器建立的一次会话相关的对象和属性。跟某个用户相关的数据应该放在用户自己的session中。
- application代表与整个Web应用程序相关的对象和属性,它实质上是跨越整个Web应用程序,包括多个页面、请求和会话的一个全局作用域。
67.session 和 cookie 有什么区别?
68.说一下 session 的工作原理?
其实session是一个存在服务器上的类似于一个散列表格的文件。里面存有我们需要的信息,在我们需要用的时候可以从里面取出来。类似于一个大号的map吧,里面的键存储的是用户的sessionid,用户向服务器发送请求的时候会带上这个sessionid。这时就可以从中取出对应的值了。
69.如果客户端禁止 cookie 能实现 session 还能用吗?
70.spring mvc 和 struts 的区别是什么?
71.如何避免 sql 注入?
72.什么是 XSS 攻击,如何避免?
73.什么是 CSRF 攻击,如何避免?
八、网络
79.http 响应码 301 和 302 代表的是什么?有什么区别?
301,302 都是HTTP状态的编码,都代表着某个URL发生了转移。
- 301 redirect: 301 代表永久性转移(Permanently Moved)。
- 302 redirect: 302 代表暂时性转移(Temporarily Moved )。
80.forward 和 redirect 的区别?
81.简述 tcp 和 udp的区别?
- TCP面向连接(如打电话要先拨号建立连接);UDP是无连接的,即发送数据之前不需要建立连接。
- TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付。
- Tcp通过校验和,重传控制,序号标识,滑动窗口、确认应答实现可靠传输。如丢包时的重发控制,还可以对次序乱掉的分包进行顺序控制。
- UDP具有较好的实时性,工作效率比TCP高,适用于对高速传输和实时性有较高的通信或广播通信。
- 每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信。
- TCP对系统资源要求较多,UDP对系统资源要求较少。
82.tcp 为什么要三次握手,两次不行吗?为什么?
为了实现可靠数据传输, TCP 协议的通信双方, 都必须维护一个序列号, 以标识发送出去的数据包中, 哪些是已经被对方收到的。 三次握手的过程即是通信双方相互告知序列号起始值, 并确认对方已经收到了序列号起始值的必经步骤。
如果只是两次握手, 至多只有连接发起方的起始序列号能被确认, 另一方选择的序列号则得不到确认。
83.说一下 tcp 粘包是怎么产生的?
84.OSI 的七层模型都有哪些?
- 应用层:网络服务与最终用户的一个接口。
- 表示层:数据的表示、安全、压缩。
- 会话层:建立、管理、终止会话。
- 传输层:定义传输数据的协议端口号,以及流控和差错校验。
- 网络层:进行逻辑地址寻址,实现不同网络之间的路径选择。
- 数据链路层:建立逻辑连接、进行硬件地址寻址、差错校验等功能。
- 物理层:建立、维护、断开物理连接。
85.get 和 post 请求有哪些区别?
- GET在浏览器回退时是无害的,而POST会再次提交请求。
- GET产生的URL地址可以被Bookmark,而POST不可以。
- GET请求会被浏览器主动cache,而POST不会,除非手动设置。
- GET请求只能进行url编码,而POST支持多种编码方式。
- GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。
- GET请求在URL中传送的参数是有长度限制的,而POST么有。
- 对参数的数据类型,GET只接受ASCII字符,而POST没有限制。
- GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息。
- GET参数通过URL传递,POST放在Request body中。
十七、MySql
164.数据库的三范式是什么?
- 第一范式:强调的是列的原子性,即数据库表的每一列都是不可分割的原子数据项。
- 第二范式:要求实体的属性完全依赖于主关键字。所谓完全依赖是指不能存在仅依赖主关键字一部分的属性。
- 第三范式:任何非主属性不依赖于其它非主属性。
165.一张自增表里面总共有 7 条数据,删除了最后 2 条数据,重启 mysql 数据库,又插入了一条数据,此时 id 是几?
- 表类型如果是 MyISAM ,那 id 就是 8。
- 表类型如果是 InnoDB,那 id 就是 6。
InnoDB 表只会把自增主键的最大 id 记录在内存中,所以重启之后会导致最大 id 丢失。
166.如何获取当前数据库版本?
使用 select version() 获取当前 MySQL 数据库版本。
167.说一下 ACID 是什么?
- Atomicity(原子性):一个事务(transaction)中的所有操作,或者全部完成,或者全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被恢复(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。即,事务不可分割、不可约简。
- Consistency(一致性):在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设约束、触发器、级联回滚等。
- Isolation(隔离性):数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)。
- Durability(持久性):事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。
168.char 和 varchar 的区别是什么?
char(n) :固定长度类型,比如订阅 char(10),当你输入"abc"三个字符的时候,它们占的空间还是 10 个字节,其他 7 个是空字节。
chat 优点:效率高;缺点:占用空间;适用场景:存储密码的 md5 值,固定长度的,使用 char 非常合适。
varchar(n) :可变长度,存储的值是每个值占用的字节再加上一个用来记录其长度的字节的长度。
所以,从空间上考虑 varcahr 比较合适;从效率上考虑 char 比较合适,二者使用需要权衡。
169.float 和 double 的区别是什么?
- float 最多可以存储 8 位的十进制数,并在内存中占 4 字节。
- double 最可可以存储 16 位的十进制数,并在内存中占 8 字节。
170.mysql 的内连接、左连接、右连接有什么区别?
内连接关键字:inner join;左连接:left join;右连接:right join。
内连接是把匹配的关联数据显示出来;左连接是左边的表全部显示出来,右边的表显示出符合条件的数据;右连接正好相反。
171.mysql 索引是怎么实现的?
索引是满足某种特定查找算法的数据结构,而这些数据结构会以某种方式指向数据,从而实现高效查找数据。
具体来说 MySQL 中的索引,不同的数据引擎实现有所不同,但目前主流的数据库引擎的索引都是 B+ 树实现的,B+ 树的搜索效率,可以到达二分法的性能,找到数据区域之后就找到了完整的数据结构了,所有索引的性能也是更好的。
172.怎么验证 mysql 的索引是否满足需求?
使用 explain 查看 SQL 是如何执行查询语句的,从而分析你的索引是否满足需求。
explain 语法:explain select * from table where type=1。
173.说一下数据库的事务隔离?
174.说一下 mysql 常用的引擎?
InnoDB 引擎:InnoDB 引擎提供了对数据库 acid 事务的支持,并且还提供了行级锁和外键的约束,它的设计的目标就是处理大数据容量的数据库系统。MySQL 运行的时候,InnoDB 会在内存中建立缓冲池,用于缓冲数据和索引。但是该引擎是不支持全文搜索,同时启动也比较的慢,它是不会保存表的行数的,所以当进行 select count(*) from table 指令的时候,需要进行扫描全表。由于锁的粒度小,写操作是不会锁定全表的,所以在并发度较高的场景下使用会提升效率的。
MyIASM 引擎:MySQL 的默认引擎,但不提供事务的支持,也不支持行级锁和外键。因此当执行插入和更新语句时,即执行写操作的时候需要锁定这个表,所以会导致效率会降低。不过和 InnoDB 不同的是,MyIASM 引擎是保存了表的行数,于是当进行 select count(*) from table 语句时,可以直接的读取已经保存的值而不需要进行扫描全表。所以,如果表的读操作远远多于写操作时,并且不需要事务的支持的,可以将 MyIASM 作为数据库引擎的首选。
175.说一下 mysql 的行锁和表锁?
MyISAM 只支持表锁,InnoDB 支持表锁和行锁,默认为行锁。
- 表级锁:开销小,加锁快,不会出现死锁。锁定粒度大,发生锁冲突的概率最高,并发量最低。
- 行级锁:开销大,加锁慢,会出现死锁。锁力度小,发生锁冲突的概率小,并发度最高。
176.说一下乐观锁和悲观锁?
- 乐观锁:每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在提交更新的时候会判断一下在此期间别人有没有去更新这个数据。
- 悲观锁:每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻止,直到这个锁被释放。
数据库的乐观锁需要自己实现,在表里面添加一个 version 字段,每次修改成功值加 1,这样每次修改的时候先对比一下,自己拥有的 version 和数据库现在的 version 是否一致,如果不一致就不修改,这样就实现了乐观锁。
177.mysql 问题排查都有哪些手段?
- 使用 show processlist 命令查看当前所有连接信息。
- 使用 explain 命令查询 SQL 语句执行计划。
- 开启慢查询日志,查看慢查询的 SQL。
178.如何做 mysql 的性能优化?
- 为搜索字段创建索引。
- 避免使用 select *,列出需要查询的字段。
- 垂直分割分表。
- 选择正确的存储引擎。