笔试真题

JavaEE面试经验分享(西安**捷普网络科技有限公司)_二级缓存

JavaEE面试经验分享(西安**捷普网络科技有限公司)_java_02

JavaEE面试经验分享(西安**捷普网络科技有限公司)_zookeeper_03

JavaEE面试经验分享(西安**捷普网络科技有限公司)_zookeeper_04

JavaEE面试经验分享(西安**捷普网络科技有限公司)_二级缓存_05

 

面试过程

1: 请问 ArrayList、 HashSet、 HashMap 是线程安全的吗?如果不是我想要线程安全的集合怎么办?

我们都看过上面那些集合的源码(如果没有那就看看吧),每个方法都没有加锁,显然都是线程不安全的。话又说过来如果他们安全了也就没第二问了。

在集合中 Vector 和 HashTable 倒是线程安全的。你打开源码会发现其实就是把各自核心方法添加上了synchronized 关键字。

Collections 工具类提供了相关的 API,可以让上面那 3 个不安全的集合变为安全的。

①// Collections.synchronizedCollection(c)

②// Collections.synchronizedList(list)

③ // Collections.synchronizedMap(m)

④ // Collections.synchronizedSet(s)

上面几个函数都有对应的返回值类型,传入什么类型返回什么类型。打开源码其实实现原理非常简单,就是将集合的核心方法添加上了 synchronized 关键字。

2: 阿帕奇提供的StringUtils中 isNotEmpty 和isNotBlank的区别?

1)public static boolean isEmpty(String str)  判断某字符串是否为空,为空的标准是str==null或str.length()==0

示例:

StringUtils.isEmpty(null) ==> true

StringUtils.isEmpty("") ==> true

StringUtils.isEmpty(" ") ==> false //注意StringUtils 中空格作非空处理

StringUtils.isEmpty("  ") ==> false

StringUtils.isEmpty("bob") ==> false

StringUtils.isEmpty(" bob ") ==> false

2)public static boolean isNotEmpty(String str)  判断某字符串是否非空,等于!isEmpty(String str)

示例:

StringUtils.isNotEmpty(null) ==> false

StringUtils.isNotEmpty("") ==> false

StringUtils.isNotEmpty(" ") ==> true

StringUtils.isNotEmpty("     ") ==> true

StringUtils.isNotEmpty("bob") ==> true

StringUtils.isNotEmpty(" bob ") ==> true

3)public static boolean isBlank(String str)  判断某字符串是否为空或长度为0或由空白符(whitespace)构成

示例:

StringUtils.isBlank(null) ==> true

StringUtils.isBlank("") ==> true

StringUtils.isBlank(" ") ==> true

StringUtils.isBlank("    ") ==> true

StringUtils.isBlank("\t \n \f \r") ==> true  //对于制表符、换行符、换页符和回车符,均识为空白符

StringUtils.isBlank("\b") ==> false  //"\b"为单词边界符

StringUtils.isBlank("bob") ==> false

StringUtils.isBlank(" bob ") ==> false

4)public static boolean isNotBlank(String str)  判断某字符串是否不为空且长度不为0且不由空白符(whitespace)构成,等于!isBlank(String str)

示例:

StringUtils.isNotBlank(null) ==> false

StringUtils.isNotBlank("") ==> false

StringUtils.isNotBlank(" ") ==> false

StringUtils.isNotBlank("     ") ==> false

StringUtils.isNotBlank("\t \n \f \r") ==> false

StringUtils.isNotBlank("\b") ==> true

StringUtils.isNotBlank("bob") ==> true

StringUtils.isNotBlank(" bob ") ==> true

JavaEE面试经验分享(西安**捷普网络科技有限公司)_zookeeper_06

3: Spring 的通知是什么?有哪几种类型?

page通知是个在方法执行前或执行后要做的动作,实际上是程序执行时要通过 SpringAOP 框架触发的代码段。

Spring 切面可以应用五种类型的通知:

1) before:前置通知,在一个方法执行前被调用。

2) after: 在方法执行之后调用的通知,无论方法执行是否成功。

3) after-returning: 仅当方法成功完成后执行的通知。

4) after-throwing: 在方法抛出异常退出时执行的通知。

5) around: 在方法执行之前和之后调用的通知。

4: 简单介绍一下 Shiro 框架 ?

A:栈Apache Shiro 是 Java 的一个安全框架。使用 shiro 可以非常容易的开发出足够好的应用,其不仅可以用在 JavaSE环境,也可以用在 JavaEE 环境。 Shiro 可以帮助我们完成:认证、授权、加密、会话管理、与 Web 集成、缓存等。

