本人小菜鸟一个,学的java后端,老家江西坐标上海,20届普本软件工程毕业生,种种原因导致21年1月底才开始找工作,基础学的一般,开个贴记录下面试遇到的问题,慢慢提升自己,大部分答案都是百度的

2021.1.29 收到一家创业外包offer 待遇福利不错(可能是大饼)
2021.2.2 过了两家小公司的面试
2021.2.3 过了一家科技公司的技术面和hr面,待遇谈完等offer中
2021.2.4 去了科技公司,offer已签,965,实习期三到六个月
2021.2.22 办理入职中,中午迎新吃了顿饭,原来公司是966,我之前听错了,顺便说句运维的只有兄弟真惨,上午入职,下午电脑到手就开干了
2021.3.4 原来只有运维的兄弟是966,java开发部门的是965。。。
总结
人生第一次找到工作,耗时一星期,boss投了147,拉钩没有统计不过估计差不多,总共5个offer,三家外包,一家定制网页,一家科技公司(我也不太懂公司的性质这些的)。先这样吧,技术一般就不挑剔了,先入行才是重点,看了下牛客上大厂的面经自己还是差很多,努力吧。

2022.9.8 三月份已经转行golang开发了,java开发太能卷了,天天搞到晚上八九点

目录

  • 自我介绍
  • java基础
    • 讲讲访问修饰符public、private、protect、default
    • 重写和重载的区别
    • jdk1.8新特性
    • =和equal的区别
    • hashcode()的作用
    • 重写hashcode()的原因
    • get和post的区别
    • wait()和notify()
    • 类和抽象类的区别
    • Java类加载机制
    • 简述下io流
    • 谈谈Java IO里面的常见类,字节流,字符流、接口、实现类、方法阻塞
    • Java类和对象的初始化顺序
    • Java中的泛型是什么 ? 使用泛型的好处是什么?
    • 简述TCP三次握手和四次挥手流程
    • String字符串反转顺序怎么做
    • stringbuffer和stringbuilder
    • cookie被禁止后怎样使用session的解决方案?
    • jvm调优会吗,讲讲
    • jvm内存模型
    • JVM里面哪些区域是线程安全
  • mysql
    • 你项目中的表结构设计是如何得(基本是个公司都会问)
    • 数据库内联和外联的区别(交集并集)
    • 简单的sql优化讲讲你知道的
    • 如何确定索引有没有被查询
    • mysql索引(普通索引,唯一索引,主键索引,组合索引,全文索引,组合索引)
    • MySQL索引存储结构和特点
    • 索引失效场景有哪些
  • spring
    • spring中bean的生命周期
    • 如何理解依赖注入?(ioc控制反转)
  • springmvc
    • 简述下springmvc原理
    • springmvc三层架构之间是怎么互相传递数据的
  • mybatis
  • springboot
  • juc
    • 创建线程的四种方法
    • 线程和进程的区别
    • 讲讲volitail(轻量)关键字
    • 如何保证多线程下 i++ 结果正确?
    • 谈谈JUC
  • redis
    • Redis 数据结构使用场景
  • 项目
    • xxxx
  • 其他
    • MQ怎么防止消息丢失
    • 单例设计模式
    • 简述下aop
    • 领域模型相关知识
    • 缓存算法(淘汰策略)
    • 既然你对spi有一定了解,那么dubbo的spi和jdk的spi有区别吗?有的话,究竟有什么区别?
    • 你说你看过Dubbo源码,那你简单说下,他在设计上有哪些细节让你觉得很巧妙?(区分度高)
    • 事务的四个特性
    • 并发下事务会产生的问题
    • 事务隔离级别
    • 事务的传播行为
  • 反问环节
    • 我今天面试的表现如何,有什么建议吗?
    • 公司现在主要的技术栈是什么?

自我介绍

面试官,您好!我叫xx。能熟练使用Springboot+vue2.0+elementui快速开发。我参与了一个分布式电子交易系统的开发,分布式服务架构,使用SpringBoot+Mybatis-Plus,完成了商品系统模块的分类维护,品牌 管理,模糊查询功能,用户可以通过拖动级联选择器的子节点到相应位置,来调整商品所属的三级分类,通过模糊查询搜索 分组添加修改来完成品牌管理维护上新,用对象存储OSS处理品牌logo,用SpringCloud Gateway统 一处理前端请求及跨域问题。生活中我是一个比较积极乐观的人,一般会通过健身的方式来放松。我非常想加入贵公司,我觉得贵公司的文化和技术氛围我都非常喜欢,期待能与你共事!

