简答题1. 什么是多租户技术?Kafka是否支持多租户?
多租户技术(multi-tenancy technology)是一种软件架构技术,它是实现如何在多用户的环境下共用相同的系统或程序组件,并且仍可确保各用户间数据的隔离性。
我们可以将Kafka部署为多租户解决方案。做法是:通过配置哪个主题可以生产或消费数据来启用多租户,也有对配额的操作支持。管理员可以对请求定义和强制配额,以控制客户端使用的Broker资源。
[考点] Kafka
2. Rest和RPC各有什么优缺点?
RPC最大的缺点是服务提供方和调用方之间存在强依赖,需要为每一个服务进行接口的定义,需要严格的版本控制才能防止因为版本不一致而在服务提供方和调用方之间产生冲突。RPC的优点是可以使请求报文体积更小,一般以二进制传输,性能比较高。
而Rest是轻量级的解耦合的接口,服务的提供方和调用方不存在代码之间的依赖问题,双方可以通过约定好的规则进行独立开发,但是要避免出现文档和接口不一致而导致的服务集成问题。Rest相对也更容易上手。
Rest接口一般是用JSON格式的文本传递报文,体积相对较大,性能相对较低。
[考点] Spring Cloud与微服务架构
3. 如何使用IK中文分词器?如何实现词库热更新?
IK分词器有两种分词模式:ik_max_word和ik_smart模式。ik_max_word会将文本做最细粒度的拆分,ik_smart会将文本做最粗粒度的拆分。两种分词器使用的最佳实践是:索引时用ik_max_word模式,搜索时用ik_smart模式,即索引时最大化地将文章内容分词,搜索时更精确地搜索到想要的结果。
IK分词器有良好的扩展性,支持添加自定义词库和停用词库。词库文件的扩展名是.dic,在配置文件IKAnalyzer.cfg.xml进行简单配置就能做到扩展或停止词库,配置示例如下:
<properties>
<comment>IK Analyzer扩展配置</comment>
<! --用户可以在这里配置自己的扩展词库 -->
<entry key="ext_dict">myext.dic</entry>
<! --用户可以在这里配置自己的扩展停止词词库-->
<entry key="ext_stopwords"></entry>
<! --用户可以在这里配置远程扩展词词库-->
<! --<entry key="remote_ext_dict">words_location</entry>-->
<! --用户可以在这里配置远程扩展停止词词库-->
<! --<entry key="remote_ext_stopwords">words_location</entry>-->
</properties>
当然,完成配置后,需要重启ES服务才行。更新完成后,以后就可以进行词库的热更新了,只要修改已配置的词库文件,无须重启ES服务,大约一分钟左右就可以看到更新效果了。
[考点] Elasticsearch
4. 如何避免Jsp页面自动生成Session对象?为什么要这么做?
默认情况下,对一个Jsp页面发出请求,如果Session还没有建立,那么Jsp页面会自动为请求创建一个Session对象。但是Session是比较消耗资源的,如果不需要使用Session,就不应该创建Session,例如一些只用来宣传产品的网页,往往无需使用Session,这时可在Jsp中使用page指令进行设置,代码如:<%@page Ses sion="false"%>,就可避免Jsp页面为每个请求自动创建Session。
[考点] Java Web基础
5. 什么是缓存预热?
缓存预热就是系统上线时,提前将相关的缓存数据直接加载到缓存系统。而不是等到用户请求时,才将查询数据进行缓存,这样用户请求可直接查询事先被预热的缓存数据。
缓存预热的方式可以有如下几种。
●直接编写缓存刷新页面,上线时手工操作。
●数据量不大时,可以在项目启动时自动进行加载。
●定时刷新缓存。
[考点] NoSQL与缓存综合
6. 什么是重定向攻击?
重定向攻击是指受害者的计算机被定向到其他网站而非目标网站,这可通过操纵DNS服务器中的缓存、本地系统中的DNS缓存或者修改本地系统中主机文件来完成。
链接操控的钓鱼攻击其实也是一种重定向攻击。
常见的防范措施是白名单,将合法的要重定向的URL加到白名单中,非白名单上的域名重定向时拒之,第二种解决方案是重定向Token,在合法的URL上加上Token,重定向时进行验证。
[考点] 软件安全知识
7. 如何保证数据读写的原子性?
进行数据库读写操作时,利用数据库引擎提供的事务和回滚机制,可以保证数据库跨表操作的原子性。
[考点] 关系型数据库知识
8. Spring Cloud Config如何实现自动刷新?
Spring Cloud Config客户端结合消息总线Spring Cloud Bus可以实现自动刷新。以RabbitMQ为例,首先添加依赖spring-cloud-starter-bus-amqp,spring-boot-starter-actuator也必不可少,并在配置文件中配置好RabbitMQ相关属性参数。暴露bus-refresh端点(1.*版是/bus/refresh),即配置Management.endpoints.Web.exposure.include的属性值要包含bus-refresh,或者是'*'。也可以只刷新指定应用如/bus-refresh? destination=micro-provider:**,这样只会刷新Spring.application.name为micro-provider的所有实例。
配置好后,需要刷新配置信息,在类上添加注解@RefreshScope,修改config服务端配置后,使用curl(或其他方式)执行Post请求。
curl-X Post http://localhost:8080/actuator/bus-refresh
注意:localhost: 8000是某一Config客户端的服务地址。
[考点] Spring Cloud与微服务架构
9. Myisamchk是用来做什么的?
使用Myisamchk实用程序,可以检查、修复或优化Myisam表。如果你使用Myisamchk修复或优化表,你必须总是保证MySQL服务器不在使用表(如果你正在使用--skip-locking,这也适用)。如果你不停掉MySQL,在你运行Myisamchk前,你至少应该做一个mysqladmin flush-tables。
也可使用命令optimize tables优化并修复表,但是这不如Myisamchk快或可靠(在真正的致命错误的情况下)。但optimize tables的好处是较易使用并且不必关心清空表。
[考点] MySQL数据库
10. 页面导入样式时,使用link和@import有什么区别?
两者主要有以下四点区别。
1)link是XHtml标签,除了加载CSS外,还可以定义RSS等其他事务,@import属于CSS范畴,只能加载CSS。
2)link引用CSS时,在页面载入时同时加载,@import需要页面网页完全载入以后加载。
3)link是XHtml标签,无兼容问题;@import是在CSS2.1提出的,低版本的浏览器不支持。
4)link支持使用JavaScript控制DOM去改变样式,而@import不支持。
[考点] HTML5与Web编程综合
11. Struts2的常用注解有哪些?
@ParentPackage注解,对应xml配置文件中的package的父包,一般需要继承struts-default。
@Action注解,对应<action>节点。创建Action,这个注解可以应用于Action类上,也可以应用于方法上。
@Actions注解,配置一个类为多个Action。
@Namespace注解,用于创建不同的模块,对应<package>的namespace属性。
@Result注解,对应了<result>节点,用于结果页面。
[考点] Struts2
12. Spring Boot加密组件jasypt如何使用?
加密组件jasypt的使用方法如下:
1)在Spring Boot项目中使用jasypt组件对敏感信息加密,使用jasypt组件首先添加依赖项jasypt-spring-boot-starter,不同JDK版本也要选择不同版本的Starter (JDK6对应版本为1.5-Java6,JDK7对应版本为1.5-Java7, JDK8可使用1.8或以上版本)。
2)然后在配置文件中配置加密密钥:
jasypt.encryptor.password=yourjasypt
当然,在配置文件中配置加密密钥是不太安全的,可以在启动参数传入:
-Djasypt.encryptor.password=yourjasypt-jar xxx.jar
也可以写在启动类中,在启动类的main函数中增加一行代码如下:
System.setProperty("jasypt.encryptor.password", "yourjasypt");
另外,如果是在Tomcat中启动,也可以在Tomcat的启动文件中的JAVA_OPTS中设置加密参数,在Windows环境下,在catalina.bat文件头部加入:
set "JAVA_OPTS=%JAVA_OPTS% -Djasypt.encryptor.password=yourjasypt"
在Linux环境下,在Tomcat启动文件catalina.sh文件头部加入:
JAVA_OPTS="$JAVA_OPTS -Djasypt.encryptor.password=yourjasypt"
3)使用组件提供的工具类PooledPBEStringEncryptor可生成加密串:
/**
*这个方法是直接使用加密密钥生成加密串
*@param password加密密钥
*@param value加密值
*/
public static String encyptPwd (String password, String value) {
PooledPBEStringEncryptor encryptor=new PooledPBEStringEncryptor();
encryptor.setConfig(cryptor(password));
return encryptor.encrypt(value);
}
如果不想通过工具类来获取加密后的字符串,也可以在项目中编写测试类来获取:
@RestController
public class IndexController {
@Autowired
private StringEncryptor encryptor;
@GetMapping("/myjasypt")
public void testMyjasypt() {
String password="111111";
String encryptPwd=encryptor.encrypt(password);
System.out.println("加密后:"+encryptPwd);
System.out.println("解密后:"+encryptor.decrypt(encryptPwd));
}
}
启动后通过浏览器访问该地址,就会在控制台输出字符串"111111"进行加密后和解密后的值。
生成加密字符串的方式很多,也可以用命令行生成,读者可自行了解。
4)然后将生成的加密字符串配置到配置文件对应的参数即可,要加上约定的关键字ENC,格式如:
password=ENC(ln6hgzpDZItgjjojAntHqsYPFjkkkTew==)
只要带上约定关键字的属性,都会被用加密密钥去解密。假定之前生成的是数据库密码,并将加密字符串配置到配置文件的参数spring.mysql.datasource.password中,这时可以通过测试类来验证加密字符串的正确性:
@RestController
public class IndexController {
@Value("${spring.mysql.datasource.password}")
private String dbPassword;
@GetMapping ("/password")
public String password() {
return dbPassword;
}
}
启动项目后,访问该地址,返回的结果就是数据库密码的明文"111111"。
[考点] Spring Boot
13. Spring支持哪些事务管理方式?实现原理是什么?
Spring的事务管理方式有编程式事务管理和声明式事务管理两种。编程式事务管理使用TransactionTemplate或者直接使用底层的PlatformTransactionManager。对于编程式事务管理,Spring推荐使用TransactionTemplate管理事务。
Spring声明式事务管理建立在AOP之上的。其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。声明式事务最大的优点就是不需要通过编程的方式管理事务,程序员只需要专注于业务逻辑的实现,只需在配置文件中做相关的事务规则声明(或通过基于注解的方式),便可以将事务规则应用到业务逻辑中。
Spring实现声明式事务管理主要有两种方式。
1)基于XML方式的声明式事务管理。
2)通过Annotation注解方式的事务管理。注解方式管理事务时所用的注解为@Transactional。注解可用在类上和方法上。
注解标注在类前,标示类中所有方法都进行事务处理。
注解标注在接口、实现类的方法前,标示方法进行事务处理。
[考点] Spring基础
14. MongoDB中的命名空间是什么意思?
MongoDB内部有预分配空间的机制,每个预分配的文件都用0进行填充。
数据文件每新分配一次,它的大小都是上一个数据文件大小的两倍,每个数据文件最大2GB。
MongoDB每个集合和每个索引都对应一个命名空间,这些命名空间的元数据集中在16M的*.ns文件中,平均每个命名占用约628字节,也即整个数据库的命名空间的上限约为24000。
如果每个集合有一个索引(如默认的_id索引),那么最多可以创建12000个集合。如果索引数更多,则可创建的集合数就更少了。同时,如果集合数太多,一些操作也会变慢。
要建立更多的集合,MongoDB也是支持的,只需要在启动时加上“--nssize”参数,这样对应数据库的命名空间文件就可以变得更大以便保存更多的命名。这个命名空间文件(.ns文件)最大可以为2G。
每个命名空间对应的盘区不一定是连续的。与数据文件增长相同,每个命名空间对应的盘区大小都是随分配次数不断增长的。目的是为了平衡命名空间浪费的空间与保持一个命名空间数据的连续性。
需要注意的一个命名空间是$freelist,这个命名空间用于记录不再使用的盘区(被删除的Collection或索引)。每当命名空间需要分配新盘区时,会先查看$freelist是否有大小合适的盘区可以使用,如果有就回收空闲的磁盘空间。
[考点] MongoDB
15. 如何防止表单重复提交?
可以通过使用Session来实现。
1)在进入JSP页面时生成一个随机值并保存到Session中,同时将其设置为表单的一个隐藏域的值,随表单提交。
2)在处理表单提交请求时,获取Session中的值,获取提交表单对应隐藏域的参数值,比较两者是否相同,如果相同说明不是重复提交,则继续执行请求且删除Session中保存的值,如果不相同则是重复提交,返回提示不能重复提交。
[考点] Java Web基础
16. Redis执行AOF持久化执行时调用了哪个函数?AOF文件的内容是什么?
Redis执行AOF持久化时会调用flushAppendOnlyFile函数,这个函数执行以下两个工作来写入保存。
write:根据条件将aof_buf中的缓存写入AOF文件。
save:根据条件调用fsync或fdatasync函数,将AOF文件保存到磁盘中。
AOF文件以日志的形式记录Redis服务端每一个写、删除操作,不包括查询操作。记录内容是Redis通信协议(RESP)格式的命令文本。RESP是Redis客户端和服务端之前使用的一种通信协议,RESP实现简单、快速解析、可读性好。
[考点] Redis
17. AJAX和JavaScript有什么区别?
AJAX是一种创建交互式网页应用的开发技术,JavaScript是其中的关键技术。AJAX可以实现网页的无跳转异步刷新,给用户带来良好的操作体验,在Web前端开发中被广泛使用。
JavaScript是一种解释性脚本语言(代码不进行预编译),可以在浏览器端和服务端(Node.js)执行,是一种动态类型、弱类型、基于原型的语言,内置支持类型。它的解释器被称为JavaScript引擎,为浏览器的一部分。被广泛用于Web应用开发,常用来为网页添加各式各样的动态功能,为用户提供更流畅美观的浏览效果。
[考点] AJAX与JavaScript
18. 代理的优点有哪些?代理有哪些实现方式?两者有何不同?
代理分为静态代理和动态代理。
静态代理就是代理类在程序运行前就已经存在的代理方式,在运行前要编写好代码。静态代理中的代理类和委托类会实现同一接口或是派生自相同的父类。
动态代理是代理类在程序运行时创建的代理方式。也就是说,代理类并不是在Java代码中事先定义的,而是在运行时动态生成的。
静态代理性能相对会略高一些,但是缺点也很明显,要事先编写好代码,为不同的对象与不同的方法添加相同的通用处理时,会产生大量冗余代码。
如果使用动态代理,代码是在运行时动态生成的,可以对所有代理类的方法进行统一处理,而不用逐一修改每个方法,有高度的灵活性,有逻辑需要修改时,可以一次进行统一修改。效率很高,纠错也容易。因此动态代理获得了广泛的使用。
[考点] Spring基础
19. 什么是Raft选举算法?
Raft算法也是一种分布式选举算法,类似于Paxos算法,也是以少数服从多数的算法。它也有三个角色:
角色名
|
角色的作用
|
Leader
|
处理所有客户端交互,日志复制等操作,一般一次只有一个 Leader。
|
Follower
|
类似选民,处于被动状态。所有节点都以Follower的状态开 始,如果没有收到Leader消息则会变成candidate状态。
|
Candidate
|
类似Proposer,可以被选为一个新的Leader。
|
Raft算法有两个基本过程:
Leader选举:每个candidate随机经过一定时间都会提出选举方案,最近阶段中的票最多者被选为Leader。
同步log:Leader会找到系统中log(各种事件的发生记录)最新的记录,并强制所有的follow来刷新到这个记录。
Raft一致性算法是通过选出一个Leader来简化日志副本的管理,例如,日志项(log entry)只允许从Leader流向Follower。
[考点] 分布式软件系统(Distributed Software Systems)相关知识
20. Struts2的名称空间namespace有什么用?
使用名称空间的好处是能把Action类按功能模块归类配置,即实现Action的模块化配置。
[考点] Struts2