java基础面试题

1:map集合的遍历方式

1:遍历map集合需要的用到的方法

1:将map所有的key封装到一个set的集合

2:根据key获取map中对应的value

3:entrySet获取所有的键值对对象

4:将map中所有的value封装到一个Collection体系的集合

2:遍历ma集合的几种方式

1:根据键找值

2:获取所有的键值对对象集合,通过迭代器遍历

3:获取所有的键值对对象集合,通过增强for比那里

4:通过map集合中的values方法,拿到所有的值

3:Map的实现类有哪些(拓展)

1:TreeMaps使用二叉树进行存储

2:HashTable:线程安全,效率低

3:HashMap:线程不安全,效率高


2:HashMap的特性

1:Map集合的特点

1:Map是一个双列集合,将键映射到值的对象

2:Map集合的数据结构,只针对键有效,跟值没有关系

3:一个映射下不能包含重复的值,每个值最多只能映射到一个值

2:数据结构

1:哈希表结构:数组+链表

通过哈希表结构配合对象的hashcode和equles方法保证见键的唯一性

存储自定义类型的数据时,要重写hashCode和equles方法

3:hashmap和hashtable的区别

1:HashMap:不同步(线程不安全)

2:HashTable:同步(线程安全)

3:HashMap集合的扩展

1:jdk1.8版本以后,在哈希表结构中引出了二叉树

提高了查询的效率

4:Java虚拟机的内存模型

1:java虚拟机的内存空间

1:栈内存:方法运行时所进入的内存,里面还会存储程序的局部变量

2:堆内存:new出来的数据都会进入堆内存

3:方法去:字节码文件加载时进入的内存

4:本地方法区:内存空间主要调用的是操作系统相关资源

5:寄存器:交给cpu使用

5:线程内存空间

1:带有线程的内存图

1:每一个线程都会有自己独立的栈内存空间

6:java中的异常处理机制的简单原理和应用

1:什么是异常

异常就是程序的不正常,程序所发生的错误

2:异常体系结构和分类

1:分类

编译时异常 运行时异常

2:体系结构

Thorwable

Error:严重生错误

Exception:

RunnTimeException:运行时异常

!RunnTimeException:编译时异常

3:异常处理方式

1:自己手动处理

2:throws抛出处理方式

7:创建线程的几种方法

1:继承Thread类

优点:代码简单

缺点:取法继承别的类

2:实现Runnable接口

优点:继承其他的类,统一实现接口的实例可以共享资源

缺点:代码复杂

3:实现Callable接口

有返回值

4:线程池方式

优点:实现自动化装配,易于管理,循环利用资源

8:垃圾回收机制的了解

1:什么样的对象会被当做垃圾回收?

当一个对象的引用没有被变量去记录时,就会成为垃圾对象

2:如何校验对象是否被收回?

重写Object中的finalize方法。自动调用这个方法

3:如何通知垃圾回收器回收对象

调用System类的静态方法

9:HashCode,equles的区别

1:作用

1:不重写:比较的是地址值

2:重写的话:比较的是信息内容

10:String,StringBuilder,StringBuffer三者区别

1:String和StringBuilder的本质区别是?

String是一个不可改变的字符序列

StringBuilder是一个可以改变的字符序列

2:常见字符串拼接

推荐使用StringBuilder效率高

3:StringBuilder和StringBuffer的区别

1:buffer线程安全:效率低

2:builder线程不安全:效率高

4:SQL语句拼接

内容多使用StringBuilder拼接,内容少使用String

11:是否可以从一个static方法内部发出对非static方法的调用

12:wait方法和sleep方法的区别

1:基本使用

1:wait:此方法来自Object类,必须由锁对象进行调用

2:sleep:此方法来自Thread类,是Thread类的静态方法,可以类名点调用

13:问题拓展应用场景

14:String s=new String(“asc”)创建了几个StringObject?是够可以继承String类吗?

1:String创建对象有什么特点?

1:如果已经创建,就不会创建了

2:如果没有创建,则会创建两个对象

15:多线程中解决同步问题的方式

1:同步代码快

2:同步方法

3:Lock锁方式

16:HashMap和HashTable的区别

1:相同点

1:都是双列集合,一个键对应一个值

2:都是键不能重复,但是值可以重复

2:不同点

1:出现的版本区别

map是1.2版本出现的

table是1.0出现的

2:线程同步的区别

map是线程不同步的

table是线程同步的

3:存储数据的区别

map可以存储null键和null值

table不能存储null键和NULL值

17:单例设计模式中懒汉式和恶汉式区别

1:懒汉模式:再类加载的时候不能被初始化

2:恶汉模式:在类加载时就完成了初始化,但是加载比较慢,获取对象比价快


恶汉模式是线程安全的,再类创建好一个静态对象提供给系统使用,懒汉模式在创建对象是不加上synchronized会导致对象的访问不是线程安全的

从实现方式来讲他们最他的区别就是懒汉式是延时加载,是在需要要的时候才创建对象,而饿汉式在虚拟机启动的时候就会创建