java基础

讲讲访问修饰符public、private、protect、default

public: Java语言中访问限制最宽的修饰符,一般称之为“公共的”。被其修饰的类、属性以及方法不
     仅可以跨类访问,而且允许跨包(package)访问。
private: Java语言中对访问权限限制的最窄的修饰符,一般称之为“私有的”。被其修饰的类、属性以
     及方法只能被该类的对象访问,其子类不能访问,更不能允许跨包访问。
protect: 介于public 和 private 之间的一种访问修饰符,一般称之为“保护形”。被其修饰的类、
     属性以及方法只能被类本身的方法及子类访问,即使子类在不同的包中也可以访问。
default:即不加任何访问修饰符,通常称为“默认访问模式“。该模式下,只允许在同一个包中进行访
     问。

重写和重载的区别

重载(Overload)是让类以统一的方式处理不同类型数据的一种手段,实质表现就是多个具有不同的参数个数或者类型的同名函数(返回值类型可随意,不能以返回类型作为重载函数的区分标准)同时存在于同一个类中,是一个类中多态性的一种表现(调用方法时通过传递不同参数个数和参数类型来决定具体使用哪个方法的多态性)。
重写(Override)是父类与子类之间的多态性,实质是对父类的函数进行重新定义,如果在子类中定义某方法与其父类有相同的名称和参数则该方法被重写,不过子类函数的访问修饰权限不能小于父类的;若子类中的方法与父类中的某一方法具有相同的方法名、返回类型和参数表,则新方法将覆盖原有的方法,如需父类中原有的方法则可使用 super 关键字。

jdk1.8新特性

Lambda表达式(箭头函数)
Stream API

=和equal的区别

==比较的是内存地址,而equal比较的是值

hashcode()的作用

hashCode() 方法用于返回字符串的哈希码。

重写hashcode()的原因

hashset在存储一个元素的时候会调用equals()和hashcode()进行判断,如果返回值不一致就会将数据存储在不一样的位置,然后添加成功

get和post的区别

1、传送方式:get通过地址栏传输,post通过报文传输。
2、传送长度:get参数有长度限制(受限于url长度),而post无限制
3、GET和POST还有一个重大区别,简单的说:
GET产生一个TCP数据包;POST产生两个TCP数据包
4、get不安全,post安全

wait()和notify()

类和抽象类的区别

抽象类不能被实例化
抽象类可以有抽象方法,抽象方法只需申明,无需实现
含有抽象方法的类必须申明为抽象类
抽象的子类必须实现抽象类中所有抽象方法,否则这个子类也是抽象类
抽象方法不能被声明为静态
抽象方法不能用private修饰
抽象方法不能用final修饰

Java类加载机制

类加载的过程包括了加载、验证、准备、解析、初始化五个阶段。

简述下io流

Java对数据的操作是通过流的方式,IO流用来处理设备之间的数据传输,上传文件和下载文件,Java用于操作流的对象都在IO包中

谈谈Java IO里面的常见类,字节流,字符流、接口、实现类、方法阻塞

输入流就是从外部文件输入到内存,输出流主要是从内存输出到文件。
IO里面常见的类,第一印象就只知道IO流中有很多类,IO流主要分为字符流和字节流。字符流中有抽象类InputStream和OutputStream,它们的子类FileInputStream,FileOutputStream,BufferedOutputStream等。字符流BufferedReader和Writer等。都实现了Closeable, Flushable, Appendable这些接口。程序中的输入输出都是以流的形式保存的,流中保存的实际上全都是字节文件。
java中的阻塞式方法是指在程序调用改方法时,必须等待输入数据可用或者检测到输入结束或者抛出异常,否则程序会一直停留在该语句上,不会执行下面的语句。比如read()和readLine()方法。

Java类和对象的初始化顺序

因为类的加载肯定是第一步的,所以类的初始化在前。大体的初始化顺序是:
类初始化 -> 子类构造函数 -> 父类构造函数 -> 实例化成员变量 -> 继续执行子类构造函数的语句

Java中的泛型是什么 ? 使用泛型的好处是什么?

提供了编译期的类型安全,确保你只能把正确类型的对象放入 集合中,避免了在运行时出现ClassCastException

