Java面试题 -其他框架

1. 描述⼀下Hibernate的三个状态?

a. transient(瞬时状态):new出来⼀个对象,还没被保存到数据库中
b. persistent(持久化状态):对象已经保存到数据库中并且在hibernate session也存在该对象
c. detached(离线状态):对象在数据库中存在,hibernate session不存在

2. struts⼯作流程

在这里插入图片描述
1、客户端浏览器发出HTTP请求。
2、根据web.xml配置,该请求被FilterDispatcher接收。
3、根据struts.xml配置,找到需要调⽤的Action类和⽅法, 并通过IoC⽅式,将值注⼊给Aciton。
4、Action调⽤业务逻辑组件处理业务逻辑,这⼀步包含表单验证。
5、Action执⾏完毕,根据struts.xml中的配置找到对应的返回结果result,并跳转到相应⻚⾯。
6、返回HTTP响应到客户端浏览器。

3. Hibernate对⼀⼆级缓存的使⽤, Lazy-Load的理解

a. ⼀级缓存:hibernate的⼀级缓存是由session提供的,因此它只存在session的⽣命周期中。也就是说session关闭的时候该session所管理的⼀级缓存也随之被清除。hibernate的⼀级缓存是session所内置的,默认开启,不能被卸载,也不能进⾏任何配置。在缓存中的对象,具有持久性,session对象负责管理.⼀级缓存的优点是使⽤同⼀个session对象多次查询
同⼀个数据对象,仅对数据库查询⼀次。⼀级缓存采⽤的是Key-Value的MAP⽅式来实现的。在缓存实体对象时,对象的主关键字ID是MAP的Key,实体对象就是对象的值。所以说⼀级缓存是以实体对象为单位进⾏存储的。访问的时候使⽤的是主键关键字ID。⼀级缓存使⽤的是⾃动维护的功能。但可以通过session提供的⼿动⽅法对⼀级缓存的管理进⾏⼿动⼲预。evict()⽅法⽤于将某个对象从session的⼀级缓存中清除。clear()⽅法⽤于将session缓存中的⽅法全部清除。

b. ⼆级缓存:⼆级缓存的实现原理与⼀级缓存是⼀样的。也是通过Key-Value的Map来实现对对象的缓存。⼆级缓存是作⽤在SessionFactory范围内的。因此它可被所有的Session对象所共享。需要注意的是放⼊缓存中的数据不能有第三⽅的应⽤对数据进⾏修改。⼆级缓存默认关闭,需要程序员⼿动开启,默认为ehcache实现.

c. 懒加载:当⽤到数据的时候才向数据库查询,这就是hibernate的懒加载特性。延迟加载策略能避免加载应⽤程序不需要访问的关联对象,以提⾼应⽤程序的性能。

4. mybatis如何实现批量提交?

a. 通过标签:

insert into sys_user_role
	( `user_id`, `role_id`) 