应用场景

懒汉式特点是延时加载,比如配置文件,采用懒汉式的方式

18:类加载机制有了解吗?

1:什么是类加载

当程序要使用某个类时。如果该类还未被加载到内存中,则系统会通过类的加载,;类的连接,;类的初始化这三个步骤来对类进行初始化,如果不出现意外,jvm将会连续完成这三个步骤,所以有时也把这三个步骤统称为类加载或者类初始化

2:类的加载

javaWeb面试题

1:cookie和session的区别与联系

核心解析:

1:cookie数据存放在客户的浏览器上,session数据放在服务器上

2:很多浏览器都限制一个站点最多保存20个cookie,单个保存的数据不能超过4K

3:cookie并不安全,别人可以分析存放在本地的cookie并进行cookie欺骗,考虑到安全应当使用session

4:可以考虑将登陆信息等重要信息存放为session,其他信息如果需要保存,可以放在cookie中

5:session会在一定时间保存在服务器上,当访问增多,会比较占用你的服务的性能,考虑到减轻服务器性能方面,应当把不是用户敏感的信息保存到csookie。

6:session会在浏览器关闭或者一段时间内销毁,也可以通过setMaxInactveInterval(int)方法进行设置,或者通过invalidate()方法强制结束当前会话。cookie可以通过setMaxAge(int)方法设置缓存存在客户端的时间。

7:一般情况下,session生成的session都是保存在cookie中。

总结:

cookie:在客户端保存数据,不安全。只能保存字符串,且是少量数据

session:在服务器端保存数据,安全。可以保存对象数据,数据无限制

问题扩展:

cookie被用户禁用怎么办?可以使用URL地址重写是对客户端不支持Cookie的解决方案。URL地址重写的原理是将该用户Session的id信息重写到URL地址中。服务器能够解析重写后URL获取sessiondeid。这样即使客户端不支持Cookie,也可以使用session来记录用户状态。

2:在Http请求中。什么情况下我们会选择post方式而非get?反之也是如何考虑的?

GET一般用于获取和查询资源信息,指定的资源经服务器端解析后返回响应内容,必要时,可以将查询字符串参数追加到URL末尾,一遍将信息发送给服务器。 查询请求参数不安全,提交的数据量小

POST一般用于更新资源信息,通常会用来传输实体的本体,用GET方法也可以传输实体的主体,但一般不用GET方法进行传输,而是用POST方法,虽然GET方法和POST方法很相似,但是POST的主要目的并不是获取形影的主体内容。

问题扩展:

http协议其他的请求方式?

head:获得报文首部。GET方法有实体,head方法无实体

put:传输文件,就想ftp协议的文件上传一样,要求在请求报文的主体中包含文件内容,然后保存在请求URL指定的位置,存在安全问题,一般不用。

delete:删除文件或资源,与put方法相反,按URL删除指定资源

opttons:询问支持的方式,客户端询问服务器可以提交麻斜请求方法。

trace:追踪路径,让WEB服务器端将之前的请求通信还给客户端的方法。

connect:要求用隧道协议连接代理,实现用隧道协议进行通信。

GET方法和post方法本质上的连接?

1:GET方法用于信息获取,它是安全的(安全:指非修改信息,如数据库方面的信息),而POST方法是用于修改服务器上的资源的请求;

2:GET请求的数据会附在URL之后,而POST方法提交的数据则放置在HTTp报文实体的主体里,所以post方法的安全性比GET方法要高;

3:GET方法传输的数据量一般限制在2KB,而Chrome,FierFox浏览器理论上对于URL是没有限制的,它真正的限制取决于操作系统本身,POST方法对于数据大小是无限制的,真正影响到数据大小的是服务器处理程序的能力。

3:jsp的九大内置对象及作用对象分别是什么

九大内置对象

out:web浏览器输出信息,并管理应用服务器上的输出缓冲区,常用方法是prine();作用域是page;

request:代表客户端的请求信息。

response:代表对客户端的响应。

session:由服务器自动创建的与用户请求相关的对话–对话;

application:将信息保存在服务器中,直到服务关闭,保存的信息在整个过程中都有效

pageContext:去的任何范围的参数,以上对象的参数都可以获取。

page:代表jsp本身,只有在jsp页面内才合法;

config:取得服务器的配置信息;

exception:显示异常信息;

四大作用域:

page当前页面有效

request当前请求中有效

session:会话中有效

application所有应用程序中有效

4:servlet的生命周期及常用方法

生命周期:

实例化,web容器实例化servlet实例

初始化,容器调用init()方法。

服务,客户端请求serlvet时,容器调用service()方法

销毁,结束服务,调用destroy()方法

垃圾回收

常用方法:

1:init()方法

在Servlet的生命周期中,仅执行一次init()方法,它是在服务器装入Servlet是执行的,可以配置服务器,以在启动服务器或客户机首次访问Serclet时装入Servlet。无论有多少客户机访问Servlet,都不会重复执行init()

2:service()方法