简述TCP三次握手和四次挥手流程

三次握手
第一次:
客户端 - - > 服务器 此时服务器知道了客户端要建立连接了
第二次:
客户端 < - - 服务器 此时客户端知道服务器收到连接请求了
第三次:
客户端 - - > 服务器 此时服务器知道客户端收到了自己的回应
四次挥手
数据传输完毕后,双方都可以释放连接.
此时客户端和服务器都是处于ESTABLISHED状态,然后客户端主动断开连接,服务器被动断开连接.
1, 客户端进程发出连接释放报文,并且停止发送数据
释放数据报文首部,FIN=1,其序列号为seq=u(等于前面已经传送过来的数据的最后一个字节的序号加1),此时客户端进入FIN-WAIT-1(终止等待1)状态。 TCP规定,FIN报文段即使不携带数据,也要消耗一个序号。
2, 服务器收到连接释放报文,发出确认报文,ACK=1,确认序号为 u+1,并且带上自己的序列号seq=v,此时服务端就进入了CLOSE-WAIT(关闭等待)状态。
TCP服务器通知高层的应用进程,客户端向服务器的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个CLOSE-WAIT状态持续的时间。
3, 客户端收到服务器的确认请求后,此时客户端就进入FIN-WAIT-2(终止等待2)状态,等待服务器发送连接释放报文(在这之前还需要接受服务器发送的最终数据)
4, 服务器将最后的数据发送完毕后,就向客户端发送连接释放报文,FIN=1,确认序号为v+1,由于在半关闭状态,服务器很可能又发送了一些数据,假定此时的序列号为seq=w,此时,服务器就进入了LAST-ACK(最后确认)状态,等待客户端的确认。
5, 客户端收到服务器的连接释放报文后,必须发出确认,ACK=1,确认序号为w+1,而自己的序列号是u+1,此时,客户端就进入了TIME-WAIT(时间等待)状态。注意此时TCP连接还没有释放,必须经过2∗MSL(最长报文段寿命)的时间后,当客户端撤销相应的TCB后,才进入CLOSED状态。
6, 服务器只要收到了客户端发出的确认,立即进入CLOSED状态。同样,撤销TCB后,就结束了这次的TCP连接。可以看到,服务器结束TCP连接的时间要比客户端早一些。

String字符串反转顺序怎么做

调用StringBuffer的reverse()
new StringBuffer(“abcde”).reverse().toString()

stringbuffer和stringbuilder

1、这两个类之间的区别主要是在两个方面,即运行速度和线程安全这两方面。
2、首先说运行速度,或者说是执行速度,在这方面运行速度快慢为:StringBuilder > StringBuffer
3、在线程安全上,StringBuilder是线程不安全的,而StringBuffer是线程安全的
如果一个StringBuffer对象在字符串缓冲区被多个线程使用时,StringBuffer中很多方法可以带有synchronized关键字,所以可以保证线程是安全的,但StringBuilder的方法则没有该关键字,所以不能保证线程安全,有可能会出现一些错误的操作。所以如果要进行的操作是多线程的,那么就要使用StringBuffer,但是在单线程的情况下,还是建议使用速度比较快的StringBuilder。
4、StringBuilder:适用于单线程下在字符缓冲区进行大量操作的情况
StringBuffer:适用多线程下在字符缓冲区进行大量操作的情况

cookie被禁止后怎样使用session的解决方案?

经常被使用的一种技术叫做URL重写,就是把session id直接附加在URL路径的后面。
还有一种技术叫做表单隐藏字段。就是服务器会自动修改表单,添加一个隐藏字段,以便在表单提交时能够把session id传递回服务器。

jvm调优会吗,讲讲

