一、基础
1、集合
1)类关系图
2)集合
集合 | ArrayList | Lin | ||
list如何扩容
2、IO
3、多线程
4、异常
5、网络编程
二、框架
1、SpringMVC
1)用户发送请求---》DispatcherServlet中央控制器
2)DispatcherServlet调用处理器映射器找到处理器---》HandlerMapping处理器映射器
3)HandlerMapping返回HandlerExcutionChain给Dispatcher
4)DispatcherServlet---》调用HandlerAdapter---》Controller-
5)Controller---》返回ModelAndView--》HandlerAdapter---》返回ModelAndView--》DispatcherServlet
6)DispatcherServlet---》视图解析viewResolver--》返回view--》DispatcherServlet
7)DispatcherServlet---》渲染视图view
8)DispatcherServlet----》相应用户
2、Spring
Spring生态、Spring技术栈
IOC
AOP
1)如何给单个方法加入切面
Bean
Spring事务
3、Mybatis
1)#{}和${}的区别
2)Mybatis的传值方式
方法1:顺序传参法
| |
#{}
里面的数字代表你传入参数的顺序。
这种方法不建议使用,sql层表达不直观,且一旦顺序调整容易出错。
方法2:@Param注解传参法
| |
#{}
里面的名称对应的是注解@Param
括号里面修饰的名称。
这种方法在参数不多的情况还是比较直观的,推荐使用。
方法3:Map传参法
| |
#{}
里面的名称对应的是Map
里面的key名称。
这种方法适合传递多个参数,且参数易变能灵活传递的情况。
方法4:Java Bean传参法
| |
#{}
里面的名称对应的是User
类里面的成员属性。
这种方法很直观,但需要建一个实体类,扩展不容易,需要加属性,看情况使用。
4、SpringBoot
优点
5、SpringCloud
6、Dubbo
7、Zookeeper
三、数据库
1、存储过程
sql语句需要先编译然后执行,而存储过程(Sroed Procedure)十一组为了完成特定功能的sql语句集,经编译后存储在数据库中,用户通过制定存储过程的名字并给定参数(如果存储过程中带有参数)来调用它
存储过程是可编程的函数,在数据库总创建并保存,可以由sql语句和控制结构组成。当想要在不同的应用程序或平台上执行相同的函数,或者封装特定的动能时,存储过程是非常有用的。数据库中的存储过程可以看做是对编程中面向对象方法的模拟,它允许控制数据的访问方式。
优点
1)增强sql语音的功能和灵活性
2)标准组件式编程
3)较快的执行速度
2、sql语句
from表索引---》where过滤条件---》Group By分组---》Having对分组数据过滤条件---》select那些列,及计算---》order by 排序
left join左连接--》返回包括坐标的所有记录和右边中连接字段相等的记录
right join右连接---》返回包括右表中所有记录和左表中连接字段相等的记录
inner join等值连接---》只返回俩个表中连接字段相等的行
3、数据库优化
3.1、数据库压力变大,读写分离
主从数据库之间的数据需要同步(可以使用mysql自带的master-slave方式实现主从复制)
应用中需要根据业务进行对应的数据源选择(可以采用第三方数据库中间件,例如mycat)
3.2、使用搜索引擎缓解读库的压力
创建普通索引:
CREATE INDEX username ON mytable(username);
创建唯一索引:不重复。列值唯一,但是唯一索引可以有空值。
CREATE UNIQUE INDEX age ON mytable(age);
创建主键索引:主键索引不可以有空值。
ALTER TABLE mytable ADD PRIMARY KEY (id);
删除索引
DROP INDEX 索引的名字 ON 索引的表;
组合索引
ALTER TABLE mytable ADD INDEX name_city_age (username,city,age);
全文索引
CREATE FULLTEXT INDEX index_content ON article(content)
修改索引
ALTER table mytable ADD UNIQUE [indexName] (username(length))
显示索引信息
SHOW INDEX FROM table_name
B+树的查询时间---》树的高度,log(n)
hash存储索引---》o(1)
树---》前中后便利、二叉树、二叉搜索树、平衡二叉树、红黑树、B树、B+树、字典树
1)二叉排序数据
左边根节点小,右边根节点大,并且左右子树都是二叉排序树
有序序列,二叉排序树退化成链表
2)平衡树
插入的时候调整这棵树,让它的节点尽可能平均分布
树的查找性能取决于树的高度,让树尽量平衡,就是为了降低树的高度
3)B树(文件系统索引)
是一种多路搜索树,他的每个子节点可以拥有多于俩个孩子节点。M路的B树最多可以拥有M个孩子节点
进一步降低树的高度
不限制路数,B树就退化成一个有序数组了
文件系统和数据库的索引都是存储在硬盘上,并且如果数据量大的化,不一定能一次性加载到内存中(程序运行时内存情况)
可以每次加载B树的一个节点,然后一步步往下找
假设内存一次最多加载2个数
3)B+树(数据库索引)
是在B树的基础上进行改造,它的数据都在叶子结点,同时叶子结点之间还加了指针形成链表
如果是多条的话,B树需要做局部的中序遍历,可能要跨层访问。而B+树由于所有数据都在叶子结点,不用跨层,
同时由于有链表结构,只需要找到首尾,通过链表就能把所有数据取出来了。
如果一张表用hash更快,但数据库中经常会选择多条,这时候B+树索引有序,并且又有链表相连,它的查询效率比hash就快很多了。
而且数据库中的索引一般是在磁盘上,数据量大的情况可能无法一次装入内存,B+树的设计可以允许数据分批加载,同时树的高度较低,提高查找效率。
3.3、引入缓存机制缓解数据库的压力
Memcache
Redis
3.4、某些场景下,可以对用户的某些IP的访问频率做限制
那这方内存中不合适,放数据库又太麻烦,这个时候可以用Nosql的方式来代替传统的关系型数据库
MongDB
3.5、数据库的水平/垂直拆分
垂直拆分:把数据库不同业务的数据拆分到不同的数据库中
水平拆分:把同一个表中的数据拆分到俩个甚至更多的数据库中,水平拆分的原因是某些业务数据量已经达到单个数据库的瓶颈,这个时候可以采取拆分到多个数据库中
四、数据结构
五、设计模式
六、Linux
七、其他知识
1、Docker
2、jenkins
3、Elasticsearch
八、前端
1、Node.js
2、MVVN
vue.js
九、JVM
十、编程题
1、输入一行字符,分别统计其英文字母、空格、数字和其他字符个数
定义变量 if else循环判断 输入Scanner(System.in)对象; a.nextLine获取String ,
将String转换为toCharArray(); isDigit是否数字 isSpaceChar(arr[i])是否空格 isLetter是否字母
public static void main(String[] args) {
int num = 0;
int spcae = 0;
int england = 0;
int qita= 0;
Scanner s = new Scanner(System.in);
String a = s.nextLine();
char[] arr = a.toCharArray();
for (int i = 0; i < arr.length; i++) {
if(Character.isDigit(arr[i])) {
num++;
}else if(Character.isSpaceChar(arr[i])) {
spcae++;
}else if(Character.isLetter(arr[i])) {
england++;
}else {
qita++;
}
}
System.out.println(num);
System.out.println(spcae);
System.out.println(england);
System.out.println(qita);
}
2、将一个数组逆顺序输出
要求实现函数(不能调用api)
void Rev(int InputArray[].unsigned int n)
【输入】InputArray 给定的数组 n:数组的长度
【输出】InputArray:你顺序的数组
【返回】无
1、将数组转换为ArrayList Arrays.asList(s);
2、调用集合工具类Conllections.reverse(list);
3、list.toArray(s);
public static void main(String[] args) {
int InputArray [] = new int[] {1,2,3,4,6,7};
int n = InputArray.length;
Rev(InputArray, n);
}
public static void Rev(int InputArray[],int n) {
for (int i = n - 1; i >= 0; --i) { // 逆序输出
System.out.print(InputArray[i] + " ");
}
}
3、写一段代码,判断一个包括’{‘,’[‘,’(‘,’)’,’]’,’}’的表达式是否合法(注意看样例的合法规则。)
给定一个表达式A,请返回一个bool值,代表它是否合法。
解析:利用栈来做,当遇到 ‘{‘, ‘[‘, ‘(’ 等就把当前的括号字符入栈,当遇到 ‘)’ , ‘]’ , ‘}’
就出栈一个括号字符。最后判断栈是否为空,栈空则表达式合法,否则不合法
public static void main(String[] args) {
String a = "[a+b*(5-4)]*{x+b+b*({1+2})}";
System.out.println(chkLegal(a));
}
public static boolean chkLegal(String A) {
Stack<Character> stack = new Stack<>();
for(int i=0;i<A.length();i++) {
if(A.charAt(i) == '{'||A.charAt(i) == '[' || A.charAt(i) == '(' ) {
stack.push(A.charAt(i));
}
if(A.charAt(i) == '}'||A.charAt(i) == ']' || A.charAt(i) == ')' ) {
stack.pop();
}
}
return stack.isEmpty();
}
4、List集合排序及去重
使用Collections的sort()方法排序
Collections.sort(intList,new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
// 返回值为int类型,大于0表示正序,小于0表示逆序
return o2-o1;
}
});
使用set集合去重
private List<DeviceServiceLog> removeDuplicateRecord(List<DeviceServiceLog> deviceServiceLogList) {
Set<DeviceServiceLog> set = new TreeSet<>(new Comparator<DeviceServiceLog>() {
@Override
public int compare(DeviceServiceLog o1, DeviceServiceLog o2) {
return o1.getServiceCode().compareTo(o2.getServiceCode());
}
});
set.addAll(deviceServiceLogList);
return new ArrayList<>(set);
}
十一、项目
OOA、OOD、OOP区别
OOA是面向对象的分析 Analysis
OOD是面向对象的设计 Design
OOP是面向对象的编程 Programming
都是相辅相成的: 分析是为了设计,设计是为了编程。
都属于软件工程的不同课题。
本文部分知识来源:
互联网侦察---》面试现场---》作者---》channingbreeze
Java技术栈 https://www.javastack.cn/