它是servlet的核心,每当一个客户请求一个HttpServlet对象,该对象的Service()方法就要调用,而且传递给这个方法一个“请求”(ServletRequest)对象和一个“响应“(ServletResponse)对象作为参数,在HttpServlet中已存在Service()方法。默认的服务功能是调用与Http请求的方法相应的do功能。

3:destory()方法

仅执行一次,在服务器端停止且卸载Servlet时执行该方法。

5:转发和重定向的区别

1:请求次数不同

重定向是浏览器向服务器发送一个请求并收到响应后再次向一个新地址发出请求,转发是服务器收到请求后为了完成响应跳转到一个新的地址;重定向至少请求两次,转发请求一次;

2:地址栏不一样

重定向地址栏会发生变化,转发地址栏不会发生变化;

3:是否共享数据

重定向两次请求不共享数据,转发一次请求共享数据(在request级别使用信息共享,使用重定向必然出错);

4:跳转限制

重定向可以跳转到任意URL,转发只能跳转本站点资源

5:发生行为不同

重定向是客户端行为,转发是服务器端行为;

6:ajax书写方式及内部主要参数都有哪些

1:同步异步

同步请求:整个页面刷新

异步请求:页面的局部刷新

2:使用$.ajax() $.getlson()

3:主要参数:

1:url: 要求为string类型的参数,发送请求的地址。

2:Data:要求为 object或stirng类型,发送到服务器的数据。

3:Type:要求为 Stirng类型,请求方式post或get。

4:DataType: 要求为String类型,预期服务器返回的数据类型。

5:Timeout: 要求为number类型,设置请求超时时间(亳秒)。

6:Asyne: 要求为boolean.类型,异步为true (默认),同步为false。

7:Cache: 要求为boolean类型,默认为true,是否从浏览器缓存中加载信息。

8:BeforeSend: 要求为function类型的参数。例如添加自定义HTTP头

7:Jquery常用选择器都有哪些

1:jquery的基本选择器
  • id选择器
    $("#myElement");
    选择id值等于myElement的元素,id值不能重复在文档中只能有一个id值是myElement所以得到的是唯一元素
  • 标签名选择器
    $(“div”);
    择所有的div标签元素,返回div元素数组
  • Class选择器
    $(".myClass");
    选择使用myClass类的css的所有元素
  • 通配符选择器
    $("*")
    选择文档中的所有的元素,可以运用多种的选择方式进行联合选择
2:常用的选择器
  1. 群组选择器
    $(“div,span”)
    使用逗号对选择器进行分隔
  2. 后代选择器
    $("#main *")
    选择id值为main的所有的后代元素
  3. 子代选择器
    $(“div>span”)
    选择div标签的所有子代span元素
  4. 相邻选择器
    $(“label + input”)
    $(“label”).next(“input”)
    选择所有的label元素的下一个input元素节点,经测试选择器返回的是label标签后面直接跟一个input标签的所有input标签元素
  5. 兄弟选择器
    $("#prev ~ div")
    $("#prev").nextAll(“div”)
    同胞选择器,该选择器返回的为id为prev的标签元素的所有的属于同一个父元素的div标签
  6. 从id是prev的元素开始向下选择兄弟元素到div元素之前为止
    $("#prev").nextUntil(“div”)
  7. 获取id是prev的上一个兄弟元素是div的元素
    $("#prev").prev(“div”)
  8. 获取id是prev的上所有兄弟元素是div的元素
    $("#prev").prevAll(“div”)
  9. 从id是prev的元素开始向上选择兄弟元素到div元素之前为止
    $("#prev").prevUntil(“div”)
  10. 根据id是prev的元素所有的上下的兄弟元素中是div
    $("#prev").siblings(“div”)

8:jsp和servlet的之间的联系和区别

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WxmpmRZm-1607944823070)(C:\Users\PC\AppData\Local\Temp\1607862660719.png)]

9:ajax提交请求默认是异步还是同步,怎么改成同步?

默认提交方式是异步提交,这样做的好处就是能够通过局部刷新的方式提高用户的体验,同时还能节省资料,减少数据库的压力,改成同步的方法就是将async的默认值改成false,一般都是true或者不写,如果改成false就会失去ajax的本身作用

10:你的项目中使用过哪些jstl标签?

项目中主要使用了JSTL的核心标签库,包括**< c:if>、< c:choose>、< c: when>、< c: otherwise>、< c:forEach>等**,主要用于构造循环和分支结构以控制显示逻辑。虽然JSTL标签库提供了core、sql、fmt、xml等标签库,但是实际开发中建议只使 用核心标签库(core),而且最好只使用分支和循环标签并辅以表达式语言(EL),这样才能真正做到数据显示和业务逻辑的分离,这才是最佳实践。

11:jsp常用的动作标签及作用?

JSP共有以下6种基本动作

jsp:include:在页面被请求的时候引入一个文件。

jsp:useBean:寻找或者实例化一个JavaBean。

jsp:setProperty:设置JavaBean的属性。

jsp:getProperty:输出某个JavaBean的属性。