1.Full GC
会对整个堆进行整理,包括Young、Tenured和Perm。Full GC因为需要对整个堆进行回收,所以比较慢,因此应该尽可能减少Full GC的次数。
1.监控GC的状态
使用各种JVM工具,查看当前日志,分析当前JVM参数设置,并且分析当前堆内存快照和gc日志,根据实际的各区域内存划分和GC执行时间,觉得是否进行优化。
2.生成堆的dump文件
通过JMX的MBean生成当前的Heap信息,大小为一个3G(整个堆的大小)的hprof文件,如果没有启动JMX可以通过Java的jmap命令来生成该文件。
3.分析dump文件
打开这个3G的堆信息文件,显然一般的Window系统没有这么大的内存,必须借助高配置的Linux,几种工具打开该文件:
Visual VM
IBM HeapAnalyzer
JDK 自带的Hprof工具
Mat(Eclipse专门的静态内存分析工具)推荐使用
备注:文件太大,建议使用Eclipse专门的静态内存分析工具Mat打开分析。
4.分析结果,判断是否需要优化
如果各项参数设置合理,系统没有超时日志出现,GC频率不高,GC耗时不高,那么没有必要进行GC优化,如果GC时间超过1-3秒,或者频繁GC,则必须优化。
注:如果满足下面的指标,则一般不需要进行GC:
Minor GC执行时间不到50ms;
Minor GC执行不频繁,约10秒一次;
Full GC执行时间不到1s;
Full GC执行频率不算频繁,不低于10分钟1次;
5.调整GC类型和内存分配
如果内存分配过大或过小,或者采用的GC收集器比较慢,则应该优先调整这些参数,并且先找1台或几台机器进行beta,然后比较优化过的机器和没有优化的机器的性能对比,并有针对性的做出最后选择。
6.不断的分析和调整
通过不断的试验和试错,分析并找到最合适的参数,如果找到了最合适的参数,则将这些参数应用到所有服务器。

jvm内存模型

JVM 内存共分为虚拟机栈,堆,方法区,程序计数器,本地方法栈五个部分。

JVM里面哪些区域是线程安全

程序计数器,虚拟机栈,本地方法栈这三个

mysql

你项目中的表结构设计是如何得(基本是个公司都会问)

通常先背一遍三范式

1、字段不可分
2、有主键,非主键字段依赖主键,ID字段就是主键,它能表示这一条数据是唯一的
3、非主键字段不能相互依赖

,然后讲了讲一对一,一对多,多对多得处理关系。
一对一:A表存B表id,A表id作为B表id
一对多:B表存A表parent_id,B表parent_id对应多个chirden_id
多对多:采用中间表的形式存储其关系。
表的字段尽量不要太长,导致数据过于冗余。查询频繁和低频字段应该分开存储。

数据库内联和外联的区别(交集并集)

内连接
定义:仅将两个表中满足连接条件的行组合起来作为结果集。
左(外)连接
定义:在内连接的基础上,还包含左表中所有不符合条件的数据行,并在其中的右表列填写NULL
右(外)连接
定义:在内连接的基础上,还包含右表中所有不符合条件的数据行,并在其中的左表列填写NULL

简单的sql优化讲讲你知道的

1.对查询进行优化,应尽量避免全表扫描
2.应尽量避免在 where 子句中对字段进行 null 值判断
3.加索引
4.索引并不是越多越好,索引固然可以提高相应的 select 的效率,但同时也降低了 insert 及 update 的效率
5.避免频繁创建和删除临时表,以减少系统表资源的消耗
6.尽量避免大事务操作,提高系统并发能力。

如何确定索引有没有被查询

在select语句前加上explain就可以了
当type出现ref或者index时,表示走的是索引

mysql索引(普通索引,唯一索引,主键索引,组合索引,全文索引,组合索引)

普通索引
普通索引是最基本的索引,它没有任何限制,值可以为空;仅加速查询
唯一索引
唯一索引与普通索引类似,不同的就是:索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一。
主键索引
主键索引是一种特殊的唯一索引,一个表只能有一个主键,不允许有空值。
组合索引
组合索引指在多个字段上创建的索引,只有在查询条件中使用了创建索引时的第一个字段,索引才会被使用。使用组合索引时遵循最左前缀集合。
全文索引
全文索引主要用来查找文本中的关键字,而不是直接与索引中的值相比较。fulltext索引跟其它索引大不相同,它更像是一个搜索引擎,而不是简单的where语句的参数匹配。

MySQL索引存储结构和特点

二叉树
红黑树 左旋右旋
Hash
B-Tree 设计阈值加大节点的存储(单条快,范围查不行)
B+Tree 非叶子节点存索引,叶子节点存数据(范围查快)

索引失效场景有哪些

1.列类型是字符串,查询条件未加引号。
2.未使用该列作为查询条件
3.使用like时通配符在前
4. 在查询条件中使用OR
5.对索引列进行函数运算
6.联合索引ABC问题

spring

spring中bean的生命周期

