宁波银行金融岗最全面经
本面经整理来自牛客各位牛友以及CSDN以及同学以及本人
此处为宁波银行总行科技岗(JAVA语言方向)的面经集合(答案仅供参考,可自行百度)
面试流程
5-10分钟
1.自我介绍一分钟
2.问基础问题2-6个
3.有可能会问一下项目,以及项目中遇到的问题怎么解决的
面经
JDBC如何实现,步骤
在java开发中,数据一般保存于数据库中;由于数据库开发商有许多,连接标准各不相同;为了解决这个问题,java开发了一套访问数据库的解决方案叫JDBC,用相同的访问方式访问不同的数据库,其定义了一套标准接口,数据库开发商根据这个接口按照各自不同的特点,实现这个JDBC接口。
JDBC工作原理:
1.加载驱动,建立连接;
2.创建sql语句对象;
3.执行sql;
4.处理结果集;
5.关闭连接。
Java的特性,多态实现的方法
封装、继承和多态
多态:
1.继承了某个类,实现了某个接口
2.重写父类的方法,实现接口中的方法
3.父类引用指向子类对象
sleep和wait区别
1.sleep方法是Thread类的静态方法;
wait方法是Object类的成员方法
2.sleep方法使当前线程暂停执行指定的时间,让出cpu给其他线程,但是它的监控状态依然保持着,当指定的时间到了又会自动恢复运行状态。在调用sleep方法后,线程不会释放对象锁;
而当调用wait方法时,线程会放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象调用notify()方法后本线程才进入对象锁定池处于准备状态。
3.sleep方法有可能会抛出异常,所以需要进行异常处理;
wait方法不需要处理
4.sleep方法可以在任何地方使用;
wait方法只能在同步方法和同步代码块中使用
final finally finalize的区别
final 表示最终的、不可改变的。用于修饰类、方法和变量。
finally 异常处理的一部分,它只能用在try/catch语句中,表示希望finally语句块中的代码最后一定被执行(但是不一定会被执行)
finalize()是在java.lang.Object里定义的,Object的finalize方法什么都不做,对象被回收时finalized方***被调用。
特殊情况下,可重写finalize方法,当对象被回收的时候释放一些资源。但注意,要调用super.finalize()。
hashmap原理
HashMap的主干是一个Entry数组。Entry是HashMap的基本组成单元,每一个Entry包含一个key-value键值对。
简单来说,HashMap由数组+链表组成的,数组是HashMap的主体,链表则是主要为了解决哈希冲突而存在的,如果定位到的数组位置不含链表(当前entry的next指向null),那么对于查找,添加等操作很快,仅需一次寻址即可;如果定位到的数组包含链表,对于添加操作,其时间复杂度为O(n),首先遍历链表,存在即覆盖,否则新增;对于查找操作来讲,仍需遍历链表,然后通过key对象的equals方法逐一比对查找。所以,性能考虑,HashMap中的链表出现越少,性能才会越好。
HashMap和HashTable的区别
1.父类不同:
HashTable是继承自Dictionary, HashMap是继承自AbstractMap
2.null值问题
Hashtable既不支持Null key也不支持Null value。
HashMap中,null可以作为键,这样的键只有一个;可以有一个或多个键所对应的值为null。
3.线程安全性
Hashtable是线程安全的,它的每个方法中都加入了Synchronize方法。在多线程并发的环境下,可以直接使用Hashtable
HashMap不是线程安全的,在多线程并发的环境下,可能会产生死锁等问题。
4.初始容量不同
Hashtable的初始长度是11,之后每次扩充容量变为之前的2n+1(n为上一次的长度)
而HashMap的初始长度为16,之后每次扩充变为原来的两倍
5.计算哈希值的方法不同
Hashtable直接使用对象的hashCode。hashCode是JDK根据对象的地址或者字符串或者数字算出来的int类型的数值。然后再使用除留余数发来获得最终的位置。 然而除法运算是非常耗费时间的。效率很低
HashMap为了提高计算效率,将哈希表的大小固定为了2的幂,这样在取模预算时,不需要做除法,只需要做位运算。位运算比除法的效率要高很多。
drop delete truncate区别
1.drop (删除表):删除内容和定义,释放空间。简单来说就是把整个表去掉.以后要新增数据是不可能的,除非新增一个表。
2.truncate (清空表中的数据):删除内容、释放空间但不删除定义(保留表的数据结构)。与drop不同的是,只是清空表数据而已。
注意:truncate 不能删除行数据,要删就要把表清空。
3.truncate table 删除表中的所有行,但表结构及其列、约束、索引等保持不变。新行标识所用的计数值重置为该列的种子。如果想保留标识计数值,请改用delete。
4.delete (删除表中的数据):delete 语句用于删除表中的行。
执行速度,一般来说: drop> truncate > delete。
数据库表连接的几种方式
1.内连接:join,inner join
2.外连接:left join,left outer join,right join,right outer join,union
3.交叉连接:cross join
array arraylist区别
一、Array和ArrayList的区别
- Array类型的变量在声明的同时必须进行实例化(至少得初始化数组的大小),而ArrayList可以只是先声明。
- Array只能存储类型相同的对象,而ArrayList可以存储不同类型的数据。
- Array是始终是连续存放的,而ArrayList的存放不一定连续。
- Array对象的初始化必须只定指定大小,且创建后的数组大小是固定的,而ArrayList的大小可以动态指定,其大小可以在初始化时指定,也可以不指定,也就是说该对象的空间可以任意增加。
- Array不能够随意添加和删除其中的项,而ArrayList可以在任意位置插入和删除项。
二、Array和ArrayList的相似点 - 都具有索引(index),即可以通过index来直接获取和修改任意项。
- 他们所创建的对象都放在托管堆中。
- 都能够对自身进行枚举(因为都实现了IEnumerable接口)。
==和equals
1)对于==,比较的是值是否相等
如果作用于基本数据类型的变量,则直接比较其存储的 值是否相等,
如果作用于引用类型的变量,则比较的是所指向的对象的地址是否相等。
其实==比较的不管是基本数据类型,还是引用数据类型的变量,比较的都是值,只是引用类型变量存的值是对象的地址
2)对于equals方法,比较的是是否是同一个对象
首先,equals()方法不能作用于基本数据类型的变量,
另外,equals()方法存在于Object类中,而Object类是所有类的直接或间接父类,所以说所有类中的equals()方法都继承自Object类,在没有重写equals()方法的类中,调用equals()方法其实和使用==的效果一样,也是比较的是引用类型的变量所指向的对象的地址,不过,Java提供的类中,有些类都重写了equals()方法,重写后的equals()方法一般都是比较两个对象的值,比如String类。run和start的区别
区别:调用start方法实现多线程,而调用run方法没有实现多线程
Start:用start方法来启动线程,真正实现了多线程运行,这时无需等待run方法体代码执行完毕而直接继续执行下面的代码。通过调用Thread类的start()方法来启动一个线程,这时此线程处于就绪(可运行)状态,并没有运行,一旦得到spu时间片,就开始执行run()方法,这里方法run()称为线程体,它包含了要执行的这个线程的内容,Run方法运行结束,此线程随即终止。
Run:run()方法只是类的一个普通方法而已,如果直接调用Run方法,程序中依然只有主线程这一个线程,其程序执行路径还是只有一条,还是要顺序执行,还是要等待run方法体执行完毕后才可继续执行下面的代码,这样就没有达到写线程的目的。
总结:调用start方法方可启动线程,而run方法只是thread的一个普通方法调用,还是在主线程里执行JVM运行时内存
JVM运行时内存主要分5块,Java堆、方法区、本地方法栈、虚拟机栈、程序计数器,其中Java堆与方法区为线程共享,本地方法栈、虚拟机栈、程序计数器为线程私有。集合排序怎么实现,用什么排序来实现
java集合的工具类Collections中提供了两种排序的方法,分别是:
Collections.sort(List list)
Collections.sort(List list,Comparator c)
第一种称为自然排序,参与排序的对象需实现comparable接口,重写其compareTo()方法,方法体中实现对象的比较大小规则
第二种叫定制排序,需编写匿名内部类,先new一个Comparator接口的比较器对象c,同时实现其compare()方法;
然后将比较器对象c传给Collections.sort()方法的参数列表中,实现排序功能;泛型是什么?有什么作用?
“泛型” 意味着编写的代码可以被不同类型的对象所重用。泛型的提出是为了编写重用性更好的代码。泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。
泛型:把类型明确的工作推迟到创建对象或调用方法的时候才去明确的特殊的类型
有了泛型以后:代码更加简洁【不用强制转换】
程序更加健壮【只要编译时期没有警告,那么运行时期就不会出现ClassCastException异常】
可读性和稳定性【在编写集合的时候,就限定了类型】
生成对象的几种方式
1.new
2.clone
3.newInstance
4.反序列化
5.String s = "abc"(这个是比较特殊的)
多线程实现的方式
方式一:继承Thread类的方式
方式二:实现Runnable接口的方式
方式三:实现Callable接口
方式四:使用线程池
NIO和BIO、AIO的区别
BIO (Blocking I/O):同步阻塞I/O模式,数据的读取写入必须阻塞在一个线程内等待其完成。
NIO (New I/O):同时支持阻塞与非阻塞模式,
序列化与反序列化,用在什么场景,可能出现的异常
主要用于存储对象状态为另一种通用格式,比如存储为二进制、xml、json等等,把对象转换成这种格式就叫序列化,而反序列化通常是从这种格式转换回来。使用序列化主要是因为跨平台和对象存储的需求,因为网络上只允许字符串或者二进制格式,而文件需要使用二进制流格式,如果想把一个内存中的对象存储下来就必须使用序列化转换为xml(字符串)、json(字符串)或二进制(流)
简单来说,Java的序列化机制是通过在运行时判断类的serialVersionUID来验证版本一致性的。在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体(类)的serialVersionUID进行比较,如果相同就认为是一致的,可以进行
反序列化,否则就会出现序列化版本不一致的异常。(InvalidCastException)
强烈建议在一个可序列化类中显示的定义serialVersionUID,为它赋予明确的值。
servlet生命周期:
1.servlet的生命周期
主要有三个方法:
init()初始化阶段
service()处理客户端请求阶段
destroy()终止阶段
初始化阶段:
Servlet容器加载Servlet,加载完成后,Servlet容器会创建一个Servlet实例并调用init()方法,init()方法只会调用一次
Servlet容器会在一下几种情况装载Servlet:
Servlet容器启动时自动装载某些servlet,实现这个需要在web.xml文件中添加1
在Servlet容器启动后,客户首次向Servlet发送请求
Servlet类文件被更新后,重新装载
处理客户端请求阶段:
每收到一个客户端请求,服务器就会产生一个新的线程去处理。
对于用户的Servlet请求,Servlet容器会创建一个特定于请求的ServletRequest和ServletResponse。
对于tomcat来说,它会将传递来的参数放入一个HashTable中,这是一个String–>String[]的键值映射
终止阶段:
当web应用被终止,或者Servlet容器终止运行,或者Servlet重新装载Servlet新实例时,Servlet容器会调用Servlet的destroy()方法
2.servlet的工作原理
客户发送一个请求,Servlet调用service()方法对请求进行响应,service()方***对请求的方法进行匹配,进入相应的逻辑层,完成请求的响应。
但是Servlet接口和GenericServlet接口中没有doGet(),doPost()等方法,HttpServlet中定义了这些,但是返回的都是Error信息,所以每次定义Servlet都要重写这些方法。
Sertvlet和GenericServlet是不特定于任何协议的,而HttpServlet是特定于Http协议的,所以HttpServlet中的service()方法中将ServletRequest,ServletResponse强转为HttpRequest和HttpResponse,最后调用自己的service方法去完成响应。
构造函数的特点:
- 构造函数的主要作用是完成对象的初始化工作,
- 它能够把定义对象时的参数传给对象的域。意即当创建一个对象时,这个对象就被初始化.如果这时构造函数不为空,则会在
创建对象时就执行构造函数里面的代码。 - 构造函数的名称必须与类名相同,包括大小写;
- 构造函数没有返回值,也不能用void修饰.
- 一个类可以定义多个构造方法,如果在定义类时没有定义构造方法,则编译系统会自动插入一个无参数的默认构造器,这个构造器不执行任何代码。
- 构造方法可以重载
string、stringbuilder、stringbuffer的区别
java对象生命周期
对象的整个生命周期大致可以分为7个阶段:创建阶段(Creation)、应用阶段(Using)、不可视阶段(Invisible)、不可到达阶段(Unreachable)、可收集阶段(Collected)、终结阶段(Finalized)与释放阶段(Free)java类生命周期
一个java类的完整的生命周期会经历加载、连接、初始化、使用、和卸载五个阶段
SpringBoot运行过程
主要分为三个部分,第一部分进行SpringApplication的初始化模块,配置一些基本的环境变量、资源、构造器、监听器,第二部分实现了应用具体的启动方案,包括启动流程的监听模块、加载配置环境模块、及核心的创建上下文环境模块,第三部分是自动化配置模块,该模块作为springboot自动配置核心并发事务
- 事务的并发问题如何发生?
多个事务同时操作同一个数据库的相同数据时 - 并发问题都有哪些
脏读:一个事务读取了其他事务还没有提交的数据 读到的是其他事物更新的数据
不可重复度:一个事务多次读取,结果不一样
幻读:一个事务读取了其他事物还没有提交的数据,只是读到的是其他事物插入的数据
抽象类和接口都不能直接实例化,如果要实例化,抽象类变量必须指向实现所有抽象方法的子类对象,接口变量必须指向实现所有接口方法的类对象。
抽象类要被子类继承,接口要被类实现。
接口里定义的变量只能是公共的静态的常量,抽象类中的变量是普通变量。
抽象类里可以没有抽象方法。
接口可以被类多实现(被其他接口多继承),抽象类只能被单继承。
接口中没有 this 指针,没有构造函数,不能拥有实例字段(实例变量)或实例方法。
抽象类不能在Java 8 的 lambda 表达式中使用。
如何解决并发问题
通过设置隔离级别
隔离级别
脏读 不可重复读 幻读
read uncommitted:读未提交 × × ×
read committed:读已提交 √ × ×
repeatable read:可重复度 √ √ ×
serializable:串行化 √ √ √
事务特性
1、原子性(Atomicity)
原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚,因此事务的操作如果成功就必须要完全应用到数据库,如果操作失败则不能对数据库有任何影响。
2、 一致性(Consistency)
一致性是指事务必须使数据库从一个一致性状态变换到另一个一致性状态,也就是说一个事务执行之前和执行之后都必须处于一致性状态。
3、隔离性(Isolation)
隔离性是当多个用户并发访问数据库时,比如操作同一张表时,数据库为每一个用户开启的事务,不能被其他事务的操作所干扰,多个并发事务之间要相互隔离。
4、持久性(Durability)
持久性是指一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的,即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作。
LinkedeList和ArrayList的区别
1、数据结构不同
ArrayList是Array(动态数组)的数据结构,LinkedList是Link(链表)的数据结构。
2、效率不同
当随机访问List(get和set操作)时,ArrayList比LinkedList的效率更高,因为LinkedList是线性的数据存储方式,所以需要移动指针从前往后依次查找
当对数据进行增加和删除的操作(add和remove操作)时,LinkedList比ArrayList的效率更高,因为ArrayList是数组,所以在其中进行增删操作时,会对操作点之后所有数据的下标索引造成影响,需要进行数据的移动。
3、自由性不同
ArrayList自由性较低,因为它需要手动的设置固定大小的容量,但是它的使用比较方便,只需要创建,然后添加数据,通过调用下标进行使用;而LinkedList自由性较高,能够动态的随数据量的变化而变化,但是它不便于使用。
4、主要控件开销不同
ArrayList主要控件开销在于需要在lList列表预留一定空间;而LinkList主要控件开销在于需要存储结点信息以及结点指针信息。
spring aop
AOP(Aspect-Oriented Programming,面向切面编程)能够将那些与业务无关,却为业务模块所共同调用的逻辑或责任(例如事务处理、日志管理、权限控制等)封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可扩展性和可维护性。
spring配置方式
基于XML的配置
基于注解的配置
基于Java的配置
sql注入
SQL注入即是指web应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步得到相应的数据信息。
什么是Spring
Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开发框架。Spring是为了解决企业级应用开发的复杂性而创建的,使用Spring可以让简单的JavaBean实现之前只有EJB才能完成的事情。但是Spring不仅仅局限于服务器端开发,任何Java应用都能在简单性、可测试性和松耦合性等方面从Spring中获益。
什么是SpringBoot
Spring Boot 是所有基于 Spring 开发的项目的起点。Spring Boot 的设计是为了让你尽可能快的跑起来 Spring 应用程序并且尽可能减少你的配置文件。简单来说就是SpringBoot其实不是什么新的框架,它默认配置了很多框架的使用方式,就像maven整合了所有的jar包,spring boot整合了所有的框架(不知道这样比喻是否合适)。
SpringBoot四个主要特性
1、SpringBoot Starter:他将常用的依赖分组进行了整合,将其合并到一个依赖中,这样就可以一次性添加到项目的Maven或Gradle构建中;
2、自动配置:SpringBoot的自动配置特性利用了Spring4对条件化配置的支持,合理地推测应用所需的bean并自动化配置他们;
3、命令行接口:(Command-line-interface, CLI):SpringBoot的CLI发挥了Groovy编程语言的优势,并结合自动配置进一步简化Spring应用的开发;
4、Actuatir:它为SpringBoot应用的所有特性构建一个小型的应用程序。但首先,我们快速了解每项特性,更好的体验他们如何简化Spring编程模型。
SpringBoot开发的具体好处
回顾我们之前的 SSM 项目,搭建过程还是比较繁琐的,需要:
1、配置web.xml,加载spring和spring mvc
2、配置数据库连接、配置spring事务
3、配置加载配置文件的读取,开启注解
。。。
配置完成之后部署tomcat 调试
而使用 Spring Boot 来开发项目则只需要非常少的几个配置就可以搭建起来一个 Web 项目,并且利用 IDEA 可以自动生成生成
什么是Spring MVC
SpringMVC 是一种基于 Java 的实现 MVC 设计模型的请求驱动类型的轻量级 Web 框架,