jsp:forward:把请求转到一个新的页面。

jsp:plugin:根据浏览器类型为Java插件生成OBJECT或EMBED标记

12:jsp四大作用域及请求范围

所谓“作用域”就是“信息共享的范围”,也就是说一个信息能够在多大的范围内有效。4个JSP内置对象的作用域分别为:application、session、request、page 。JSP内置对象作用域表如下:

名称

作用域

application

在所有应用程序中有效

session

在当前会话中有效

request

在当前请求中有效

page

在当前页面有效

application 作用域

如果把变量放到application里,就说明它的作用域是application,它的有效范围是整个应用。 整个应用是指从应用启动,到应用结束。

session作用域

同一浏览器对服务器进行多次访问,在这多次访问之间传递信息,就是session作用域的体现。如果把变量放到session里,就说明它的作用域是session,它的有效范围是当前会话。所谓当前会话,就是指从用户打开浏览器开始,到用户关闭浏览器这中间的过程。

request作用域

如果把变量放到request里,就说明它的作用域是request,它的有效范围是当前请求周期。

page作用域

如果把变量放到pageContext里,就说明它的作用域是page,它的有效范围只在当前jsp页面里。

13:如何防止表单重复提交问题

平时开发的项目中可能会出现下面这些情况:

  1. 由于用户误操作,多次点击表单提交按钮。
  2. 由于网速等原因造成页面卡顿,用户重复刷新提交页面。
  3. 黑客或恶意用户使用postman等工具重复恶意提交表单(攻击网站)。
    这些情况都会导致表单重复提交,造成数据重复,增加服务器负载,严重甚至会造成服务器宕机。因此有效防止表单重复提交有一定的必要性。
1.通过JavaScript屏蔽提交按钮(不推荐)

通过js代码,当用户点击提交按钮后,屏蔽提交按钮使用户无法点击提交按钮或点击无效,从而实现防止表单重复提交。

ps:js代码很容易被绕过。比如用户通过刷新页面方式,或使用postman等工具绕过前段页面仍能重复提交表单。因此不推荐此方法。

2.给数据库增加唯一键约束(简单粗暴)

在数据库建表的时候在ID字段添加主键约束,用户名、邮箱、电话等字段加唯一性约束。确保数据库只可以添加一条数据。

数据库加唯一性约束sql:

alter table tableName_xxx add unique key uniq_xxx(field1, field2)

通过数据库加唯一键约束能有效避免数据库重复插入相同数据。但无法阻止恶意用户重复提交表单(攻击网站),服务器大量执行sql插入语句,增加服务器和数据库负荷。

3.利用Session防止表单重复提交(推荐)

服务器返回表单页面时,会先生成一个subToken保存于session,并把该subToen传给表单页面。当表单提交时会带上subToken,服务器拦截器Interceptor会拦截该请求,拦截器判断session保存的subToken和表单提交subToken是否一致。若不一致或session的subToken为空或表单未携带subToken则不通过。

首次提交表单时session的subToken与表单携带的subToken一致走正常流程,然后拦截器内会删除session保存的subToken。当再次提交表单时由于session的subToken为空则不通过。从而实现了防止表单重复提交。

4.使用AOP自定义切入实现
  1. 自定义防止重复提交标记(@AvoidRepeatableCommit)。
  2. 对需要防止重复提交的Congtroller里的mapping方法加上该注解。
  3. 新增Aspect切入点,为@AvoidRepeatableCommit加入切入点。
  4. 每次提交表单时,Aspect都会保存当前key到reids(须设置过期时间)。
  5. 重复提交时Aspect会判断当前redis是否有该key,若有则拦截。

14:分别说出http,ftp,talnet的默认端口

HTTP 80\

FTP 20控制 21传输

TELNET 23

15:常见的http返回状态码(200,301,302,400)

200 - 请求成功 一般用于GET与POST请

301 - 资源(网页等)被永久转移到其它URL 请求的资源已被永久的移动到新URI,返回信息会包括新的URI,浏览器会自动定向到新URI。今后任何新的请求都应使用新的URI代替

404 - 请求的资源(网页等)不存在 服务器无法根据客户端的请求找到资源(网页)。通过此代码,网站设计人员可设置"您所请求的资源无法找到"的个性页面

**500 - 内部服务器错误 ** 服务器内部错误,无法完成请求

1xx - 信息提示
  这些状态代码表示临时的响应。客户端在收到常规响应之前,应准备接收一个或多个 1xx 响应。

2xx - 成功
  这类状态代码表明服务器成功地接受了客户端请求。

3xx - 重定向
  客户端浏览器必须采取更多操作来实现请求。
  例如,浏览器可能不得不请求服务器上的不同的页面,或通过代理服务器重复该请求

4xx - 客户端错误
  发生错误,客户端似乎有问题。
  例如,客户端请求不存在的页面,客户端未提供有效的身份验证信息。

5xx - 服务器错误
  服务器由于遇到错误而不能完成该请求。

16:tcp和udp区别,你对http协议的理解