实例化 -> 属性赋值 -> 初始化 -> 销毁

如何理解依赖注入?(ioc控制反转)

依赖注入就是你不用关心对象的生命周期,什么时候被创建,什么时候销毁,只需直接使用即可,对象的生命周期由提供依赖注入的框架来管理

springmvc

简述下springmvc原理

1.客户端请求提交到DispatcherServlet
2.由DispatcherServlet控制器查询一个或多个HandlerMapping,找到处理请求的Controller
3.DispatcherServlet将请求提交到Controller
4.Controller调用业务逻辑处理后,返回ModelAndView
5.DispatcherServlet查询一个或多个ViewResoler视图解析器,找到ModelAndView指定的视图
6.视图负责将结果显示到客户端

springmvc三层架构之间是怎么互相传递数据的

xxxx

mybatis

springboot

juc

创建线程的四种方法

1、通过实现Runnable接口来创建Thread线程
2、与方法1类似,通过实现Callable接口来创建Thread线程
3、通过继承Thread类来创建一个线程
4、使用Executor框架来创建线程池

线程和进程的区别

根本区别:进程是操作系统资源分配的基本单位,而线程是任务调度和执行的基本单位
在开销方面:每个进程都有独立的代码和数据空间(程序上下文),程序之间的切换会有较大的开销;线程可以看做轻量级的进程,同一类线程共享代码和数据空间,每个线程都有自己独立的运行栈和程序计数器(PC),线程之间切换的开销小。
所处环境:在操作系统中能同时运行多个进程(程序);而在同一个进程(程序)中有多个线程同时执行(通过CPU调度,在每个时间片中只有一个线程执行)
内存分配方面:系统在运行的时候会为每个进程分配不同的内存空间;而对线程而言,除了CPU外,系统不会为线程分配内存(线程所使用的资源来自其所属进程的资源),线程组之间只能共享资源。
包含关系:没有线程的进程可以看做是单线程的,如果一个进程内有多个线程,则执行过程不是一条线的,而是多条线(线程)共同完成的;线程是进程的一部分,所以线程也被称为轻权进程或者轻量级进程。

讲讲volitail(轻量)关键字

当多个线程操作共享数据时,可以保证内存中的数据可见。用这个关键字修饰共享数据,就会及时的把线程缓存中的数据刷新到主存中去,也可以理解为,就是直接操作主存中的数据。所以在不使用锁的情况下,可以使用volatile。

如何保证多线程下 i++ 结果正确?

Java是可以用synchronized同步,其实就是加锁

谈谈JUC

xxxx

redis

Redis 数据结构使用场景

String——字符串
Hash——字典
List——列表
Set——集合
Sorted Set——有序集合

项目

xxxx

其他

MQ怎么防止消息丢失

A:生产者丢失消息
①:可以选择使用rabbitmq提供是事物功能,就是生产者在发送数据之前开启事物,然后发送消息,如果消息没有成功被rabbitmq接收到,那么生产者会受到异常报错,这时就可以回滚事物,然后尝试重新发送;如果收到了消息,那么就可以提交事物。
②:可以开启confirm模式。在生产者哪里设置开启了confirm模式之后,每次写的消息都会分配一个唯一的id,然后如何写入了rabbitmq之中,rabbitmq会给你回传一个ack消息,告诉你这个消息发送OK了;如果rabbitmq没能处理这个消息,会回调你一个nack接口,告诉你这个消息失败了,你可以进行重试。而且你可以结合这个机制知道自己在内存里维护每个消息的id,如果超过一定时间还没接收到这个消息的回调,那么你可以进行重发。
B:rabbitmq自己弄丢了数据
设置消息持久化到磁盘。设置持久化有两个步骤:
①创建queue的时候将其设置为持久化的,这样就可以保证rabbitmq持久化queue的元数据,但是不会持久化queue里面的数据。
②发送消息的时候讲消息的deliveryMode设置为2,这样消息就会被设为持久化方式,此时rabbitmq就会将消息持久化到磁盘上。
必须要同时开启这两个才可以。
而且持久化可以跟生产的confirm机制配合起来,只有消息持久化到了磁盘之后,才会通知生产者ack,这样就算是在持久化之前rabbitmq挂了,数据丢了,生产者收不到ack回调也会进行消息重发。
C:消费者弄丢了数据
使用rabbitmq提供的ack机制,首先关闭rabbitmq的自动ack,然后每次在确保处理完这个消息之后,在代码里手动调用ack。这样就可以避免消息还没有处理完就ack。
(2)kafka
A:消费端弄丢了数据
关闭自动提交offset,在自己处理完毕之后手动提交offset,这样就不会丢失数据。
B:kafka弄丢了数据
一般要求设置4个参数来保证消息不丢失:
①给topic设置 replication.factor参数:这个值必须大于1,表示要求每个partition必须至少有2个副本。
②在kafka服务端设置min.isync.replicas参数:这个值必须大于1,表示 要求一个leader至少感知到有至少一个follower在跟自己保持联系正常同步数据,这样才能保证leader挂了之后还有一个follower。
③在生产者端设置acks=all:表示 要求每条每条数据,必须是写入所有replica副本之后,才能认为是写入成功了
④在生产者端设置retries=MAX(很大的一个值,表示无限重试):表示 这个是要求一旦写入事变,就无限重试
C:生产者弄丢了数据
如果按照上面设置了ack=all,则一定不会丢失数据,要求是,你的leader接收到消息,所有的follower都同步到了消息之后,才认为本次写成功了。如果没满足这个条件,生产者会自动不断的重试,重试无限次。