values
<foreach collection="roleIdList" item="item" index="index" separator=","> 
	(  #{userId}, #{item} )
</foreach>

b. 通过ExecutorType.BATCH:
在这里插入图片描述

5. session机制?

  1. session是服务器的⽣成,并传⾄客户端浏览器,后续请求,都会通过URL重写传⾄服务器进⾏session⽐较.
  2. session是基于cookie
  3. session可以保存⽤户信息,但cookie如果浏览器被禁⽤,则⽆法保存⽤户信息
  4. 如果浏览器禁⽤会话cookie,则每次请求都⽆法将第⼀次请求获得的sessionId传⾄后台服务器.所以每次请求刷新⻚⾯服务器都会⽣成新的sessionid给到浏览器
  5. 因HTTP协议为⽆状态的协议(⼀旦数据交互完毕,客户端和服务端的连接就会关闭,再次交换数据时需要建⽴新的连接),需要通过session或者cookie保存和跟踪⽤户信息
  6. sessionID放在浏览器客户端cookie,其它信息放在服务器内存中,也可以做持久化管理memcached、redis中;

6. Struts2表单重复提交问题(token拦截器)

  1. 访问⻚⾯前保存token(服务器后台⽣成的⼀串序列时间串放到session中),并传⾄前台jsp⻚⾯中的隐藏域

  2. 提交时验证token,将前台的隐藏的token传⾄后台进⾏验证是否⼀致,提交随机⽣成新的token,可以防⽌重复提交;

7.Shiro

定义:
apache shiro是java的⼀个安全框架,简单易⽤,基本功能有:认证、授权、加密、会话管理、与Web集成、缓存等。Shiro不会去维护⽤户、维护权限;这些需要我们⾃⼰去设计/提供;然后通过相应的接⼝注⼊给Shiro即可(五张表)。

功能点:
在这里插入图片描述
Authentication:身份认证/登录,验证⽤户是不是拥有相应的身份;
Authorization:授权,即权限验证,验证某个已认证的⽤户是否拥有某个权限;即判断⽤户是否能做事情,常⻅的如:验证某个⽤户是否拥有某个⻆⾊。或者细粒度的验证某个⽤户对某个资源是否具有某个权限;
Session Manager:会话管理,即⽤户登录后就是⼀次会话,在没有退出之前,它的所有信息都在会话中;会话可以是普通JavaSE环境的,也可以是如Web环境的;
Cryptography:加密,保护数据的安全性,如密码加密存储到数据库,⽽不是明⽂存储;
Web Support:Web⽀持,可以⾮常容易的集成到Web环境;
Caching:缓存,⽐如⽤户登录后,其⽤户信息、拥有的⻆⾊/权限不必每次去查,这样可以提⾼效率;
Concurrency:shiro⽀持多线程应⽤的并发验证,即如在⼀个线程中开启另⼀个线程,能把权限⾃动传播过去;
Testing:提供测试⽀持;
Run As:允许⼀个⽤户假装为另⼀个⽤户(如果他们允许)的身份进⾏访问;
Remember Me:记住我,这个是⾮常常⻅的功能,即⼀次登录后,下次再来的话不⽤登录了。

⼯作流程:

  1. 应⽤代码通过Subject(主体,代表当前”⽤户")来进⾏认证和授权,⽽Subject⼜委托给SecurityManager(安全管理器,shiro核⼼);
  2. 我们需要给Shiro的SecurityManager注⼊Realm(域,Shiro从Realm获取安全数据(如⽤户、⻆⾊、权限)),从⽽让SecurityManager能得到合法的⽤户及其权限进⾏判断。

8. Tomcat Filter过滤器责任链模式,过滤器拦截器区别?

责任链模式

  • 将⼀个事件处理流程分派到⼀组执⾏对象上去,这⼀组执⾏对象形成⼀个链式结构,事件处理请求在这⼀组执⾏对象上进⾏传递。

过滤器和拦截器

  1. 过滤器filter:是在java web中,你传⼊的request,response提前过滤掉⼀些信息,或者提前设置⼀些参数,然后再传⼊servlet或者struts的 action进⾏业务逻辑,⽐如过滤掉⾮法url(不是login.do的地址请求,如果⽤户没有登陆都过滤掉),或者在传⼊servlet或者 struts的action前统⼀设置字符集,或者去除掉⼀些⾮法字符;
  2. 拦截器interceptor:是在⾯向切⾯编程的就是在你的service或者⼀个⽅法,前调⽤⼀个⽅法,或者在⽅法后调⽤⼀个⽅法⽐如动态代理就是拦截器的简单实现,在你调⽤⽅法前打印出字符串(或者做其它业务逻辑的操作),也可以在你调⽤⽅法后打印出字符串,甚⾄在你抛出异常的时候做业务逻辑的操作。拦截是AOP的⼀种实现策略;

区别:

a. 拦截器是基于java的反射机制的,⽽过滤器是基于函数回调。
b. 拦截器不依赖于servlet容器,过滤器依赖与servlet容器。
c. 拦截器只能对action请求起作⽤,⽽过滤器则可以对⼏乎所有的请求起作⽤。
d. 拦截器可以访问action上下⽂、值栈⾥的对象,⽽过滤器不能访问。
e. 在action的⽣命周期中,拦截器可以多次被调⽤,⽽过滤器只能在容器初始化时被调⽤⼀次。

9. Git与Svn的区别

1、Git是分布式的,⽽Svn不是;
2、GIT把内容按元数据⽅式存储,⽽SVN是按⽂件
3、分⽀不同:git分⽀切换很⽅便;svn分⽀就是版本库的另外⼀个⽬录;
4、GIT没有⼀个全局的版本号,⽽svn有,SVN的版本号实际是任何⼀个相应时间的源代码快照。
5、GIT的内容完整性要优于SVN(GIT的内容存储使⽤的是SHA-1哈希算法。这能确保代码内容的完整性,确保在遇到磁盘故障和⽹络问题时降低对版本库的破坏。)

10. Git命令底层原理:

1.git init:使⽤git init初始化⼀个新的⽬录时,会⽣成⼀个.git的⽬录,该⽬录即为本地仓库。⼀个新初始化的本地仓库是这样的:
在这里插入图片描述

  • description⽤于GitWeb程序
  • config配置特定于该仓库的设置(还记得git config的三个配置级别么)
  • hooks放置客户端或服务端的hook脚本
  • HEAD传说中的HEAD指针,指明当前处于哪个分⽀
  • objectsGit对象存储⽬录
  • refsGit引⽤存储⽬录
  • branches放置分⽀引⽤的⽬录

其中description、config和hooks这些不在讨论中,后⽂会直接忽略。

git add:Git commit之前先要通过git add添加⽂件:
在这里插入图片描述
可以看到,多了⼀个index⽂件。并且在objects⽬录下多了⼀个9f的⽬录,其中多了⼀个
4d96d5b00d98959ea9960f069585ce42b1349a⽂件。其实9f4d96d5b00d98959ea9960f069585ce42b1349a就是⼀个Git对象,称为blob对象。

git commit:
在这里插入图片描述

11. JSP的执⾏过程:

  1. 客户端发出请求。
  2. Web容器将JSP转译成Servlet源代码。
  3. Web容器将产⽣的源代码进⾏编译。
  4. Web容器加载编译后的代码并执⾏。
  5. 把执⾏结果响应⾄客户端。

12. ZK⾼可⽤

  • ZooKeeper 运⾏期间,集群中⾄少有过半的机器保存了最新数据。集群超过半数的机器能够正常⼯作,集群就能够对外提供服务。

13. zookeeper有什么功能,选举算法如何进⾏?

选举算法 (Fast Leader(领导者选举)选举算法):

  1. server启动时默认选举⾃⼰,并向整个集群⼴播
  2. 收到消息时,通过3层判断:选举轮数,zxid,server id⼤⼩判断是否同意对⽅,如果同意,则修改⾃⼰的选票,并向集群⼴播
  3. QuorumCnxManager负责IO处理,每2个server建⽴⼀个连接,只允许id⼤的server连id⼩的server,每个server启动单独的读写线程处理,使⽤阻塞IO
  4. 默认超过半数机器同意时,则选举成功,修改⾃身状态为LEADING或FOLLOWING
  5. Obserer机器不参与选举

原理:

  • 选举结果的影响权重关系是:⾸先看数据id,数据id⼤者胜出;其次再判断leader id,leader id⼤者胜出。

举例:

假设有五台服务器组成的zookeeper集群,它们的id从1-5,同时它们都是最新启动的,也就是没有历史数据,在存放数据量这⼀点上,都是⼀样的.假设这些服务器依序启动,来看看会发⽣什么?

  1. 服务器1启动,此时只有它⼀台服务器启动了,它发出去的报没有任何响应,所以它的选举状态⼀直是LOOKING状态;
  2. 服务器2启动,它与最开始启动的服务器1进⾏通信,互相交换⾃⼰的选举结果,由于两者都没有历史数据,所以id值较⼤的服务器2胜出,但是由于没有达到超过半数以上的服务器都同意选举它(这个例⼦中的半数以上是3),所以服务器1,2还是继续保持LOOKING状态.
  3. 服务器3启动,根据前⾯的理论分析,服务器3成为服务器1,2,3中的⽼⼤,⽽与上⾯不同的是,此时有三台服务器选举了它,所以它成为了这次选举的leader.
  4. 服务器4启动,根据前⾯的分析,理论上服务器4应该是服务器1,2,3,4中最⼤的,但是由于前⾯已经有半数以上的服务器选举了服务器3,所以它只能接收当⼩弟的命了.
  5. 服务器5启动,同4⼀样,当⼩弟.

4、zookeeper管理员指南:

  • 集群中过半存活即可⽤,故集群选择奇数台机器;

14. RPC、RMI、MQ、SOAP

RPC:远程过程调⽤协议,采⽤C/S模式,分布式跨语⾔平台,更多⽤于同步调⽤,⽐如Web Service(SOAP);

RMI:远程⽅法调⽤,依赖于java远程消息交换协议,要求服务端与客户端都为java编写;每个⽅法都具有⽅法签名,只有签名匹配才可以调⽤,返回值是基本类型和对象;

MQ:队列,更多⽤于异步传输;

SOAP:最主要的⼯作是使⽤标准的XML描述了RPC的请求信息(URI/类/⽅法/参数/返回值)。理论上,SOAP就是⼀段xml,你可以通过http,smtp等发送它(复制到软盘上,叫快递公司送去也⾏?),同样SOAP也是跨语⾔的。

15. Netty⾼性能

  1. NIO异步⾮阻塞通信
  2. “零拷⻉”
  3. 内存池ByteBuf
  4. Netty提供了多种内存管理策略,通过在启动辅助类中配置相关参数,可以实现差异化的定制。
  5. ⾼效的Reactor线程模型:Reactor单线程(多线程、主从)模型,指的是所有的IO操作都在同⼀个NIO线程上⾯完成
  6. 为了尽可能提升性能,Netty采⽤了串⾏⽆锁化设计,在IO线程内部进⾏串⾏操作,避免多线程竞争导致的性能下降。表⾯上看,串⾏化设计似乎CPU利⽤率不⾼,并发程度不够。但是,通过调整NIO线程池的线程参数,可以同时启动多个串⾏化的线程并⾏运⾏,这种局部⽆锁化的串⾏线程设计相⽐⼀个队列-多个⼯作线程模型性能更优。
  7. ⾼效的序列化框架。
  8. 灵活的TCP参数配置能⼒:合理设置TCP参数在某些场景下对于性能的提升可以起到显著的效果,例如SO_RCVBUF和SO_SNDBUF。如果设置不当,对性能的影响是⾮常⼤的。

⾼效的并发编程:Netty的⾼效并发编程主要体现在如下⼏点:

  • volatile的⼤量、正确使⽤;
  • CAS和原⼦类的⼴泛使⽤;
  • 线程安全容器的使⽤;
  • 通过读写锁提升并发性能。

16. 如何保证服务的幂等性?

概念:接⼝的幂等性实际上就是接⼝可重复调⽤,在调⽤⽅多次调⽤的情况下,接⼝最终得到的结果是⼀致的。有些接⼝可以天然的实现幂等性,⽐如查询接⼝,对于查询来说,你查询⼀次和两次,对于系统来说,没有任何影响,查出的结果也是⼀样。

GET幂等:值得注意,幂等性指的是作⽤于结果⽽⾮资源本身。怎么理解呢?例如,这个HTTP GET⽅法可能会每次得到不同的返回内容,但并不影响资源。

POST⾮幂等:因为它会对资源本身产⽣影响,每次调⽤都会有新的资源产⽣,因此不满⾜幂等性。

如何保证幂等性

  1. 全局唯⼀id:如果使⽤全局唯⼀ID,就是根据业务的操作和内容⽣成⼀个全局ID,在执⾏操作前先根据这个全局唯⼀ID是否存在,来判断这个操作是否已经执⾏。如果不存在则把全局ID,存储到存储系统中,⽐如数据库、redis等。如果存在则表示该⽅法已经执⾏。从⼯程的⻆度来说,使⽤全局ID做幂等可以作为⼀个业务的基础的微服务存在,在很多的微服务中都会⽤到这样的服务,在每个微服务中都完成这样的功能,会存在⼯作量重复。另外打造⼀个⾼可靠的幂等服务还需要考虑很多问题,⽐如⼀台机器虽然把全局ID先写⼊了存储,但是在写⼊之后挂了,这就需要引⼊全局ID的超时机制。使⽤全局唯⼀ID是⼀个通⽤⽅案,可以⽀持插⼊、更新、删除业务操作。但是这个⽅案看起来很美但是实现起来⽐较麻烦,下⾯的⽅案适⽤于特定的场景,但是实现起来⽐较简单。

  2. 去重表:这种⽅法适⽤于在业务中有唯⼀标的插⼊场景中,⽐如在以上的⽀付场景中,如果⼀个订单只会⽀付⼀次,所以订单ID可以作为唯⼀标识。这时,我们就可以建⼀张去重表,并且把唯⼀标识作为唯⼀索引,在我们实现时,把创建⽀付单据和写⼊去重表,放在⼀个事务中,如果重复创建,数据库会抛出唯⼀约束异常,操作就会回滚。

  3. 插⼊或更新:这种⽅法插⼊并且有唯⼀索引的情况,⽐如我们要关联商品品类,其中商品的ID和品类的ID可以构成唯⼀索引,并且在数据表中也增加了唯⼀索引。这时就可以使⽤InsertOrUpdate操作。在mysql数据库中如下:在这里插入图片描述

  4. 多版本控制:这种⽅法适合在更新的场景中,⽐如我们要更新商品的名字,这时我们就可以在更新的接⼝中增加⼀个版本号,来做幂等:在这里插入图片描述在实现时可以如下:在这里插入图片描述

  5. 、状态机控制:这种⽅法适合在有状态机流转的情况下,⽐如就会订单的创建和付款,订单的付款肯定是在之前,这时我们可以通过在设计状态字段时,使⽤int类型,并且通过值类型的⼤⼩来做幂等,⽐如订单的创建为0,付款成功为100。付款失败为99在做状态机更新时,我们就这可以这样控制:在这里插入图片描述

17. zookeeper⼯作原理?

定义:zookeeper是⼀种为分布式应⽤所设计的⾼可⽤、⾼性能且⼀致的开源协调服务,它提供了⼀项基本服务:分布式锁服务。后来摸索出了其他使⽤⽅法:配置维护、组服务、分布式消息队列、分布式通知/协调等。

特点:

  1. 能够⽤在⼤型分布式系统中;
  2. 具有⼀致性、可⽤性、容错性,不会因为⼀个节点的错误⽽崩溃;

⽤途:(⽤户⼤型分布式系统,作协调服务⻆⾊)

  1. 分布式锁应⽤:通过对集群进⾏master选举,来解决分布式系统中的单点故障(⼀主n从,主挂全挂)。
  2. 协调服务;
  3. 注册中⼼;

术语:

  • 数据结构Znode:zookeeper数据采⽤树形层次结构,和标准⽂件系统⾮常相似,树中每个节点被称为Znode;
  • 通知机制Watcher:zookeeper可以为所有的读操作(exists()、getChilden()及getData())设置watch,watch事件是⼀次性出发器,当watch的对象状态发⽣改变时,将会触发次对象上watch所对应的事件。watch事件将被异步的发送给客户端,并且zookeeper为watch机制提供了有序的⼀致性保证。

基本流程:(分布式锁应⽤场景)

  1. 传统的⼀主n从分布式系统,容易发⽣单点故障,传统解决⽅式是增加⼀个备⽤节点,定期给主节点发送Ping包,主节点回复ack,但是如果⽹络原因ack丢失,那么会出现两个主节点,造成数据混乱。
  2. zookeeper的引⼊可以管理两个主节点,其中挂了⼀个,会将另外⼀个作为新的主节点,挂的节点回来时担任备⽤节点;

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

18. cap理论

概念:⼀个分布式系统最多只能同时满⾜⼀致性(Consistency)、可⽤性(Availability)和分区容错性(Partition tolerance)这三项中的两项。

  • ⼀致性:更新操作成功并返回客户端完成后,所有节点在同⼀时间的数据完全⼀致,所以,⼀致性,说的就是数据⼀致性。
  • 可⽤性:服务⼀直可⽤,⽽且是正常响应时间。
  • 分区容错性:分布式系统在遇到某节点或⽹络分区故障的时候,仍然能够对外提供满⾜⼀致性和可⽤性的服务。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章