TCP(Transmission Control Protocol,传输控制协议)

TCP是一种面向连接的、可靠的、基于字节流的传输层通信协议,是专门为了在不可靠的网络中提供一个可靠的端对端字节流而设计的,面向字节流。

UDP(User Data Protocol,用户数据报协议)

是与TCP相对应的协议。它是面向非连接的协议,它不与对方建立连接,而是直接就把数据包发送过去!

Http协议的特点:

1.Http协议是无状态的,就是说每次HTTP请求都是独立的,任何两个请求之间没有什么必然的联系。但是在实际应用当中并不是完全这样的,引入了Cookie和Session机制来关联请求。

2.多次Http请求,在客户端请求网页时多数情况下并不是一次请求就能成功的,服务端首先是响应HTML页面,然后浏览器收到响应之后发现HTML页面还引用了其他的资源,例如,CSS,JS文件,图片等等,还会自动发送HTTP请求这些需要的资源。现在的HTTP版本支持管道机制,可以同时请求和响应多个请求,大大提高了效率。

3.基于TCP协议,HTTP协议目的是规定客户端和服务端数据传输的格式和数据交互行为,并不负责数据传输的细节。底层是基于TCP实现的。现在使用的版本当中是默认持久连接的,也就是多次HTTP请求使用一个TCP连接。

区别:

TCP

UDP

是否连接

面向连接

面向非连接

传输可靠性

可靠

不可靠

应用场合

传输大量的数据,对可靠性要求较高的场合

传送少量数据、对可靠性要求不高的场景

速度



1) TCP是面向连接的,可靠性高;UDP是基于非连接的,可靠性低

2) 由于TCP是连接的通信,需要有三次握手、重新确认等连接过程,会有延时,实时性差,同时过程复杂,也使其易于攻击;UDP没有建立连接的过程,因而实时性较强,也稍安全

3) 在传输相同大小的数据时,TCP首部开销20字节;UDP首部开销8字节,TCP报头比UDP复杂,故实际包含的用户数据较少。TCP在IP协议的基础上添加了序号机制、确认机制、超时重传机制等,保证了传输的可靠性,不会出现丢包或乱序,而UDP有丢包,故TCP开销大,UDP开销较小

4) 每条TCP连接只能时点到点的;UDP支持一对一、一对多、多对一、多对多的交互通信

17:json数据的格式是什么?

JSON语法格式:

方括号:保存数组

花括号:保存对象

逗号:分割数据

键值对(key – value):标识对象

其中,key必须为string类型,value可以是任何基本类型、对象或者数据

JSON的数据结构有:

Object — 对象

Array — 数组

string、number、true、false、null — 基本数据类型

框架面试题

1:Spring是如何管理事务的,事务管理机制?以及隔离级别

Spring事务的本质其实就是数据库对事务的支持,没有数据库的事务支持,spring是无法提供事务功能的。真正的数据库层的事务提交和回滚是通过binlog或者redo log实现的。

事务管理的两种方式

1:编程式事务管理:使用TransactionTemplate

2:声明式事务管理:建立在aop之上,其本质是通过AOP功能,对方法前后进行拦截,将事务处理的功能编织到拦截的方法中,也就是在目标方法开始之前加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。

隔离级别:

1:脏读:允许读取未提交的信息

原因:Read uncommitted

解决方案: (表级读锁)

2不可重复读:读取过程中单个数据发生了变化

解决方案: Repeatable read (行级写锁)

3:幻读:读取过程中数据条目发生了变化

解决方案: Serializable(表级写锁)

2:SpringAOP的实现原理

SpringAOP的实现原理有两种方式,jdk动态代理和cglib动态代理

jdk动态代理:通过反射来接收被代理的类,但是被代理的类必须实现接口,核心是InvocationHandler和Proxy类。

cglib动态代理的类一般是没有实现接口的类,cglib是一个代码生成的类库,可以在运行时动态生成某个类的子类,所以,cglib是通过继承的方式做的动态代理,因此如果某个类别标记为final,南无他是无法使用CGLIB做动态代理的。

AOP能做什么:

1:降低模块之间的耦合度

2:使系统容易扩展

3:避免修改业务代码,避免引入重复代码,更好的代码复用

AOP怎么用:

1:前置通知:某方法调用之前发出通知

2:后置方法:某方法完成之后发出通知

3:返回后方法:方法正常返回后,调用通知,在方法调用后,正常退出发出通知

4:异常通知:抛出异常后通知(After,throwing,advice):在方法抛出异常退出时执行的通知。在方法调用时,异常退出发出通知

5:环绕通知:通知包裹在被通知的方法的周围知.

结合项目中使用

举例:项目中日志的处理和事务的处理

3:IOC和DI是什么?

1:IOC(控制反转)

全称为:Inverse of control。从字面上理解就是控制反转,将对自身对象中的一个内置对象的控制反转,反转之后不在有自己本身的对象进行控制这个内置对象的创建,而是由第三方系统去控制这个内置对象的创建,简单来说就是把本来类内部控制的对象,反转到类外部进行创建后注入,不在有类本身进行控制,这就是IOC的本质