单例设计模式

在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例

简述下aop

面向切面编程,通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术

领域模型相关知识

领域模型 对于程序员来说真正困难或者困惑的部分
是领域模型本身怎么和其它模块(或者其它层)进行交互,这些交互或者说关系是
对于一个领域模型来说,从语言层面来讲,它具备 5 方面的特性:
1:有父类,放置公共的属性之类的内容,同时,存在一个父类,也表示它不是一个 值对象(领域概念中的值对象);
2:有实例字段;
3:有实例属性;
4:领域自身逻辑,非 static 方法,有 public 的和 非public;
5:领域服务,static 方法,可独立出去放置到对应的 服务类 中;

缓存算法(淘汰策略)

LFU 的每个数据块都有一个引用计数,所有数据块按照引用计数排序,具有相同引用计数的数据块则按照时间排序
LRU(LeastRecently User): 根据数据的历史访问记录来进行淘汰数据,其核心思想是“如果数据最近被访问过,那么将来被访问的几率也更高”
LRU-K(LeastRecently Used K) : 相比LRU,LRU-K需要多维护一个队列,用于记录所有缓存数据被访问的历史。只有当数据的访问次数达到K次的时候,才将数据放入缓存。当需要淘汰数据时,LRU-K会淘汰第K次访问时间距当前时间最大的数据。
FIFO(First inFirst out) : 最先进入的数据,最先被淘汰。一个很简单的算法。只要使用队列数据结构即可实现。那么FIFO淘汰算法基于的思想是”最近刚访问的,将来访问的可能性比较大”。
2Q(Two Queues) : 同样也是为了解决LRU算法的缓存污染问题。类似于LRU-2,不同点在于2Q将LRU-2算法中的访问历史队列改为一个FIFO缓存队列,即:2Q算法有两个缓存队列,一个是FIFO队列,一个是LRU队列。
当数据第一次访问时,2Q算法将数据缓存在FIFO队列里面,当数据第二次被访问时,则将数据从FIFO队列移到LRU队列里面,两个队列各自按照自己的方法淘汰数据。

既然你对spi有一定了解,那么dubbo的spi和jdk的spi有区别吗?有的话,究竟有什么区别?

xxxx

你说你看过Dubbo源码,那你简单说下,他在设计上有哪些细节让你觉得很巧妙?(区分度高)

xxxx

事务的四个特性

原子性、一致性、隔离性、持久性

并发下事务会产生的问题

