1.Arraylist和LinkedList的区别是什么?(Array数组)
Array(数组)是基于索引(index)的数据结构,它使用索引在数组中搜索和读取数据是很快的。Array获取数据的时间复杂度是O(1),但是要删除数据却是开销很大,因为这需要重排数组中的所有数据,(因为删除数据以后, 需要把后面所有的数据前移)。缺点:数组初始化必须指定初始化的长度, 否则报错。
例如:
int[] a = new int[4];//推荐使用int[] 这种方式初始化
int c[] = {23,43,56,78};//长度:4,索引范围:[0,3]
List—是一个有序的集合,可以包含重复的元素,提供了按索引访问的方式,它继承Collection。List有两个重要的实现类:ArrayList和LinkedList。
ArrayList:
1).可以看作是能够自动增长容量的数组
2).ArrayList的toArray方法返回一个数组,Arrays的asList方法返回一个列表
3).ArrayList底层的实现是Array, 数组扩容实现
LinkedList:
1).是一个双链表,在添加和删除元素时具有比ArrayList更好的性能.
2).在get与set方面弱于ArrayList.
当然,这些对比都是指数据量很大或者操作很频繁。
2.String,StringBuilder和StringBuffer 三者有什么不同?
String是只读字符串,它并不是基本数据类型,而是一个对象。从底层源码来看是一个final类型的字符数组,所引用的字符串不能被改变,一经定义,无法再增删改。每次对String的操作都会生成新的String对象。
private final char value[];
每次+操作 : 隐式在堆上new了一个跟原字符串相同的StringBuilder对象,再调用append方法拼接+后面的字符。
StringBuffer与StringBuilder都继承了AbstractStringBuilder类,而AbtractStringBuilder又实现了CharSequence接口,两个类都是用来进行字符串操作的。在做字符串拼接修改删除替换时,效率比String更高。
StringBuffer是线程安全的,StringBuilder是非线程安全的。所以StringBuilder比StringBuffer效率更高,StringBuffer的方法大多都加了synchronized关键字
3.说说Java垃圾回收机制。(5分)
1.垃圾回收,顾名思义,便是将已经分配出去的,但却不再使用的内存回收回来,以便能够再次分配。在 Java 虚拟机的语境下,垃圾指的是死亡的对象所占据的堆空间。垃圾回收只会负责释放那些对象占有的内存,此时对象也就被销毁。
2. 发生地点:一般发生在堆内存中,因为大部分的对象都储存在堆内存中。
3.发生时间:程序空闲时间不定时回收。
4.服务注册和发现是什么意思?Spring Cloud 如何实现?(5分)
在微服务项目中,我们通常会用到服务之间的相互调用,我们通常在属性文件中进行所有的需要请求的微服务的地址端口等信息。随着越来越多的 服务开发和部署,添加和修改这些属性变得更加复杂。有些服务可能会下架,而某些位置可 能会发生变化。手动更改属性可能会产生问题。
Eureka 提供了服务注册和服务发现的功能,服务注册是让所有微服务将自己的信息注册到注册中心,服务发现是让微服务可以拉取注册中心里的服务列表,方便结合feign进行远程调用,由于所有服务都在 Eureka 服务器上注册并通过调用 Eureka 服务器完成查找, 因此无需处理服务地点的任何更改和处理。
5.什么是Spring Cloud Gateway?(5分)
Spring Cloud Gateway是Spring Cloud官方推出的第二代网关框架,取代Zuul网关。网关作为流量的,在微服务系统中有着非常作用,网关常见的功能有路由转发、权限校验、限流控制等作用。
使用了一个RouteLocatorBuilder的bean去创建路由,除了创建路由RouteLocatorBuilder可以让你添加各种predicates和filters,predicates断言的意思,顾名思义就是根据具体的请求的规则,由具体的route去处理,filters是各种过滤器,用来对请求做各种判断和修改。
6.Springboot 如何集成mybatis (5分)
MyBatis执行流程
mybatis
ssm整合
7.写出几个你熟悉的设计模式及其使用场景。(10 分)
1.工厂模式:在Beanfactory和applicationContext创建中都用到了
2.单例模式:Bean默认就是单例模式,单例模式只允许创建一个对象,获取两个bean对象会发现他们的内存地址是一样的
<bean id="emp" class="entity.employee" scope="singleton">
</bean>
3.多例模式:把scope="singleton"改成scope=“prototype”, 每次获取这个bean都会创建一个新的bean对象,内存地址都不一样。
<bean id="emp" class="entity.employee" scope="prototype">
</bean>
4.代理模式:Spring AOP 底层就是用了动态代理
5.适配器模式:就比如springmvc执行原理有一步就用到了, DispatcherServlet通过HandlerAdapter处理器适配器调用具体的处理器也就是Controller。
6.装饰器模式: 就是动态的给一个对象添加一些额外的职责。
4,5,6属于结构型模式
7.模板模式:spring提供的数据库访问的模板类JdbcTemplate、消息处理的模板类JMSTemplate、HTTP通信的模板类RestTemplate都用到了模板设计模式
8.策略模式: 策略模式需要定义一个策略接口,不同的策略都去实现策略接口,在需要调用过程中通过持有该策略接口,然后根据不同的场景去使用不同的实现类 。
9.委派模式: 它的基本作用就是负责任务的调用和分配任务, 应用场景:委派对象本身不知道如何处理一个任务或请求,而交给其他对象来处理;
10.观察者模式:用于spring监听事件
8.请设计一个基于角色的用户权限控制系统的数据库表结构。(15 分)
基于RBAC设计表
RBAC(Role-Based Access Control,基于角色的访问控制),就是用户通过角色与权限进行关联。简单地说,一个用户拥有若干角色,每一个角色拥有若干权限。这样,就构造成“用户-角色-权限”的授权模型。在这种模型中,用户与角色之间,角色与权限之间,一般者是多对多的关系。
后续再写一个博客解释。
9.日常工作中你是怎么优化 SQL 查询速度的? (20分)
1、建立索引
问到了哪些情况会使索引失效:a.有or必全有索引;
b.复合索引未用左列字段;
c.like以%开头;
d.需要类型转换;
e.where中索引列有运算;
f.where中索引列使用了函数;
g.如果mysql觉得全表扫描更快时(数据少);2、对查询进行优化,尽可能避免全表扫描
3、优化数据库字段(设计优化:尽量避免使用NULL;最小数据长度;使用最简单数据类型;尽量少定义 text 类型;适当分表、分库策略)4、字段冗余
减少跨库查询或多表连接操作5、表的拆分
表分区和拆分,无论是业务逻辑上的拆分(如一个月一张报表、分库)还是无业务含义的分区6、查询时不要返回不需要的行、列
7、减少SQL中函数运算与其它计算8、升级硬件
9、使用缓存其它
读写分离数据库三大范式:
当数据较好范式化时,修改的数据更少,而且范式化的表通常要小,可以有更多的数据缓存在内存中,所以执行操作会更快
缺点则是查询时需要更多的关联
第一范式:字段不可分割,数据库默认支持
第二范式:消除对主键的部分依赖,可以在表中加上一个与业务逻辑无关的字段作为主键,比如用自增id
第三范式:消除对主键的传递依赖,可以将表拆分,减少数据冗余
10.编程写出一个函数:判断两个字符串是否可以通过改变字母的顺序变成一样的字符串(25分)
方法一:
import java.util.LinkedList;
public class Solution {
/**
* @param s: The first string
* @param b: The second string
* @return true or false
*/
public boolean anagram(String s, String t) {
// write your code here
if(s.length() != t.length())
return false;
LinkedList<String> list = new LinkedList<String>();
for(int i=0;i<s.length();i++){
list.add(s.substring(i, i+1));
}
for(int j=0;j<t.length();j++){
if(list.size()==0)
return false;
if(list.contains(t.substring(j, j+1))){
list.remove(t.substring(j, j+1));
}else{
return false;
}
}
return true;
}
};
方法二:
public static boolean compareArg(String a,String b){
if(a.length()!=b.length()){
return false;
}
a=a.toLowerCase();
b=b.toLowerCase();
int temp=0;
for(int j=0;j<b.length();j++){
String c=b.substring(j,j+1);
if(a.contains(b.substring(j,j+1))){
temp=temp+1;
}
}
if(a.length()==temp){
return true;
}
return false;
}
方法三:
public static boolean compareArg2(String a, String b) {
if (a.length() != b.length()) {
return false;
}
a = a.toLowerCase();
b = b.toLowerCase();
char[] ac = a.toCharArray();
char[] bc = b.toCharArray();
Arrays.sort(ac);
Arrays.sort(bc);
a = String.valueOf(ac);
b = String.valueOf(bc);
return a.equals(b);
}