2:DI(依赖注入)

全称为Dependency In jection ,意思是自身对象中的内置对象是通过注入的方式进行创建。

3:IOC和DI的关系

ioc就是容器,di就是注入这一行为,那么di确实就是ioc的具体功能的实现 。而ioc则是di发挥的平台和空间。所以说,ioc和di即使相辅相成的搭档,最重要的是。他们都是为了实现解耦而服务的

4:DI是如何实现的?

依赖注入可以通过settrt方法注入,构造器注入和接口注入三种方式来实现,Spring支持setter注入和构造器注入,通常使用构造器注入来注入必须的依赖关系,对于可选的依赖关系,则setter注入是更好的的选择,setter注入需要提供无参构造器或者无参的静态工厂来创建对象。

4:Spring中用到了那些设计模式?

1:工厂模式

这个很明显,在各种BeanFactory以及ApplicationCotext创建中都用到了

2:模板模式

这个也很明显,在各种BeanFactory以及ApplicationContext实现中也都用到了

3:代理模式

在AOP实现中用到了JDK的动态代理

4:单例模式

这个比如在创建bean的时候

5:策略模式

在Spring中,我们可以使用jdbcTemlate实现对数据库的CRUD操作,而在查询时我们可能会用到RowMapper接口以及spring提供的一个BeanPropertyRowMapper的实现类。RowMapper接口就是规范,而我们根据实际业务需求编写每个实现类,都是一个达成目标的策略

6:观察者模式

spring在javaEE应用中创建的WEBapplicationContext时,是通过一个ContextLoaderListener监听器实现的。监听器就是观察者模式的具体体现

7:适配器模式

在spring——framework中提供了spring mvc的开发包。我们在用springmvc中,它实现控制器方式有很多种。例如我们常用的使用@Controller注解,还有实现Controller接口或者实现HttpRequestHandler接口等等。而在DispatcherServlet中如何处理这三种不同的控制器呢,用到了适配器。用到了对于不同的实现方式适配。

5:Spring中Bean的作用域有哪些?

1:作用域包括:

1:singleton(单例模式)

使用该属性定义Bean时,IOC容器仅创建一个bean实例,IOC容器每次返回的事同一个Bean、实例

2:prototype(原型模式)

使用该属性定义Bean时,ioc容器仅创建一个Bean实例,ioc容器每次返回的是同一个Bean实例

3:request(http请求)

该属性仅对Http请求产生作用,使用该属性定义Bean是,每次HTTP请求都会创建一个新的Bean,适用于WebApplicationContext环境

4:session(会话)

该属性仅对于Http Session,同一个Session共享一个Bean实例。不同于Session使用不同的实例

5:global——session(全局会话,已删除)

该属性仅用于HttpSession,通session作用域不同的是,所有的session使用不同的实例

2:Bean的生命周期

在实际开发中,我们一般用的就是单例模式和原型模式。

单例模式生命周期于容器相同

原型模式生命周期,是每次使用时创建新的对象,用完等待垃圾回收机制回收

6:spring框架实现实例化和依赖注入的方式分别是什么?

1:Spring框架实现实例化的三种方式:

1:使用构造器实例化Bean

Spring IOC容器即能使默认空构造器也能使用有参构造器两种方式创建Bean

2:使用静态工厂方式实例化Bean

使用这种方式除了指定必须的class属性,还要指定factory——method属性来指定实例化Bean的方法,该方法必须是静态方法,而且使用静态工厂方法也允许指定方法参数,Spring IOC容器将调用此属性指定的方法来获取Bean

3:使用实例化工厂方法实例化Bean

使用这种方式不能指定calss属性,此时必须使用Factory——brean属性来指定工厂Beand的ID,factory-method属性指定实例化Bean的方法,而且使用实例工厂方法允许指定参数,方式和指定构造器方式一样。

2:依赖注入的方式

依赖注入是spring协调不同Bean实例之间的合作而提供的一种工作机制,在确保Bean实例之间合作的同时,并能保持每个Bean的相对独立性。

1:基于构造函数的注入

2:基于set方法注入

3:基于自动装配的注入

4:基于注解的依赖注入

7:springmvc的执行流程

(1)用户发送请求至前端控制器 DispatcherServlet;
(2) DispatcherServlet 收到请求后,调用 HandlerMapping 处理器映射器,请求获取
Handle;
(3)处理器映射器根据请求 url 找到具体的处理器,生成处理器对象及处理器拦截器(如果
有则生成)一并返回给 DispatcherServlet;
(4)DispatcherServlet 调用 HandlerAdapter 处理器适配器;
(5)HandlerAdapter 经过适配调用 具体处理器(Handler,也叫后端控制器);
(6)Handler 执行完成返回 ModelAndView;
(7)HandlerAdapter 将 Handler 执行结果 ModelAndView 返回给 DispatcherServlet;
(8)DispatcherServlet 将 ModelAndView 传给 ViewResolver 视图解析器进行解析;
(9)ViewResolver 解析后返回具体 View;
(10)DispatcherServlet 对 View 进行渲染视图(即将模型数据填充至视图中)
(11)DispatcherServlet 响应用户。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Vgnt6j03-1607944823073)(C:\Users\PC\AppData\Local\Temp\1607759489940.png)]