举个例子,事务A和事务B操纵的是同一个资源,事务A有若干个子事务,事务B也有若干个子事务,事务A和事务B在高并发的情况下,会出现各种各样的问题。“各种各样的问题”,总结一下主要就是五种:第一类丢失更新、第二类丢失更新、脏读、不可重复读、幻读。五种之中,第一类丢失更新、第二类丢失更新不重要,不讲了,讲一下脏读、不可重复读和幻读。
1、脏读
所谓脏读,就是指事务A读到了事务B还没有提交的数据,比如银行取钱,事务A开启事务,此时切换到事务B,事务B开启事务–>取走100元,此时切换回事务A,事务A读取的肯定是数据库里面的原始数据,因为事务B取走了100块钱,并没有提交,数据库里面的账务余额肯定还是原始余额,这就是脏读。
2、不可重复读
所谓不可重复读,就是指在一个事务里面读取了两次某个数据,读出来的数据不一致。还是以银行取钱为例,事务A开启事务–>查出银行卡余额为1000元,此时切换到事务B事务B开启事务–>事务B取走100元–>提交,数据库里面余额变为900元,此时切换回事务A,事务A再查一次查出账户余额为900元,这样对事务A而言,在同一个事务内两次读取账户余额数据不一致,这就是不可重复读。
3、幻读
所谓幻读,就是指在一个事务里面的操作中发现了未被操作的数据。比如学生信息,事务A开启事务–>修改所有学生当天签到状况为false,此时切换到事务B,事务B开启事务–>事务B插入了一条学生数据,此时切换回事务A,事务A提交的时候发现了一条自己没有修改过的数据,这就是幻读,就好像发生了幻觉一样。幻读出现的前提是并发的事务中有事务发生了插入、删除操作。

事务隔离级别

事务隔离级别,就是为了解决上面几种问题而诞生的。为什么要有事务隔离级别,因为事务隔离级别越高,在并发下会产生的问题就越少,但同时付出的性能消耗也将越大,因此很多时候必须在并发性和性能之间做一个权衡。所以设立了几种事务隔离级别,以便让不同的项目可以根据自己项目的并发情况选择合适的事务隔离级别,对于在事务隔离级别之外会产生的并发问题,在代码中做补偿。
事务隔离级别有4种,但是像Spring会提供给用户5种,来看一下:
1、DEFAULT
默认隔离级别,每种数据库支持的事务隔离级别不一样,如果Spring配置事务时将isolation设置为这个值的话,那么将使用底层数据库的默认事务隔离级别。顺便说一句,如果使用的MySQL,可以使用"select @@tx_isolation"来查看默认的事务隔离级别
2、READ_UNCOMMITTED
读未提交,即能够读取到没有被提交的数据,所以很明显这个级别的隔离机制无法解决脏读、不可重复读、幻读中的任何一种,因此很少使用
3、READ_COMMITED
读已提交,即能够读到那些已经提交的数据,自然能够防止脏读,但是无法限制不可重复读和幻读
4、REPEATABLE_READ
重复读取,即在数据读出来之后加锁,类似"select * from XXX for update",明确数据读取出来就是为了更新用的,所以要加一把锁,防止别人修改它。REPEATABLE_READ的意思也类似,读取了一条数据,这个事务不结束,别的事务就不可以改这条记录,这样就解决了脏读、不可重复读的问题,但是幻读的问题还是无法解决
5、SERLALIZABLE
串行化,最高的事务隔离级别,不管多少事务,挨个运行完一个事务的所有子事务之后才可以执行另外一个事务里面的所有子事务,这样就解决了脏读、不可重复读和幻读的问题了
网上专门有图用表格的形式列出了事务隔离级别解决的并发问题:

事务的传播行为


REQUIRED(require):支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
SUPPORTS(supports):支持当前事务,如果当前没有事务,就以非事务方式执行。
MANDATORY(mandatory):支持当前事务,如果当前没有事务,就抛出异常。
REQUIRES_NEW(requires-new):新建事务,如果当前存在事务,把当前事务挂起。
NOT_SUPPORTED(not-supported):以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
NEVER(never):以非事务方式执行,如果当前存在事务,则抛出异常。
NESTED(nested):支持当前事务,如果当前事务存在,则执行一个嵌套事务,如果当前没有事务,就新建一个事务

反问环节

我今天面试的表现如何,有什么建议吗?

公司现在主要的技术栈是什么?

