技术栈:springboot框架+redis
个人笔试/技术面问题整理
1、SpringBoot有什么组件?
举例说几个:
①auto-configuration组件:核心特征。其约定大于配置思想,赋予了SpringBoot开箱即用的强大能力。
②starter组件:将复杂配置统一集成进starter,maven导入starter后,SpringBoot就自动扫描加载配置。
③springboot cli 组件:命令行工具,通过springboot cli,可通过Groovy脚本快速构建SpringBoot应用,并可通过命令行方式运行。
④actuator 组件:用来对应用系统进行自省和监控的功能模块,是SpringBoot的监控插件,本身提供了很多接口可以获取当前项目的各项运行状态指标。借助于Actuator开发者可以很方便地对应用系统某些监控指标进行查看、统计等。
2、@Service和@Autowired的区别?
@Service根据名称
@Autowired默认按类型配置
3、SpringBoot是基于什么服务器启动的?启动的原理是什么 ?
Tomcat
启动原理:
SpringBoot因内置了tomcat或者jetty服务器,不需要直接部署war文件,所以SpringBoot的程序起点是一个普通的主函数。
主函数:
@SpringBootApplication
public class DemoApplication{
public static void main (string[] args){
springApplication.run(DemoApplication.class,args);
}
}
SpringBoot的启动过程都是通过@SpringBootApplication注解和SpringApplication.run方法来实现。
Curl localhost:8080/hello
Curl:验证接口
4、定义一个post接口使用的注解?
注解@PostMapping定义一个post接口
@RequestBody:把前端传过来的Json转换成Java对象(将Json对象映射成后台Java实体)。例:(@RequestBody User user)
5、Long型跟long型的区别,Long型中equals和“==”的区别?
long是基本数据类型,没有属性方法,只能进行数学运算;而Long是long相对应的引用数据类型,也是包装类,它有方法和属性。
类里面有方法和属性,而基本数据类型里面没有方法和属性。
long a = 1 ;
Long a1 = new Long(1);
Long a2 = new Long(1);
以上:a与a1相等,a与a2相等,a1与a2 equals相等。
由此可见,
Long定义的变量为一个Long类型对象;对应的是对象的引用地址;
long定义的变量为一个长整型数值的数值变量。
到底是选择Long还是long这个还得看具体环境,如果你认为这个属性不能为null,那就用long,因为它默认值为0;如果这个字段可以为null,那就应该选择Long。
long可以用“>”,“=”,“<”作比较,Long是一个对象,使用.equals方法进行相等比较,大小比较时使用“>”“<”对Long对象longValue()。例 : L1.longValue()>L2.longValue()
6、开发过程中错误代码,文件找不到的错误代码:404,服务器内部失败:500,内部网络故障或设置问题的状态:502,请求失败(错误的请求 400);
7、SpringBoot中如何处理事务?使用的任务注解?
SpringBoot提供了一个名为“@Transational”的注解来管理事务。
假设一个场景,需要在一个service中处理数据,并通过Rest调用将数据发送到另一个service。如若另一个服务器突然停止,如果在向另一个service服务发送Api调用之前将数据信息保存在自己的数据库中,那么将来会发生差异,因为另一个service正在丢失该记录。
为了避免这种情况,我们可以将“@Transactional”注解放入另一个service的方法中,然后从那里开始,如果调用另一个service时出现故障,正在进行的流程中的所有数据都将回滚!
@Transational
public A a(B b,Double c)
{
//数据处理
//向另一个service发送Rest调用
}
8、MySQL数据库有自增序主键,Oracle有UUID主键来辨别唯一,但是无序,Oracle怎么实现自增长主键?
Oracle数据库自增长没有Mysql数据库简单,mysql可以在建表的时候设置auto_increment就好了,但Oracle这样不行,Oracle数据库必须建立序列,然后再mybatis插入id时,使用这个序列后,才能实现Oracle id 的子增长。
序列创建语句:
create sequence TBAL_OA_HOLIDAY_TYPE //序列名称
increment by 1 //以1倍的速度增长,也可以设置其他数字
start with 1 //从id=1开始 开始增长
maxvalue 9999 //最大值为9999,根据情况
minvalue 1 //最小值为1
nocycle //不循环,也就一直增长
cache 20 //设置缓存cache个序列,如果系统down掉或者有其他情况不连续,也可以设置为 ---NOCACHE
noorder ;
建立了Oracle序列之后,我们就可以再mybatis中插入这样使用,来插入id了;
insert into TBAL_OA_HOLIDAY_TYPE(ID,TYPE_NAME,REMARK) values(TBAL_OA_HOLIDAY_TYPE.NEXTVAL,#{typename},#{remark})
我们在mybatis插入id的位置用(序列名称+.NEXTVAL)的形式代替这个id
(若是uuid作为主键,Oracle中有有sys_guid函数可以产生uuid)
例:
select sys_guid() from dual
mysql中使用uuid的话,建议在Java中生成uuid再存库
( 引入java.util.UUID包。String uuid = UUID.randomUUID().toString().replace(“_”,“”) )
9、Vue前端若多次对后端进行点击响应,后端怎么能减少这个冗余?
后端:(数据库+索引)
10、Arraylist、Linkedlist和Vector三者区别
①从存储结构来看:
Arraylist和Vector是由数组构成,其默认的初始容量为10。而Linkedlist是由双向链表构成。
②从线程安全来看:
Arraylist和Linkedlist是线程不安全的,如果需要在并发的环境下使用它们,可以用Collections类中的静态方法synchronizedlist()对Arraylist和Linkedlist进行调用即可。
而Vector是线程安全的,它的源码中大部分方法中都包含关键字synchronized,但Vector的效率没有Arraylist高。
③从扩容机制来看:
Linkedlist是没有扩容的,因为是链表实现的。
Arraylist和Vector的扩容机制:(1)Arraylist扩容之后的容量是之前的1.5倍(默认);(2)Vector扩容之后的容量是之前的两倍(默认);(3)Vector可设置容量增量,Arraylist不可以。
④从增删查改的效率来看:
Arraylist和Vector:如果是在指定位置检查,或者是在集后尾部进行插入和删除的话,时间复杂度是O(1),但如果是其他地方插入或者删除的话,时间复杂度就变成了O(n)。
注意:可变长度数组的原理:当元素哥个数超过数组长度时,会产生一个新的数组,将原数组的数据复制到新数组,再将新的元素添加到新数组中。
11、equals和“= =”的区别?
“= =”是比较两个变量或实例是否指向同一个内存空间,而equals是比较两个变量或实例所指向的内存空间的值是否相等。
对于基本数据类型的变量,如Byte,short,char,int,float,long,double和boolean,“==”直接对其值进行比较;
对于引用数据类型的变量,则是对其内存地址的比较。
因此,“= =”比较的是值,只是引用类型变量存的是对象的地址。
而equals方法是Object类的方法,比较的是字符串中所包含的内容是否相同。
12、使用过的关系型数据库以及非关系型数据库,它们之间的区别
关系型数据库:mysql、Oracle
非关系型数据库:redis --是一个key-value的nosql数据库
Oracle与mysql区别:
mysql开源免费的中小型,关系数据库管理系统(RDBMS);
Oracle收费的大型、对象关系数据库管理系统(ORDMS);
mysql使用三(用户名、密码、位置)验证客户;
Oracle有用户名、密码、配置文件、本地身份验证、外部身份验证等;
mysql事务是自动提交;
Oracle需要手动,写commit或点提交按钮;
mysql没有Oracle的表空间、角色管理、快照、同义词、包、自动存储管理。
字符类型:
mysql:char(0-255)、varchar(0-65,535)
Oracle:char、nchar(1-2000),varchar2、nvarchar2(0-4000)
mysql:like ‘%字符串%’
oracle:也有li’ke ‘%字符串%’,使用字符串比较数instr(字符串,‘字符串’)>0更精确
mysql有Date、Time日期类型
Oracle只有Date
mysql非空字段也有空的内容
Oracle定义非空字段就不允许有空的内容
(所以,将mysql数据传过来Oracle,要注意导数据时要对空字符进行判断,如果为null或者空字符、需要把它转换成一个空格的字符串)
oracle与redis的区别:
①数据模型
Oracle和MySQL都是关系型数据库,数据以表格形式存储,每个表格由若干个列组成,每列定义了数据的类型和约束条件。表格之间可以建立关系,例一对多,多对多等,这些关系需要使用外键进行定义。
redis是一种键值型数据库,数据以键值对的形式存储的,其中键是一个字符串,值可以是字符串、哈希、列表、集合或有序集合等。
②查询语句
Oracle和MySQL都是使用sql查询语言来查询数据。sql是一种标准的关系型数据库查询语言。
redis使用一种类似于命令的语言来查询和操作数据,其中每个命令都对应一个具体的操作,例如set用于设置键值对,get用于获取键值对应的值等。
③扩展性
mysql和Oracle支持分布式和扩展性,但需额外配置且复杂。
redis支持分布式,可在多台服务器上分布数据,以提高性能和可用性。
④适用场景
mysql和Oracle使用于处理结构化数据的场景,支持高度优化的查询引擎,可处理复杂的查询和聚合操作
redis适用于高速读写的场景,例如缓存、消息队列等,redis读写速度非常快,可以在短时间内处理大量的请求
13、mao集合取并集、差集、交集
map1、map2
map是一个key和value的键值对的集合
①map并集:
public static Map<String,Object> getUnion( Map<String,Object> map1, Map<String,Object> map2){
Set<String> bigMapKey = map1.keySet();
Set<String> smallMapKey = map2.keySet();
Set<String> differenceSet = Sets.union(bigMapKey,smallMapKey);
Map<String,Object> result = Maps.newHashMap();
for(String key : differenceSet){
if(map1.containsKey(key)){
result.put(key,map1.get(key));
}
else{
result.put(key,map2.get(key));
}
}
return result ;
}
.containsKey:判断是否有key
.get():获取对应的value
Guava的union():返回两个集合的不可修改的视图
②差集
bigmap、smallmap
public static Map<String,Object> getDifference( Map<String,Object> bigMap, Map<String,Object> smallMap){
Set<String> bigMapKey = bigMap.keySet();
Set<String> smallMapKey = smallMap.keySet();
Set<String> differenceSet = Sets.difference(bigMapKey,smallMapKey);
Map<String,Object> result = Maps.newHashMap();
for(String key : differenceSet){
result.put(key,bigMapKey.get(key));
}
return result ;
}
difference():函数返回两个集合的差集、即返回的在第一个集合但不在第二个集合中的元素。
③map交集:
map1、map2
public static Map<String,Object> getInter( Map<String,Object> map1, Map<String,Object> map2){
Set<String> bigMapKey = map1.keySet();
Set<String> smallMapKey = map2.keySet();
Set<String> differenceSet = Sets.intersection(bigMapKey,smallMapKey);
Map<String,Object> result = Maps.newHashMap();
for(String key : differenceSet){
result.put(key,map1.get(key));
}
return result ;
}
intersection():方法用于返回两个或者更多集合中包含的元素,即交集。
14、String、StringBuffer和StringBuilder的区别
string:
①String的值是不可变的,这就导致每次对String的操作都会生成新的String对象,不仅效率低,且浪费优先的内存空间。
②不可变
③
④
StringBuffer:
①StringBuffer是可变类,和线程安全的字符串操作类,任何对它指向的字符串的操作都不会产生新的对象,每个StringBuffer对象都有一定的缓冲区容量,当字符串大小没有超过容量时,不会分配新的容量,当字符串大小超过容量时,会自动分配容量。
②可变
③线程安全
④多线程操作字符串
StringBuilder:
①可变类,速度更快。
②可变
③线程不安全
④单线程操作字符串
StringBuffer对象是一个字符序列可变的字符串,没有重新生成一个对象,而是在原来的对象中可以连接新的字符串。
StringBuilder类也代表可变字符串对象。StringBuffer和StringBuilder基本相似。不同的是:StringBuffer是线程安全的,而StringBuilder没有实现线程安全功能。
执行速度:
StringBuilder>StringBuffer>String
操作少量数据用String;多线程操作字符串缓冲区下操作大量数据用StringBuffer;单线程操作字符串缓冲区下操作大量数据用StringBuilder。
15、Java常用包、集合、线程、io、数据库索引
java常用包:
java.io包:通过文件系统,数据流和序列化提供系统的输入与输出
java.lang包:提供了java语言进行程序设计的基础类
java.util包:集合类。日期等各种实用工具类
java.sql包:Java访问并处理存储数据源中的数据api
java.net包:提供实现网络应用与开发的类
集合:
Java集合大致可分为:List、Set、queue和Map四种体系;
其中List代表有序、重复的集合;Set代表无序、不可重复的集合;Queue代表一种队列集合实现;Map接口中键和值一一映射。
线程:
java语言主要提供了两种实现线程的方式:
①继承Thread类创建线程类
②实现Runable接口创建线程类
①:
(1)定义继承Thread类,并重写Thread类的run()方法,该run()方法的方法体就代表了线程需要完成的任务。因此把run()方法称为线程执行体。
(2)创建Thread子类的实例,即创建子线程对象。
(3)调用线程对象的start()方法来启动该线程。
②:
(1)定义实现Runable接口,并重写Runable接口的run()方法,该run()方法的方法体就代表了线程需要完成的任务。
(2)创建Runable实现类的实例,并以此实例作为Thread的target来创建Thread对象,该Thread对象才是真正的线程对象。
(3)调用该Thread对象的start()方法来启动该线程。
16、空指针异常怎么避免?
①加判断:if(status.equals(success)){}
②初始化默认值
③返回空集合:return list ==null ? new ArrayList() : list;
17、怎么通过内部循环结束整体循环
break跳出循环、结束循环(如果是内层循环,仅终止内层循环,外层循环不会终止)
continue跳出本次循环、继续下次循环
return程序返回到调用某方法的地方
break+标签:跳出循环到标签处,结束标签内的循环,在多重循环的最外层设置标签,配合break可终止整个循环
(设置a for循环外加“a:” break a;)
continue+标签:跳出循环到标签处,结束此次循环,从此标签处开始下一次循环
18、MVC模型
M-model模型是指模型表示业务规则
V-view试图是指用户看到并与之交互的界面
C-controller控制器是指控制器接受用户的输入并调用模型和试图去完成用户的需求,控制器本身不输出任何东西和做任何处理
19、面向对象是什么
面向对象是把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描述某个事件在整个解决问题的步骤中的行为。
面向过程:就是分析出解决问题所需的步骤,然后用函数把这些步骤一步步实现,使用的时候一个个依次调用就可以了。
20、Java线程池、Java的jvm、 数据库sql优化、spring特征
Java的线程池通过Executor框架来实现
用到Executor、ExecutorService
ThreadPoolExecutor、Future、FutureTask等几个大类
21、什么是三次握手?
22、什么是依赖注入?
23、GC是什么?原理?(垃圾回收)
24、REST接口用到的注解?以及注解的作用?