8:spring和springmvc的常用注解有哪些

@Component用于标记在一个类,表示当前类是spring的一个组件,会进入ioc容器。它有三个衍生注解

@Controller @Service @Repository

@RequestMapping是一个用来处理请求地址映射的注解,可用于类或者方法上。用于类上,表示类中所有响应请求的方法都是以该地址作为父路径

@RequestParam用于将指定的请求参数赋值给方法中的形参

@PathVariable用于获取URL中的动态参数

@RequestBody用于读取Request请求的Body部分数据

@ResponseBody用于将Controller的方法返回的对象,用于标记在一个类上

@RestController=@Controller+@RespinseBody,用于标记在一个类上。

@Transactional写在类上用于指定当前类中的方法支持事务,写在方法上表示当前的方法支持事务

9:spring前端控制器是什么?处理器映射器是什么?

1:DispatcherServlet:前端控制器

用户请求到达前端控制器,它就相当于mvc模式中的c,DispatcherServlet是整个流程控制的中心,由它调用其它组件处理用户的请求,DispatcherServlet的存在降低了组件之间的耦合性

2:Handlermapping:处理器映射器

HandlerMapping:负责根据用户请求找到Handler即处理器,springmvc提供了不同的映射器实现不同的映射方式,例如L配置文件,实现接口方式,注解方式等

3:Handler:处理器

Handler是继DisPatcherServlet前端控制器的后端控制器,在DispatcherServlet的控制下Handler对具体用户请求进行处理。由于Handler涉及到具体的用户业务请求,所以一般情况需要程序员根据业务需求开发Handler

4:HandlerAdapter:处理器适配器

通过HandlerAdapter对处理器进行执行,这是适配器模式的应用,通过扩展适配器可以对更多类型的处理器进行执行。

5:ViewResolver:视图解析器

ViewResolver负责将处理结果生成view视图,ViewResolver首先根据逻辑视图名解析成物理视图名即具体的页面地址,在生成view视图对象,最后对view进行渲染将处理结果通过页面展示用户

6:View:视图

SpringMVC框架提供了很多的View视图类型的支持,包括:jstView。freemarkerView。pdfView等。我们最常用的视图就是jsp。一般情况下需要通过页面标签或者页面模板技术将模型数据通过页面展示给用户,需要由程序员根据业务需求开发具体的页面

10:springmvc获取表单数据的几种方式

1:直接把表单的参数写在Controller相应的方法的形参中

2:通过HttpServletRequest接收

3:通过一个bean来接收

4:通过json数据来接收

11:ssm架构的整合流程

创建maven web项目 导入spring,springmvc,mybatis,mysql坐标

数据库资料:建库建表

配置文件

12:mybatis中#和$传参的区别

1:使用#{}传入参数时,sql语句解析借助log4j输出日志看到的sql语句是

select*from table name where column name=?

2:而使用${}传入参数时,借助log4j打印出来的字符串拼接。所以#{}传参能防止sql注入。

3:项目中经常使用的是#,因为这样能够有效防止申请sql注入。

SQL注入:SQL注入即是指web应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步得到相应的数据信息。

13:mybatis中的动态sql语句是什么?

1:所谓sql的动态和静态,是指sql语句在何时被编译和执行,二者都是用在sql嵌入式编程中的,这里所说的嵌入式是指将sql语句嵌入到到高级语言中,而不是针对于单片机的那种嵌入式编程

2:sql语句的主体结构,在编译时尚无法确定,只有等到程序运行起来,在执行的过程中才能确定,这种sql叫做动态语句

3:静态sql语句的编译是在应用程序运行前进行的,编译的结果会存储早数据库内部。而程序运行时数据库将直接执行编译好的sql语句,降低运行时的开销。

4:Mybatis中用于实现动态sql的元素主要有:if,where,foreach

5:另外还要注意一点,在sql中如果某些参数没有确定,如“select*from user where age>?”这种语句是静态sql,不是动态sql,虽然个别参数的值不知道,但整个sql的结构已经确定,数据库是可以将他编译的,在执行阶段只需将个别参数的值补充进来即可

应用场景:

实际开发中动态sql语句的使用场景非常多,最明显的例子就是多条件查询,其中查询的条件每次不确定有哪些时。

14:mybatis映射配置文件的编写规范

1:xml映射文件中的namespace与mapper接口的全类名形同

2:mapper接口方法名和xml映射文件中定义的每个statement的id相同

3:mapper接口方法的输入参数类型和xml映射文件中定义的每个sql的parameterType的类型相同。

4:mapper接口方法的输出参数类型和xml映射文件定义的每个sql的resultType的类型相同

5:Mybatis中的mapper动态代理是不支持方法的重载的Dao接口里的方法,因为是全类名+方法名的保存和寻找策略。

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