毕业半年无工作经验的程序员面试会遇到哪些问题相关推荐

  1. 面试感悟-------一名3年工作经验的程序员应该具备的技能

    转载: 面试感悟-------一名3年工作经验的程序员应该具备的技能 前言 因为和同事有约定再加上LZ自己也喜欢做完一件事之后进行总结,因此有了这篇文章.这篇文章大部分内容都是面向整个程序员群体的,当 ...

  2. 3年半工作经验女程序员,聊聊程序员的薪水、工作内容和发展前景

    我先简单说一下我的职业经历,我是有3年半工作经验的程序员,主要负责企业办公网站的开发工作.大家一提到程序员,第一印象应该就是高薪,但是除了高薪以外,对这个职业的了解就不够了.为了回应粉丝的要求,接下来 ...

  3. 面试感悟----一名3年工作经验的程序员应该具备的技能,对于一些入门或者还在面试阶段的人有着很大的启发...

    前言 因为和同事有约定再加上LZ自己也喜欢做完一件事之后进行总结,因此有了这篇文章.这篇文章大部分内容都是面向整个程序员群体的,当然因为LZ本身是做Java开发的,因此有一部分内容也是专门面向咱们Ja ...

  4. 面试感悟—-一名3年工作经验的程序员应该具备的技能

    文章来自:五月的仓颉 五月的仓颉 是一位非常优秀,乐于分享的大神,目前就职阿里 原文链接:https://www.cnblogs.com/xrq730/p/5260294.html 前言 因为和同事有 ...

  5. 一名3年工作经验的程序员应该具备的技能

    本文转自:https://m.imooc.com/article/details?article_id=7557 前言 因为和同事有约定再加上LZ自己也喜欢做完一件事之后进行总结,因此有了这篇文章.这 ...

  6. c#窗体编辑个人简历_3年工作经验.net程序员简历应该怎么写

    .net程序员个人简历范文一 工作经历:河北零风软件有限公司 时间:2015-2018 岗位:程序员.net 工作描述:我任职河北零风软件有限公司技术部门,该部门后台系统主要由API模块,APP后台模 ...

  7. 为什么没有工作经验的程序员很难找工作?

    主要是和大量的培训出来的程序员有关,很多培训机构都变了味,变得越来越商业化. 第一,招生门槛越来越低.大部分培训机构为了赚钱,不管什么学员都收,非专业的收,高中毕业的也收.一个班里几十号人,学员水平良 ...

  8. 一名3年工作经验的程序员应该具备的技能 !

    前言 因为和同事有约定再加上LZ自己也喜欢做完一件事之后进行总结,因此有了这篇文章.这篇文章大部分内容都是面向整个程序员群体的,当然因为LZ本身是做Java开发的,因此有一部分内容也是专门面向咱们Ja ...

  9. 没有学历没有工作经验的程序员怎么找工作

    我是因为刚培训机构学完找不到工作,近几个月的总结 我因为这块硬性门槛, 很多投递的简历都石沉大海, 我查阅了很多网站和对信息的多方面对比总结出的结论 1.不要海投 站在HR的角度来看,他不是很懂技术他 ...

最新文章

  1. [转]在ITunes播放中前进、后退五秒的快捷键
  2. Redmi Note 11系列来势汹汹,一“机”打尽更多看不见的旗舰猛料
  3. python 列表函数
  4. MATLAB中的曲线拟合
  5. 用c语言编声光报警子程序,C语言编程的智能火灾报警监测系统
  6. 213.打家劫舍II
  7. 基于Sklearn实现LDA算法
  8. java节假日算法_java生成一年中假日表(包括周末和法定假期),用于计算一年中的工作日...
  9. 搜狗输入法弹出搜狗新闻的解决办法
  10. Cookie的path和diamon
  11. 云计算机到底是啥来的,啥叫云计算(云计算究竟是什么)
  12. sweetalert弹框插架--自定义多按钮事件
  13. leetcode 1567. 乘积为正数的最长子数组长度python
  14. PHP CURL实现单线程、多线程方法
  15. Scala:函数与匿名函数
  16. WSL 2 installation is incomplete.【BUG解决】【Docker之云原生基石】
  17. 主流的操作系统(带你快速了解)
  18. 为什么找不到用户和计算机名,win10电脑“本地用户和组”找不到该怎么办啊?...
  19. ProCAST一键导出有限元模型的几何拓扑和属性信息
  20. 用uni-app进行小程序的开发

热门文章

  1. 《工程伦理》网课第一章课后习题答案
  2. YOLOv5(v6.1)解析(四)超参数进化
  3. 【测试基础】之05 后端语言
  4. Android 项目 sdk导入腾讯云cos:
  5. 总结我工作多年来必备的办公神器,收藏好哟
  6. 利用GCV方法选择回归函数的局部线性估计的带宽
  7. Python预测之美 数据分析与算法实战(二)
  8. 处理可预料的异常处理
  9. 常用的8种字符串处理函数
  10. StringBuilder转Json