问题
基础
-
字符串连接有哪几种方法?
+
运算符
StringBuilder
StringBuffer
String.concat()
-
String,StringBuffer,StringBuilder区别?
底层,线程安全,性能,使用场景 -
1.底层数据结构:ArrayList 底层数据结构是动态数组,连续存储,LinkedList 底层双向链表,离散存储
2.特点:数据量大时,ArrayList 查询快(因为基于下标操作),增删慢(基于数组的扩容机制);
LinkedList 查询慢(需逐一遍历),增删快(但新增时消耗内存较大,每新增一个元素就会创建一个node对象)
3.扩容机制(需了解) -
java中常用的数据结构有哪些
数组,链表,队列,哈希表,栈,堆,树 -
Linux常用命令有哪些?
修改权限的命令是什么?
怎么查看端口是否被占用?
查看进程? -
对事务的理解?
-
连接查询有哪些?区别是什么?
左连接:
left join
左表为主,右表只会展示符合搜索条件信息,不足为null
右连接:right join
右表为主,左表只会展示符合搜索条件信息,不足为null
内连接:inner join
结合两个表,返回表的交集部分 -
索引的作用?索引有几种
-
sql 优化?
-
脏读,幻读
脏读:一个事务查询另一个事务还未提交的数据,回滚后再次读就读不到了
幻读:就是你一个事务用一样的 SQL 多次查询,结果每次查询都会发现查到一些之前没看到过的数据(事务A执行sql语句查询到数据,接着事务B添加数据并提交,A再次查询就多了几条数据)
其他
-
对IOC,AOP的理解?
-
常用注解?
-
M,V,C各代表什么?
-
redis 数据类型有什么?
字符串string
列表list
哈希hash
集合set
有序集合zset
-
redis单线程原理?
-
redis持久化机制
RDB,AOF -
redis穿透,击穿,雪崩及解决方案?
-
微服务各个模块间如何调用?
nacos+feign -
常用的消息中间件有哪些?
rabbitmq,rocketmq,kafka -
为什么要用消息队列?
高并发请求时流量削峰
非必要的业务逻辑以异步的方式运行,加快响应速度
系统解耦,将消息写入消息队列,需要消息的模块自己从消息队列中订阅,从而有关联的其他模块不需要做任何修改。 -
mybatis 在 xml中接收集合怎么写?
foreach
标签.
collection指定遍历集合的类型
item 当前遍历数据的变量名
separator 指定遍历结果的分割符 -
MyBatis接收多个参数,其中一个参数是集合,另一个参数是字符串的解决办法
parameterType="hashmap"
-
sql怎么根据生日得到年龄?
timestampdiff
-
如何理解静态,动态sql?
动静取决于sql语句在何时被编译和执行
1 基础知识
1.1 基础概念
1. 封装,继承,多态
- 封装: 明确标识出允许外部使用的所有成员函数和数据项内部细节对外部透明,外部调用无需修改或者关心内部实现
- 继承: 继承父类的方法,并作出自己的改变或扩展
- 多态: 父类引用指向子类对象,多态中,编译看左边,运行逻辑看右边
2. 基本数据类型
byte , short , int , long
float , double
boolean
char
3. 重载和重写的区别
- 重载:同一个类中,方法名必须相同,参数类型,个数,顺序不同
返回值和修饰符可以不同
发生在编译时 - 重写:发生在父子类中
方法名,参数列表相同
返回值范围,抛出异常的范围小于等于父类
修饰符范围大于等于父类
如果父类方法访问修饰符为private则子类就不能重写该方法。
4. == 和equals
== : 基本类型比较值
引用类型比较地址值
equals:默认比较地址值
被重写时比较内容
5. String,StringBuffer,StringBuilder
- String底层被final修饰不可变,每次使用都会创建一个新的对象
StringBuffer,StringBuilder是基于原对象的高效拼接操作,以append
追加 - StringBuffer是线程安全的,StringBuilder线程不安全的
- 性能:StringBuilder > StringBuffer > String
- 场景:经常需要改变字符串内容时使用后面两个
优先使用StringBuilder,多线程使用共享变量时使用StringBuffe
6. 接口和抽象类的区别?
1)实现:extends ,implements
2)构造函数:抽象类可以有,接口没有
3)抽象类可以有main方法,接口不能
4)接口可多实现,抽象类只能单继承
5)修饰符:接口默认public ,抽象类是任意访问修饰符
7. string 常用的方法
split():拆分
substring():截取
length()
replace():替换
equals():比较两个对象是否相等
concat() :末尾拼接
getBytes():使用给定的charset将该String编码为字节序列,将结果存储到新的字节数组中。
charAt():返回指定索引值
toLowerCase():转小写
toUpperCase():
8. 单例模式?
某个实例在多线程环境下只会被创建一次
9. 反射 ?
动态获取任意一个类和对象的所有的属性和方法
获取Class对象
- 调用某个对象的 getClass()方法
Person p=new Person();
Class clazz=p.getClass()
; - 调用某个类的 class 属性来获取该类对应的 Class 对象
Class clazz=Person.class
; - 使用 Class 类中的 forName()静态方法(最安全/性能最好)
Class clazz=Class.forName
(“类的全路径”); (最常用)
10. jdk 1.8 新特性
1)Lambda表达式
允许把函数作为一个方法参数
2)接口允许定义默认方法和静态方法
3)函数式接口
有且仅有一个抽象方法的接口叫做函数式接口
可被隐式转换为Lanbda表达式
通常函数式接口上会添加@FunctionalInterface 注解。
11. 异常
Error: 无法预期的错误,无法采取恢复操作
Exception: 可恢复的,可捕捉的
1)运行时异常:空指针,下标越界,算数异常,类型转换,传递非法参数
2)编译异常 IO,SQL
12. 同步锁,死锁,乐观锁,悲观锁
- 同步锁:同一时间只允许一个线程访问共享数据
- 死锁:多线程时同时被阻塞,他们中的一个或全部全都在等待某个资源释放
- 乐观锁:可同时访问共享数据,在数据提交更新时,才会检测数据是否冲突
- 悲观锁:共享资源每次只给一个线程使用,其它线程阻塞,用完后再把资源转让给其它线程
13. 序列化
14. ArrayList & LinkedList 详细
1.2 Linux常用命令
-
ps ,pwd,clear,ls,mkdir,mv
chomd
:文件权限修改 ,
cat,more,vi
cp -r
:连同文件夹一块复制
rm -r
&
最后加&后台运行
kill -9
:终止进程 -
ps
查看运行中进程
ps -aux
查看所有进程及PID,CPU使用率,运行状态 -
查看端口是否被监听,占用
netstat -anp |grep 端口号
-
修改权限
chmod
-
ifconfig
,ip addr
-
解压
tar -xvzf 解压文件命 -C 指定解压路径
Docker常用
-
启动,停止,重启
systemctl start docker stop restart ## 跟随服务启动 systemctl enable docker
-
拉取运行镜像
docker pull tomcat docker run tomcat
-
删除
#删除一个 docker rmi -f 镜像名/镜像ID #删除多个 其镜像ID或镜像用用空格隔开即可 docker rmi -f 镜像名/镜像ID 镜像名/镜像ID 镜像名/镜像ID #删除全部镜像 -a 意思为显示全部, -q 意思为只显示ID docker rmi -f $(docker images -aq)
-
加载镜像
docker load -i 镜像保存文件位置
-
容器命令
docker ps -a
#1. 拉取redis 镜像
docker pull redis:5.0.5
#2.命令启动
docker run -it -d --name redis001 redis:5.0.5 /bin/bash
docker exec -it 容器名/容器ID bash
1.3 集合
- List,Map,Set
1)List 有序,值允许重复
2)Set 无序,不重复,但位置固定
set是根据hashcode来进行数据存储的,这个位置不可控制
3)Map : 散列存储,无序 - List 有序,可重复
ArrayList:底层数据结构是数组,数据量大非头尾操作时查询快,增删慢
LinkedList: 底层数据结构是双向链表,查询慢,增删快 - Set
HashSet:底层是哈希表
LinkedHashSet:底层是链表和哈希表。(插入有序,唯一)
链表保证有序,哈希表保证元素唯一
TreeSet:底层是红黑树(唯一,有序) - HashSet如何保证元素的唯一性?
hashCode() 和 equals() - TreeSet 如何保证元素排序,元素唯一?
1)自然排序,比较器排序
2)根据比较返回值是否是0来决定元素唯一 - Map
HashMap:无序
HashTable:线程安全
LinkedHashMap:有序,是HashMap的一个子类,保存了记录插入的顺序
TreeMap:能够把它保存的记录根据键排序,默认键值的升序排序
1. HashMap的底层原理?
1.8后 数组+链表+红黑树 ,提高了查找效率
默认数组大小为16,负载因子0.75,初始扩容阈值为12,按2倍大小扩容
当链表中元素超过 8 个后,会将链表转换为红黑树,红黑树节点 <= 6时退化为链表
2. Hash冲突
不同对象算出来的数组下标相同
3. HashMap ,HashTable,ConcurrentHashMap区别
扩容机制
hashtable初始size为11,扩容:扩容为原来的2倍+1(newsize = olesize2+1),负载因子为0.75时是负载极限,如果给定了初始化大小就会直接使用。
hashmap初始size为16,扩容:扩容为原来的2倍(newsize = oldsize2),负载因子为0.75时是负载极限,如果给定了初始化大小会将大小扩充为2的幂次方大小。
1.4 线程
- 线程与进程
线程:
进程: - 创建线程的方式?
- 继承Thread类,重写 run 方法
实现简单,不可继承其他类 - 实现Runnable 接口 重写run 方法
避免单继承,解耦 - 实现Callable接口 重写 call 方法
可获取线程执行结果的返回值,并可抛出异常 - 使用线程池创建 java.util.concurrent.Executor 接口
//
Thread thread=new Thread();
thread.satart();
- 继承Thread类,重写 run 方法
- Runnable和Callable的区别?
- Runnable 接口 run 方法无返回值 ,Callable接口call方法有返回值,支持泛型
- Runnable接口run方法只能抛出运行时异常,无法捕获处理
Callable 允许抛出异常且可获取异常信息
- 如何启动一个线程
- 调用start()
- 调用start() 方法可启动线程使得线程进入就绪状态,
run方法只是thread的一个普通方法。在主线程中执行
- 线程状态
新建
就绪
运行
阻塞(等待wait,超时,同步阻塞)
死亡 - 线程池
管理线程
可重复利用已有的线程继续执行任务
没有创建和销毁是的消耗,提升系统响应速度
2 Web
- TCP 与 UDP
Tcp:可靠的,基于IP的传输协议 - Get 和 Post
Get 不安全,数据放在url 中,post的所有操作对用户都是不可见的
get传送的数据量较小 - cookie 和 session?
cookie 存放在客户端电脑,是一个磁盘文件
对客户端可见,可通过设置属性达到长期有效
session是存放在服务器内存中的一个对象
不可见,关闭窗口session就会失效 - jsp 和 servlet
jsp编译后就是servleet
jsp侧重视图,servlet主要用于控制逻辑 - servlet生命周期
对象创建
用户访问
对象销毁 - Ajax 和 axios
Ajax 交互式,快速动态网页应用的技术
局部刷新,异步访问
axios:异步请求
get,post,put,delete - axios 怎么解决跨域问题
通过vue接口代理方式
3 数据库
- 三范式
第一范式:1NF 原子性,列或者字段不能再分,要求属性具有原子性,不可再分解;
第二范式:2NF 唯一性,一张表只说一件事,是对记录的惟一性约束,要求记录有惟
一标识,
第三范式:3NF 直接性,数据不能存在传递关系,即每个属性都跟主键有直接关系,
而不是间接关系 - 事务特性
- 原子性
- 一致性
- 隔离性
- 持久性
- 隔离级别
- 读未提交
- 读已提交
- 可重复读 :mysql默认级别
- 可串行化
- 索引
加快查找速度,提高数据库的性能
分类:
普通索引
唯一索引
联合索引
sql怎么根据生日得到年龄?
常用sql语法
-
查看表结构
desc tablename
-
建表
create table t1( id int not null primary key, name char(20) not null );
-
删表
drop table test;
-
修改表
## 添加字段 alter table t1 add(score int not null); ## 移除字段 alter table t1 drop column score; ## 变更 alter table t1 change name score int not null;
-
插入
# 全字段插入 insert into winton values(001,'zww'),(002,'rs'); # 个别字段插入 insert into 表名(字段名) values(值一),(值二); insert into winton(id) values(004);
-
删除
delete from winton where id=4;
-
更新
update t1 set score=69 where id=2;
-
索引
1)创建普通索引create index wintonIndex on winton (name);
语法:create index 索引名称 on 表名 (字段一,字段二,……);
2)创建唯一索引
create unique index wintonIndex on winton (id);
语法:create unique index 索引名 on 表名 (字段一,字段二,……);
ps:unique index 要求列中数据唯一,不能出现重复。3)移除索引
drop index wintonIndex on winton;
4 框架
Spring
1. IOC 和 DI
- 掌握对象的创建权,让对象的创建不用区new 可直接从容器中获取
- DI是控制反转的具体实现
2. 注入方式
- 构造器注入
- setter注入
- 注解注入
3. AOP
将哪些与业务无关但对多个对象产生影响的公共行为和逻辑,抽取封装为一个可重用的模块,
在特定的切点作增强处理,并回调原对象的方法
4. AOP中的代理
说明: 一般采用代理模式,主要的目的就是为了解耦.将公共的通用的方法(功能/业务)放到代理对象中. 由业务层专注于业务执行即可.
JDK代理模式是java原生提供的API,无需导包
JDK代理要求: 被代理者必须 要么是接口,要么实现接口
灵活: 代理对象应该看起来和被代理者 一模一样!!! (方法相同)
- JDK代理
- CGLIB代理
5. BeanFactory
和 ApplicationContext
BeanFactory :spring 顶层接口
ApplicationContext:是BeanFactory 的子接口
在启动时把所有Bean实例化
6. spring中用到哪些设计模式
工厂
单例
代理
模板方法
观察者
7. Spring 事务的实现方式和原理
8. 通知类型
- 前置通知:before
- 后置通知:after-returning
- 异常通知:after-throwing
- 最终通知:after
- 环绕通知:
9. Spring 的对象默认是单例的还是多例的? 单例 bean 存不存在线程安全问题呢?
- 默认单例,存在线程安全问题
- 解决:避免在bean中定义可变成员变量
10. Spring 常用注解
@ResponseBody
:将返回值转化为JSON串,如果是字符串本身 原数据返回@RequestBody
:接收前端传递给后端的json字符串中的数据,并将JSON串转化为java对象;@RestController
: = @Controller + @ResponseBody@CrossOrigin
@Mapper
: mybatis将当前的接口交给Spring容器管理. Map<类名小写,JDK动态代理对象>@Param
Mybatis中将参数封装为Map集合. @Param(“maxAge”) int maxAge ;mybatis 多值传参需用@Param
注解指定参数@MapperScan
Mybatis中扫描指定包路径的接口 为其创建代理对象.启动类
@RestControllerAdvice
Controller层的全局异常处理@ExceptionHandler
按照某种异常类型进行拦截@TableName(“item_cat”)
MybatisPlus注解POJO与数据表绑定 注意表名@TableId(type = IdType.AUTO)
MybatisPlus注解 标识主键/主键自增@TableField(exist = false)
MybatisPlus注解 标识属性是否存在,及名称是否一致
@SpringBootApplication
@Component、@Service、@Controller、@Repository
@AutoWired、@Qualifier、@Resource
@RequestMapping、@GetMapping、@PostMapping
@PathVariable
获取路径参数
@RequestParam
获取查询参数
SpringMVC
1. SpringMVC 执行流程
- 用户发送请求到前端控制器
- 根据请求调用处理映射器查找对应处理方法
- controller执行业务代码后返回ModeleAndView到前端控制器
- 前端控制器通过视图解析器进行视图渲染
- 然后响应到用户
2. 拦截器与过滤器
拦截器是基于java的反射机制的,过滤器是基于函数回调。
拦截器不依赖与servlet容器,过滤器依赖于servlet容器。
拦截器只能对action请求起作用,过滤器则可以对几乎所有的请求起作用。
拦截器可以访问action上下文、值栈里的对象,而过滤器不能访问。
在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。
拦截器可以获取IOC容器中的各个bean,而过滤器就不行,这点很重要,在拦截器里注入一个service,可以调用业务逻辑。
Mybatis
1. Mybatis
2. 在 mybatis 中,${} 和 #{} 的区别是什么?
#{}
是占位符,预编译处理,可有效防止sql注入
${}
是字符串替换。
Mybatis 在处理#{}
时,会将 sql 中的#{}
替换为?
号,调用 PreparedStatement 的 set
方法来赋值;
Mybatis 在处理${}
时,就是把${}
替换成变量的值。
3. 在 mybatis 中,resultType 和 ResultMap 的区别是什么?
- 列名和要封装实体属性完全一致的话用resultType
- 不一致用ResultMap ,要配置和表的对应关系
4. Mybatis中的动态 sql 标签
- if 是为了判断传入的值是否符合某种规则,比如是否不为空.
- where 标签可以用来做动态拼接查询条件,当和 if 标签配合的时候,不用显示的声明类型 where 1 = 1 这种无用的条件
- foreach 标签可以把传入的集合对象进行遍历,然后把每一项的内容
作为参数传到 sql 语句中. - include 可以把大量的重复代码整理起来,当使用的时候直接 include
即可,减少重复代码的编写; - 适用于更新中,当匹配某个条件后,才会对该字段进行跟新操作
5. Mybatis 缓存机制
- 默认一级缓存,sqlsession级别
- 二级,手动在mapper中添加标签,实现Serializable序列化接口 开启
作用域是mapper的同一个namespace
mybatis 在 xml中接收集合怎么写?
关于Mybatis的遍历的写法
foreach:
1. collection 需要遍历的集合
1.1 数组 关键字: array/list
1.2 list集合 关键字: list/array
1.3 Map<key,array/list> 关键字:key
2. open/close 循环体的开始和结束 可以写到循环之外简化标签
3. item 当前遍历数据的变量名
4. separator 分割符
<select id="findListByIn" resultType="User">
select * from demo_user where id in (
<foreach collection="array" item="id" separator=",">
#{id}
</foreach>
)
</select>