应用场景:

实际开发中如果我们持久层选用了mybatis框架,那么通常会采用动态代理dao的方式,从而减少对dao的实现类开发。那么此时就必须mapper映射的编写规范

15:mybatis的执行过程分析

1:读取配置文件

2:创建构建者对象

3:创建工厂对象

4:创建sqlsession对象使用sqlsession创建dao层的代理实现类

5:使用代理实现类实现dao里面的功能

底层还是实现的原生JDBC的操作

16:说说熟悉的设计模式以及应用场景

1:开闭原则:对修改关闭,对扩展开放

2:单一职责:各司其职

常用设计模式

1:单例模式

保证一个类仅有一个实例,并提供一个全局访问点,比如一些配置文件或者管理类可以设计为单例,我们常用的线程池也是单例的。

2:模板方法

在定义好的算法股骨架下,允许子类为一个或多个步骤提供实现,一次性实现算法的不变部分,将=可变部分留给子类实现,当子类实现代码逻辑雷同是,可以使用此设计者模式。

3:工厂方法

创建对象需要大量的重复代码时,通过子类实现方法来创建对象,如Spring中通过工厂模式将创建对象。如Spring中通过工厂模式将创建对象的任务交给容器管理

4:建造者模式

将复杂对象的构建和表示分离,适用于流程固定,但是顺序不一定固定的场景。如需要一个对象多次给不同的属性赋值,可以使用链式调用传参,最后生成对象。

另外,如策略模式,观察者模式。模板方法模式,foreach中的迭代器模式,spring中ASM的访问者模式,动态代理等都有一些了解。

17:两种动态代理的区别?

动态代理:

特点:字节码文件随用随创建,随用随加载

分类:

基于接口的动态代理

基于子类的动态代理

1:基于接口的动态代理:

要求:被代理类最少实现一个接口

提供方:JDK官方

涉及类:Proxy

创建代理对象的方法:newProxyInsrance

方法中的参数:

1:calssLoader:类加载器。

负责加载代理对象的字节码文件和被代理对象使用相同的类加载器。(固定写法)

2:class【】:字节码数组

负责让生成的代理对象具有和被代理对象相同的方法。写什么要看被代理对象是一个接口还是实现类。如果是一个接口:new Class【】{接口}。如果是一个实现类:.getcalss().getInterfaces()

3:InvocationHandler:一个接口,需要我们提供该接口的实现。作用适用于对方法的增强。增强的代码,谁用谁写。写的是一个接口的实现类。通常是一个匿名内部类,但是不绝对。

2:基于子类的动态代理:

要求:需要导入cglib的坐标,被代理类不能是最终类。(不能被final修饰)

提供者;cglib(第三方)

涉及类:Enhancer

创建代理对象的方法:create

方法中的参数:

Calss:字节码对象。用于加载代理对象字节码的。写的是被代理对象的字节码。是固定写法

Callback:如何代理。提供增强代码的。它是个接口,需要自己写实现。

该接口没有方法,需要用它的子接口MethodInterceptor

创建对象需要大量的重复代码时,通过子类实现方法来创建对象,如Spring中通过工厂模式将创建对象。如Spring中通过工厂模式将创建对象的任务交给容器管理

4:建造者模式

将复杂对象的构建和表示分离,适用于流程固定,但是顺序不一定固定的场景。如需要一个对象多次给不同的属性赋值,可以使用链式调用传参,最后生成对象。

另外,如策略模式,观察者模式。模板方法模式,foreach中的迭代器模式,spring中ASM的访问者模式,动态代理等都有一些了解。

17:两种动态代理的区别?

动态代理:

特点:字节码文件随用随创建,随用随加载

分类:

基于接口的动态代理

基于子类的动态代理

1:基于接口的动态代理:

要求:被代理类最少实现一个接口

提供方:JDK官方

涉及类:Proxy

创建代理对象的方法:newProxyInsrance

方法中的参数:

1:calssLoader:类加载器。

负责加载代理对象的字节码文件和被代理对象使用相同的类加载器。(固定写法)

2:class【】:字节码数组

负责让生成的代理对象具有和被代理对象相同的方法。写什么要看被代理对象是一个接口还是实现类。如果是一个接口:new Class【】{接口}。如果是一个实现类:.getcalss().getInterfaces()

3:InvocationHandler:一个接口,需要我们提供该接口的实现。作用适用于对方法的增强。增强的代码,谁用谁写。写的是一个接口的实现类。通常是一个匿名内部类,但是不绝对。

2:基于子类的动态代理:

要求:需要导入cglib的坐标,被代理类不能是最终类。(不能被final修饰)

提供者;cglib(第三方)

涉及类:Enhancer

创建代理对象的方法:create

方法中的参数:

Calss:字节码对象。用于加载代理对象字节码的。写的是被代理对象的字节码。是固定写法

Callback:如何代理。提供增强代码的。它是个接口,需要自己写实现。

该接口没有方法,需要用它的子接口MethodInterceptor