三个核心组件: Subject, SecurityManager 和 Realms.

Subject:即“当前操作用户” 。但是,在 Shiro 中, Subject 这一概念并不仅仅指人,也可以是第三方进程、后台帐户(Daemon Account)或其他类似事物。它仅仅意味着“当前跟软件交互的东西” 。但考虑到大多数目的和用途,你可以把它认为是 Shiro 的“用户” 概念。

Subject 代表了当前用户的安全操作, SecurityManager 则管理所有用户的安全操作。

SecurityManager:它是 Shiro 框架的核心,典型的 Facade 模式, Shiro 通过SecurityManager 来管理内部组件实例,并通过它来提供安全管理的各种服务。

Realm: Realm 充当了 Shiro 与应用安全数据间的“桥梁” 或者“连接器” 。也就是说,当对用户执行认证(登录)和授权(访问控制)验证时, Shiro 会从应用配置的 Realm 中查找用户及其权限信息。

5: Mybatis 中一级缓存与二级缓存 ?

①一级缓存: 基于 PerpetualCache 的 HashMap 本地缓存,其存储作用域为 Session,当 Session flush 或close 之后,该 Session 中的所有 Cache 就将清空。

② 二级缓存与一级缓存其机制相同,默认也是采用 PerpetualCache, HashMap 存储,不同在于其存储作用域为Mapper(Namespace),并且可自定义存储源,如 Ehcache。作用域为 namespance 是指对该 namespance 对应的配置文件中所有的 select 操作结果都缓存,这样不同线程之间就可以共用二级缓存。启动二级缓存:在 mapper 配置文件中: 。

二级缓存可以设置返回的缓存对象策略: 。当readOnly="true"时,表示二级缓存返回给所有调用者同一个缓存对象实例,调用者可以 update 获取的缓存实例,但是这样可能会造成其他调用者出现数据不一致的情况(因为所有调用者调用的是同一个实例)。当 readOnly="false"时,返回给调用者的是二级缓存总缓存对象的拷贝,即不同调用者获取的是缓存对象不同的实例,这样调用者对各自的缓存对象的修改不会影响到其他的调用者,即是安全的,所以默认是 readOnly="false";

③ 对于缓存数据更新机制,当某一个作用域(一级缓存 Session/二级缓存 Namespaces)的进行了 C/U/D 操作后,默认该作用域下所有 select 中的缓存将被 clear。

6: 拦截器和过滤器有哪些区别?

* 拦截器是基于 java 的反射机制的,而过滤器是基于函数回调

* 拦截器不依赖与 servlet 容器,而过滤器依赖与 servlet 容器

* 拦截器只能对 action 请求起作用,而过滤器则可以对几乎所有的请求起作用

* 拦截器可以访问 action 上下文、值栈里的对象,而过滤器不能

* 在 action 的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一 次 .

7: 简单介绍一下 zookeeper 以及 zookeeper 的原理  ?

session:

ZooKeeper 是一个分布式的,开放源码的分布式应用程序协调服务,是 Google 的 Chubby 一个开源的实现,是 Hadoop 和 Hbase 的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。

ZooKeeper 的目标就是封装好复杂易出错的关键服务,将简单易用的接口和性能高效、 功能稳定的系统提供给用户。

ZooKeeper 包含一个简单的原语集, 提供 Java 和 C 的接口。

ZooKeeper 代码版本中,提供了分布式独享锁、选举、队列的接口,代码在 zookeeper-3.4.3\src\recipes。其中分布锁和队列有 Java 和 C 两个版本,选举只有 Java 版本。

原理:

ZooKeeper 是以 Fast Paxos 算法为基础的,Paxos 算法存在活锁的问题,即当有多个 proposer 交错提交时,有可能互相排斥导致没有一个 proposer 能提交成功,而 Fast Paxos 作了一些优化,通过选举产生一个 leader (领导者),只有 leader 才能提交 proposer,具体 算法可见 Fast Paxos。因此,要想弄懂 ZooKeeper 首先得对 Fast

Paxos 有所了解。

ZooKeeper 的基本运转流程:1、选举 Leader。 2、同步数据。 3、选举 Leader 过程中算法有很多,但要达到的选举标准是一致的。 4、 Leader 要具有最高的执行 ID,类似 root 权限。 5、集群中大多数的机器得到响应并 follow 选出的 Leader。

微信公众号:javafirst

扫码关注免费获取更多资源 

JavaEE面试经验分享(西安**捷普网络科技有限公司)_java_07