作者: 星哥 Wechat/QQ: 574373426
整理不易,感谢支持,欢迎 收藏转发分享, 专注IT职业教育多年,学编程找星哥

目录

  • JAVA基础
  • 数据库
  • 前端
  • JAVAWEB
  • 框架
  • 微服务/高并发
  • 常见笔试,机试题

JAVA基础

1. JDK

JDK是JAVA的开发工具包,包含JRE
JRE是JAVA的运行环境,包含JVM
JVM是JAVA的虚拟机
在编译期间 .java文件编译程.class字节码文件
在运行期间 JVM加载.class字节码文件并运行
因此JAVA具有跨平台特性,只要在不同操作系统上安装对应的JVM即可

2. 八大基本数据类型

整型: byte(1字节) short(2字节) int(4字节) long(8字节)
浮点型: float(4字节) double(8字节)
字符型: char(2字节)
布尔型: boolean(1字节)

3. 分支结构 switch() 方法中可以传递什么类型参数

共6种分别是:
byte short int char 枚举(JDK1.5以后支持) String(JDK1.7以后支持)

4. break,continue,return区别

break: 用在循环中,用于结束循环,break后面的代码不执行
continue: 用在循环中,跳过当次循环,执行下次循环
return: 用在方法中,用于结束当前方法,并返回相应的结果,return后面的代码不执行

5. 局部变量,成员变量,静态变量的生命周期

静态变量随着类的加载而存在,随着类的消失而消失。作用在类中,方法外;
成员变量随着对象的创建而存在,随着对象被回收而释放。作用在类中,方法外;
局部变量随着方法的创建而存在,随着方法被回收而释放。作用方法中,或者方法的形式参数;

6. 冒泡排序算法

冒泡排序思想
如果前面的数比后面的大,就进行交换

int arr[] = {8,3,1,4,5,9}
for(int i = 0; i < arr.length -1; i++){for(int j = 0 ;j < arr.length - i - 1; j++){if(arr[j] > arr[j+1]){int t = arr[j];arr[j] = arr[j+1];arr[j+1] = t;}}
}

7. 二分查找法

二分查找法又称为折半查找,适合 有序 的列表
思路: 将列表中间位置元素和目标元素进行比较,如果相等,则查找成功;
如果不相等,则查找的元素一定在表的前半部分或后半部分。
在判断,如果目标元素大于中间元素,则进一步查找后半部分,否则进一步查找前半部分。
重复以上过程,直到找到满足条件的元素,使查找成功;
如果还没有找到,则此元素不在列表里面。

 //使用循环的方式实现public static void main(String[] args) {//定义一个数组 必须是有序的int [] arr = {1,2,3,4,5,6,7,8,9};int value = 7;  //定义目标植 例如查询 7int first = 0;  //第一个元素下标int last = arr.length-1;    //最后一个元素下标int center = 0; //折半后的中间下标 先给个默认值//如果传入的值比第一个元素小 或者比最后一个值大 则没必要进行比较if(value <arr[first] || value>arr[last]){return;}while (first<=last){center = (first+last)/2;if (arr[center] > value){//如果中间值比value大则value在左侧区域//折半后最大下标为 center-1last = center-1;}else if(arr[center] < value){//如果中间值比value小则value在右侧区域//折半后最大下标为 center+1first = center+1;}else {//否则 正好等于中间值 目标值的下标就是 centeSystem.out.println("下标为"+center);return;}}}

8. 构造方法,静态代码块,构造代码块

静态代码块: 用static声明,jvm加载类时执行,仅执行一次
构造代码块: 每一次创建对象就会执行构造代码块,而且先于构造方法执行
构造方法: 对象一旦创建就会调用与之相对应的构造方法
执行顺序: 静态代码块>构造代码块>构造方法

9. 重写和重载的区别

重写发生在父子类中,子类重写父类里的方法,方法名相同,返回值类型相同,参数列表相同,方法体不同
重载发生在一个类中,方法名相同,参数数量类型不能相同,方法体不同,跟返回值类型无关

10.抽象类和接口的区别

抽象类用abstract来修饰,抽象类里可以有普通方法,也可以有构造方法,抽象方法不能用private修饰,子类用extends来继承,只能单继承
接口用interface来修饰,接口中的方法全部是抽象方法,jdk1.8以后可以有默认方法和静态方法,接口中的变量都是常量,默认用public修饰不能用其他,子类使用implements实现,可以实现多个接口

11. this和super区别

this是自身的一个对象,代表对象本身,可以理解为:指向对象本身的一个指针
super可以理解为是指向自己超(父)类对象的一个指针,而这个超类指的是离自己最近的一个父类。

12. 面向对象三大特性

封装: 属性私有化,行为公开化.将数据进行私有化保护,尽可能隐藏内部细节,只保留一些对外的方法与外部发生联系.
继承: 将子类共性的内容统一提取到父类,子类拥有父类非private修饰的属性和方法和自己特有的方法,也可以重写父类的方法,进行扩展
多态: 必须有继承,必须有重写,必须形成向上造型,对外提供统一的引用,运行期间根据实际情况决定,能调出哪些方法看父类,如果有重写一定执行重写了的方法

13. 异常

从继承关系可知:Throwable是异常体系的根,它继承自Object。Throwable有两个体系:Error和Exception
Error表示严重的错误,程序对此一般无能为力,例如 内存耗尽,无法加载某个类,栈溢出等
而Exception则是运行时的错误,它可以被捕获并处理,例如下标越界异常,未找到文件异常等

RuntimeException无需强制捕获,非RuntimeException(Checked Exception)需强制捕获,或者用throws声明
捕获异常使用try…catch语句,把可能发生异常的代码放到try {…}中,然后使用catch捕获对应的Exception及其子类
也可以不捕获异常将异常抛给调用房,此时在方法定义的时候,使用throws Xxx表示该方法可能抛出的异常类型。调用方在调用的时候,必须强制捕获这些异常,否则编译器会报错。

14. throw和throws区别

throw语句用在方法体内,表示抛出异常,由方法体内的语句处理。
throws语句用在方法声明后面,表示再抛出异常,由该方法的调用者来处理。 throws主要是声明这个方法会抛出这种类型的异常,使它的调用者知道要捕获这个异常。

15. final和finally区别

final 用于声明属性,方法和类, 分别表示属性不可变, 方法不可覆盖, 类不可继承.
finally 是异常处理语句结构的一部分,表示总是执行

16. String和new String()区别

String存放在字符串常量池有且仅有一份
new String会在堆中每new一次开辟一块新的内存空间
常见面试题:
String str1=“abc”;
String str2=“abc”;
String str3=new String(“abc”);
String str4=new String(“abc”);
System.out.println(str1 == str2); true在常量池只有一份地址相同
System.out.println(str2 == str3); false一个在常量池一个在堆中
System.out.println(str3 == str4); false每new一次开辟一块新的空间

17. String,StringBuilder,StringBuffer区别

String 是不可变的对象, 因此在每次对 String 类型进行改变的时候,都会生成一个新的 String 对象,然后将指针指向新的 String 对象,所以经常改变内容的字符串最好不要用 String
StringBuffer 每次会对 StringBuffer 对象本身进行操作,而不是生成新的对象,再改变对象引用,线程安全,速度较慢
StringBuilder jdk1.5以后新增的类和StringBuffer功能相似,线程不安全,速度快
执行效率 StringBuilder>StringBuffer>String

18. String常用的api

int hashCode() 返回此字符串的哈希码。
boolean equals(Object anObject) 将此字符串与指定的对象比较,比较的是重写后的串的具体内容
String toString() 返回此对象本身(它已经是一个字符串!)。
int length() 返回此字符串的长度。
String toUpperCase() 所有字符都转换为大写。
String toLowerCase() 所有字符都转换为小写
boolean startsWith(String prefix) 测试此字符串是否以指定的元素开头。
boolean endsWith(String suffix) 测试此字符串是否以指定的字符串结束。
char charAt(int index) 返回指定索引/下标处的 char 值/字符
int indexOf(String str) 返回指定字符在此字符串中第一次出现处的索引。
int lastIndexOf(String str) 返回指定字符在此字符串中最后一次出现处的索引。
String concat(String str) 将指定字符串连接/拼接到此字符串的结尾,注意:不会改变原串
String[] split(String regex) 根据给定元素来分隔此字符串。
String trim() 返回去除首尾空格的字符串
byte[] getBytes() 把字符串存储到一个新的 byte 数组中
String substring(int beginIndex) 返回一个新子串,从指定下标处开始,包含指定下标
String substring(int beginIndex, int endIndex) 返回一个新子串,从执定下标开始,到结束下标为止,但不包含结束下标
static String valueOf(int i) 把int转成String

19. ==和equals()区别

当使用= =比较时,如果相比较的两个变量是引用类型,那么比较的是两者的物理地值(内存地址),如果相比较的两个变量都是数值类型,那么比较的是具体数值是否相等。
当使用equals()方法进行比较时,比较的结果实际上取决于equals()方法的具体实现
众所周知,任何类都继承自Object类,因此所有的类均具有Object类的特性,比如String、integer等,他们在自己的类中重写了equals()方法,此时他们进行的是数值的比较,而在Object类的默认实现中,equals()方法的底层是通过==来实现的。

20. 数组获取长度和String获取长度区别

数组是 .length属性
String是 .length()方法

21. 集合

集合类与数组不同的是,数组长度固定,而集合类的长度是可变的,数组用来存放基本类型的数据,而集合用来存放对象。常用的有List集合、Set集合和Map集合。

22. List和Set区别

List 接口实例存储的是有序的,可以重复的数据。
Set 接口实例存储的是无序的,不可重复的数据。

23. ArrayList和LinkedList区别

ArrayList是实现了基于动态数组的数据结构,查询块,增删慢
LinkedList的实现是基于双向链表,查询慢,增删快

24. ArrayList动态扩容机制

在JDK1.8中,如果通过无参构造的话,初始数组容量为0,当真正对数组进行添加时(即添加第一个元素时),才真正分配容量,默认分配容量为10;当容量不足时(容量为size,添加第size+1个元素时),先判断按照1.5倍(位运算)的比例扩容能否满足最低容量要求,若能,则以1.5倍扩容,否则以最低容量要求进行扩容。

25. HashMap存储过程原理

HashMap的结构是数组+链表 或者 数组+红黑树 的形式
HashMap底层的Entry[ ]数组,初始容量为16,加载因子是0.75f,扩容按约为2倍扩容
当存放数据时,会根据hash(key)%n算法来计算数据的存放位置,n就是数组的长度,其实也就是集合的容量
当计算到的位置之前没有存过数据的时候,会直接存放数据
当计算的位置,有数据时,会发生hash冲突/hash碰撞
解决的办法就是采用链表的结构,在数组中指定位置处以后元素之后插入新的元素
也就是说数组中的元素都是最早加入的节点
如果链表的长度>8且数组长度>64时,链表会转为红黑树,当链表的长度<6时,红黑树会重新恢复成链表

26. 什么是进程和线程

进程是对运行时程序的封装,是系统进行资源调度和分配的的基本单位,实现了操作系统的并发;
线程是进程的子任务,是CPU调度和分派的基本单位,用于保证程序的实时性,实现进程内部的并发;
一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程。线程依赖于进程而存在。
进程在执行过程中拥有独立的内存单元,而多个线程共享进程的内存。

27. 线程的几种状态


新建状态(New) : 当线程对象创建后就进入了新建状态.如:Thread t = new MyThread();
就绪状态(Runnable):当调用线程对象的start()方法,线程即为进入就绪状态.
处于就绪(可运行)状态的线程,只是说明线程已经做好准备,随时等待CPU调度执行,并不是执行了t.start()此线程立即就会执行
运行状态(Running):当CPU调度了处于就绪状态的线程时,此线程才是真正的执行,即进入到运行状态
就绪状态是进入运行状态的唯一入口,也就是线程想要进入运行状态状态执行,先得处于就绪状态
阻塞状态(Blocked):处于运状态中的线程由于某种原因,暂时放弃对CPU的使用权,停止执行,此时进入阻塞状态,直到其进入就绪状态才有机会被CPU选中再次执行.
根据阻塞状态产生的原因不同,阻塞状态又可以细分成三种:
等待阻塞:运行状态中的线程执行wait()方法,本线程进入到等待阻塞状态
同步阻塞:线程在获取synchronized同步锁失败(因为锁被其他线程占用),它会进入同步阻塞状态
其他阻塞:调用线程的sleep()或者join()或发出了I/O请求时,线程会进入到阻塞状态.当sleep()状态超时.join()等待线程终止或者超时或者I/O处理完毕时线程重新转入就绪状态
死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期

28. 创建线程几种方式

继承Thread类,重写run方法
实现Runnable接口,重写run()方法
通过Callable和Future创建线程
使用线程池,如Executor框架

29. start()方法和run()区别

start() :
它的作用是启动一个新线程。
通过start()方法来启动的新线程,处于就绪(可运行)状态,并没有运行,一旦得到cpu时间片,就开始执行相应线程的run()方法
run() :
run()就和普通的成员方法一样, 可以被重复调用, 定义线程执行内容。
如果直接调用run方法,并不会启动新线程

30. 线程安全

当多个线程同时操作共享资源数据时,有可能会出现脏数据,数据不统一,就出现了线程安全问题
有三种方式可以避免线程安全问题:
1.同步代码块
2.同步方法
3.Lock锁机制

31. 什么是死锁,如何避免死锁

死锁: 当线程A持有独占锁a,并尝试去获取独占锁b的同时,线程B持有独占锁b,并尝试获取独占锁a的情况下,就会发生AB两个线程由于互相持有对方需要的锁,而发生的阻塞现象,我们称为死锁。
造成死锁必须达成的4个条件(原因)
互斥条件:一个资源每次只能被一个线程使用。
请求与保持条件:一个线程因请求资源而阻塞时,对已获得的资源保持不放。
不剥夺条件:线程已获得的资源,在未使用完之前,不能强行剥夺。
循环等待条件:若干线程之间形成一种头尾相接的循环等待资源关系。
如何避免死锁:
加锁顺序
加锁时限
死锁检测

32. 悲观锁和乐观锁

悲观锁:悲观锁在操作数据时比较悲观,认为别人会同时修改数据。因此操作数据时直接把数据锁住,直到操作完成后才会释放锁;上锁期间其他人不能修改数据。悲观锁的实现方式是加锁,加锁既可以是对代码块加锁(如Java的synchronized关键字),也可以是对数据加锁(如MySQL中的排它锁)。
乐观锁:乐观锁在操作数据时非常乐观,认为别人不会同时修改数据。因此乐观锁不会上锁,只是在执行更新的时候判断一下在此期间别人是否修改了数据:如果别人修改了数据则放弃操作,否则执行操作。乐观锁的实现方式主要有两种:CAS机制和版本号机制, Lock采用的就是乐观锁机制

33. synchronized和Lock区别

Lock 是一个接口,实现类为ReentrantLock. 而 synchronized 是 Java 的一个关键字,synchronized基于jvm实现
synchronized悲观锁机制, Lock乐观锁机制
异常是否释放锁:synchronized 在发生异常时候会自动释放占有的锁,因此不会出现死锁;而 lock 发生异常时候,不会主动释放占有的锁,必须手动 unlock 来释放锁,可能引起死锁的发生。(所以最好将同步代码块用 try catch 包起来,finally 中写入 unlock,避免死锁的发生。)
是否响应中断: lock 等待锁过程中可以用 interrupt 来中断等待,而 synchronized 只能等待锁的释放,不能响应中断。
是否知道获取锁:Lock 可以通过 trylock 来知道有没有获取锁,而 synchronized 不能。
在性能上来说: 如果竞争资源不激烈,两者的性能是差不多的,而当竞争资源非常激烈时(即有大量线程同时竞争),此时 Lock 的性能要远远优于 synchronized。所以说,在具体使用时要根据适当情况选择。

34. sleep()和wait()区别

使用方面
从使用的角度来看sleep方法是Thread线程类的方法,而wait是Object顶级类的方法。
sleep可以在任何地方使用,而wait只能在同步方法和同步块中使用。
CPU及锁资源释放:
sleep、wait调用后都会暂停当前线程并让出CPU的执行时间,但不同的是sleep不会释放当前持有对象的锁资源,到时间后会继续执行,而wait会释放所有的锁并需要调用notify/notifyAll方法后重新获取到对象资源后才能继续执行。
异常捕获方面
sleep需要捕获或者抛出异常,而wait/notify/notifyAll则不需要。

35. 线程其他常用方法

Thread类的静态方法sleep()
让当前线程停止执行,把CPU让给其他线程执行,但不会释放对象锁和监控的状态, 到了指定时间后线程又会自动恢复运行状态
Thread类的静态方法yield()
暂停当前正在执行的线程对象(及放弃当前拥有的cup资源),并执行其他线程。yield()做的是让当前运行线程回到可运行状态,以允许具有相同优先级的其他线程获得运行机会。可以理解为暂时放弃本次执行机会,但又肯呢个下次又被选中
Thread类的join()方法
主线程(生成子线程的线程)等待子线程(生成的线程)的终止。也就是在子线程调用了join()方法后面的代码,只有等到子线程结束了才能执行。在很多情况下,主线程创建并启动子线程,如果子线程中要进行大量的耗时运算,主线程将可能早于子线程结束。如果主线程需要知道子线程的执行结果时,就需要等待子线程执行结束
Object类的wait()方法
让当前线程进入等待状态。
Object类的notify()方法
唤醒等待该锁的其中一个线程。notify只会随机选取一个处于等待池中的线程进入锁池去竞争获取锁的机会
Object类的notifyAll()方法
唤醒等待该锁的所有线程,notifyAll会让所有处于等待池的线程全部进入锁池去竞争获取锁的机会

36. 线程池

线程池作用就是限制系统中执行线程的数量。
根 据系统的环境情况,可以自动或手动设置线程数量,达到运行的最佳效果;少了浪费了系统资源,多了造成系统拥挤效率不高。用线程池控制线程数量,其他线程排 队等候。一个任务执行完毕,再从队列的中取最前面的任务开始执行。若队列中没有等待进程,线程池的这一资源处于等待。当一个新任务需要运行时,如果线程池 中有等待的工作线程,就可以开始运行了;否则进入等待队列。

JAVA中创建线程池主要有两类方法,一类是通过Executors工厂类提供的方法,该类提供了4种不同的线程池可供使用。另一类是通过ThreadPoolExecutor类进行自定义创建
通过Executors提供四种线程池,分别为:
newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。
newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。

37. 序列化和反序列化

序列化:就是将对象转化成字节序列的过程。
反序列化:就是将字节序列转化成对象的过程。

38. IO流对象

39. 文件复制

使用文件流对单个文件进行复制,将某个文件复制到指定的路径下:

 //复制文件public static void copy(File f1, String path) throws IOException {System.out.println("***copy***" + f1.getName());FileInputStream in = new FileInputStream(f1);FileOutputStream out = new FileOutputStream(path + f1.getName());byte[] bytes = new byte[512];while ((in.read(bytes)) != -1) {out.write(bytes, 0, bytes.length);}out.close();in.close();}

40. 递归

递归在程序语言中简单的理解是:方法自己调用自己
使用文件流将文件及文件夹下的文件进行复制,采用递归方式

 public static void copyAll(File A, File B) throws IOException {boolean flag = true;if (!B.exists()) {B.mkdir();}String[] a=A.list();//遍历A中所有文件及文件夹for (int i = 0; i < a.length; i++) {System.out.println("a:"+a[i]);//若A中含有文件夹if (new File(A.getPath()+"/"+a[i]).isDirectory()) {File newFolder=null;if (! ( new File(B.getPath()+"/"+a[i]).exists() )) {newFolder = new File(B, a[i]);newFolder.mkdir(); //创建子文件夹}//递归,判断copyAll(new File(A.getPath()+"/"+a[i]), newFolder);}//若A中含有文件,直接复制文件else {copyOtherFile(new File(A.getPath()+"/"+a[i]), B);}           }}

41. 反射

反射是 Java 程序开发语言的特征之一,它允许运行中的 Java 程序获取自身的信息,并且可以操作类或对象的内部属性。通过反射机制,可以在运行时访问 Java 对象的属性,方法,构造方法等。
可以通过三种方式来获取对象
1.通过Object类的getClass方法来获取
2.使用.class的方式
3.使用Class.forName方法

反射机制 想要搞懂反射机制需要了解两个重要概念: 类加载过程 Class对象
类加载的完整过程如下:
在编译时,Java 编译器编译好 .java 文件之后,在磁盘中产生 .class 文件。.class 文件是二进制文件,内容是只有 JVM 能够识别的机器码。
JVM 中的类加载器读取字节码文件,取出二进制数据,加载到内存中,解析.class 文件内的信息。类加载器会根据类的全限定名来获取此类的二进制字节流;然后,将字节流所代表的静态存储结构转化为方法区的运行时数据结构;接着,在内存中生成代表这个类的 java.lang.Class 对象。
加载结束后,JVM 开始进行连接阶段(包含验证、准备、初始化)。经过这一系列操作,类的变量会被初始化。
要想使用反射,首先需要获得待操作的类所对应的 Class 对象
Java 中,无论生成某个类的多少个对象,这些对象都会对应于同一个 Class 对象。这个 Class 对象是由 JVM 生成的,通过它能够获悉整个类的结构。所以,java.lang.Class 可以视为所有反射 API 的入口点。
反射的本质就是:在运行时,把 Java 类中的各种成分映射成一个个的 Java 对象。
举例来说,假如定义了以下代码:
User user = new User();
步骤说明:
JVM 加载方法的时候,遇到 new User(),JVM 会根据 User 的全限定名去加载 User.class 。
JVM 会去本地磁盘查找 User.class 文件并加载 JVM 内存中。
JVM 通过调用类加载器自动创建这个类对应的 Class 对象,并且存储在 JVM 的方法区。注意:一个类有且只有一个 Class 对象。

反射其实就是 运行过程中直接通过 目标类对应的Class对象获取

42. 单例设计模式

单例模式是 Java 中最简单的设计模式之一
这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
懒汉式: 延迟加载,需要的时候再创建对象返回
饿汉式: 类加载时就初始化创建好对象,等待调用返回

43. JAVA内存分配


堆(Heap):线程共享。所有的对象实例以及数组都要在堆上分配。回收器主要管理的对象。
方法区(Method Area):线程共享。存储类信息、常量、静态变量、即时编译器编译后的代码。
方法栈(JVM Stack):线程私有。存储局部变量表、操作栈、动态链接、方法出口,对象指针。
本地方法栈(Native Method Stack):线程私有。为虚拟机使用到的Native 方法服务。如Java使用c或者c++编写的接口服务时,代码在此区运行。
程序计数器(Program Counter Register):线程私有。有些文章也翻译成PC寄存器(PC Register),同一个东西。它可以看作是当前线程所执行的字节码的行号指示器。指向下一条要执行的指令。

数据库

1. 数据库三大范式是什么

第一范式:每个列都不可以再拆分。
第二范式:在第一范式的基础上,非主键列完全依赖于主键,而不能是依赖于主键的一部分。
第三范式:在第二范式的基础上,非主键列只依赖于主键,不依赖于其他非主键。
在设计数据库结构的时候,要尽量遵守三范式,如果不遵守,必须有足够的理由。比如性能。事实上我们经常会为了性能而妥协数据库的设计。

2. mysql有哪些数据类型


3. MySQL存储引擎MyISAM与InnoDB区别

Innodb引擎:Innodb引擎提供了对数据库ACID事务的支持。并且还提供了行级锁和外键的约束。它的设计的目标就是处理大数据容量的数据库系统。
MyIASM引擎:不提供事务的支持,也不支持行级锁和外键。

4. 什么是索引

索引是一种特殊的文件(InnoDB数据表上的索引是表空间的一个组成部分),它们包含着对数据表里所有记录的引用指针。
索引是一种数据结构。数据库索引,是数据库管理系统中一个排序的数据结构,以协助快速查询、更新数据库表中数据。
更通俗的说,索引就相当于目录。为了方便查找书中的内容,通过对内容建立索引形成目录。索引是一个文件,它是要占据物理空间的。
索引的优点
可以大大加快数据的检索速度,这也是创建索引的最主要的原因。
通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能。
索引的缺点
时间方面:创建索引和维护索引要耗费时间,具体地,当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,会降低增/改/删的执行效率;
空间方面:索引需要占物理空间

5. 数据库事物

原子性: 事务是最小的执行单位,不允许分割。事务的原子性确保动作要么全部完成,要么完全不起作用;
一致性: 执行事务前后,数据保持一致,多个事务对同一个数据读取的结果是相同的;
隔离性: 并发访问数据库时,一个用户的事务不被其他事务所干扰,各并发事务之间数据库是独立的;
持久性: 一个事务被提交之后。它对数据库中数据的改变是持久的,即使数据库发生故障也不应该对其有任何影响。

6. 什么是存储过程?有哪些优缺点?

存储过程是一个预编译的SQL语句,优点是允许模块化的设计,就是说只需要创建一次,以后在该程序中就可以调用多次。如果某次操作需要执行多次SQL,使用存储过程比单纯SQL语句执行要快。
优点
1)存储过程是预编译过的,执行效率高。
2)存储过程的代码直接存放于数据库中,通过存储过程名直接调用,减少网络通讯。
3)安全性高,执行存储过程需要有一定权限的用户。
4)存储过程可以重复使用,减少数据库开发人员的工作量。
缺点
1)调试麻烦,但是用 PL/SQL Developer 调试很方便!弥补这个缺点。
2)移植问题,数据库端代码当然是与数据库相关的。但是如果是做工程型项目,基本不存在移植问题。
3)重新编译问题,因为后端代码是运行前编译的,如果带有引用关系的对象发生改变时,受影响的存储过程、包将需要重新编译(不过也可以设置成运行时刻自动编译)。
4)如果在一个程序系统中大量的使用存储过程,到程序交付使用的时候随着用户需求的增加会导致数据结构的变化,接着就是系统的相关问题了,最后如果用户想维护该系统可以说是很难很难、而且代价是空前的,维护起来更麻烦。

7. SQL语句主要分为哪几类

数据定义语言DDL(Data Ddefinition Language)CREATE,DROP,ALTER

主要为以上操作 即对逻辑结构等有操作的,其中包括表结构,视图和索引。

数据查询语言DQL(Data Query Language)SELECT

这个较为好理解 即查询操作,以select关键字。各种简单查询,连接查询等 都属于DQL。

数据操纵语言DML(Data Manipulation Language)INSERT,UPDATE,DELETE

主要为以上操作 即对数据进行操作的,对应上面所说的查询操作 DQL与DML共同构建了多数初级程序员常用的增删改查操作。而查询是较为特殊的一种 被划分到DQL中。
数据控制功能DCL(Data Control Language)GRANT,REVOKE,COMMIT,ROLLBACK
主要为以上操作 即对数据库安全性完整性等有操作的,可以简单的理解为权限控制等。

8. SQL 约束有哪几种

NOT NULL 非空约束: 用于控制字段的内容一定不能为空(NULL)。
UNIQUE 唯一约束: 控件字段内容不能重复,一个表允许有多个 Unique 约束。
PRIMARY KEY 主键约束: 也是用于控件字段内容不能重复,但它在一个表只允许出现一个。
FOREIGN KEY 外键约束: 用于预防破坏表之间连接的动作,也能防止非法数据插入外键列,因为它必须是它指向的那个表中的值之一。
CHECK 检查约束: 用于控制字段的值范围。

9. 关联查询

六种关联查询
交叉连接(CROSS JOIN)
内连接(INNER JOIN)
外连接(LEFT JOIN/RIGHT JOIN)
联合查询(UNION与UNION ALL)
全连接(FULL JOIN

交叉连接
SELECT * FROM A,B(,C)或者SELECT * FROM A CROSS JOIN B (CROSS JOIN C)#没有任何关联条件,结果是笛卡尔积,结果集会很大,没有意义

内连接
内连接分为三种
等值连接:ON A.id=B.id
不等值连接:ON A.id > B.id
自连接:SELECT * FROM A T1 INNER JOIN A T2 ON T1.id=T2.pid
很少使用内连接(INNER JOIN)SELECT * FROM A,B WHERE A.id=B.id或者SELECT * FROM A INNER JOIN B ON A.id=B.id多表中同时符合某种条件的数据记录的集合,INNER JOIN可以缩写为JOIN

外连接
左外连接:LEFT OUTER JOIN, 以左表为主,先查询出左表,按照ON后的关联条件匹配右表,没有匹配到的用NULL填充,可以简写成LEFT JOIN
右外连接:RIGHT OUTER JOIN, 以右表为主,先查询出右表,按照ON后的关联条件匹配左表,没有匹配到的用NULL填充,可以简写成RIGHT JOIN

联合查询
SELECT * FROM A UNION SELECT * FROM B UNION …
就是把多个结果集集中在一起,UNION前的结果为基准,需要注意的是联合查询的列数要相等,相同的记录行会合并
如果使用UNION ALL,不会合并重复的记录行
效率 UNION 高于 UNION ALL

全连接
MySQL不支持全连接
可以使用LEFT JOIN 和UNION和RIGHT JOIN联合使用
SELECT * FROM A LEFT JOIN B ON A.id=B.id UNIONSELECT * FROM A RIGHT JOIN B ON A.id=B.id

10. 什么是子查询

条件:一条SQL语句的查询结果做为另一条查询语句的条件或查询结果
嵌套:多条SQL语句嵌套使用,内部的SQL查询语句称为子查询。

11. varchar与char的区别

char的特点

char表示定长字符串,长度是固定的;

如果插入数据的长度小于char的固定长度时,则用空格填充;

因为长度固定,所以存取速度要比varchar快很多,甚至能快50%,但正因为其长度固定,所以会占据多余的空间,是空间换时间的做法;

对于char来说,最多能存放的字符个数为255,和编码无关

varchar的特点

varchar表示可变长字符串,长度是可变的;

插入的数据是多长,就按照多长来存储;

varchar在存取方面与char相反,它存取慢,因为长度不固定,但正因如此,不占据多余的空间,是时间换空间的做法;

对于varchar来说,最多能存放的字符个数为65532

总之,结合性能角度(char更快)和节省磁盘空间角度(varchar更小),具体情况还需具体来设计数据库才是妥当的做法。

12. drop、delete与truncate的区别

13. SQL优化

关键点:
最大化利用索引。
尽可能避免全表扫描。
减少无效数据的查询。
理解 SQL 优化原理 ,首先要搞清楚 SQL 执行顺序。
SELECT …
FROM
<表名> # 选取表,将多个表数据通过笛卡尔积变成一个表。
ON
<筛选条件> # 对笛卡尔积的虚表进行筛选
JOIN <join, left join, right join…>
<join表> # 指定join,用于添加数据到on之后的虚表中,例如left join会将左表的剩余数据添加到虚表中
WHERE
<where条件> # 对上述虚表进行筛选
GROUP BY
<分组条件> # 分组
<SUM()等聚合函数> # 用于having子句进行判断,在书写上这类聚合函数是写在having判断里面的
HAVING
<分组筛选> # 对分组后的结果进行聚合筛选
DISTINCT # 数据除重
ORDER BY
<排序条件> # 排序
LIMIT
<行数限制>

优化方式:
尽量在字段后面使用模糊查询。
尽量避免使用 in 和 not in,会导致引擎走全表扫描
如果是连续数值,可以用 between 代替。
尽量避免使用 or,会导致数据库引擎放弃索引进行全表扫描,可以用 union 代替 or
尽量避免进行 null 值的判断,会导致数据库引擎放弃索引进行全表扫描, 可以给字段添加默认值 0,对 0 值进行判断
尽量避免在 where 条件中等号的左侧进行表达式、函数操作,会导致数据库引擎放弃索引进行全表扫描
使用索引列作为条件进行查询时,需要避免使用<>或者!=等判断条件
order by 条件要与 where 中条件一致,否则 order by 不会利用索引进行排序
避免出现 select *
等等

14. limit分页写法

limit 当前页-1*每页显示条数 , 每页显示条数
例如,有21条数据,每页显示3条,查询第4页数据
limit 9,3

15. 数据库隔离级别

1.串行化(serializable):一个事务一个事务的执行
2.可重复读(Repeatable-Read) 可重复读,无论其他事务是否修改并提交了数据,在这个事务中看到的数据值始终不受其他事务影响 (mysql数据库所默认的级别)
3.读已提交(Read Committed) 读取已提交,其他事务提交了对数据的修改后,本事务就能读取到修改后的数据值(大多数数据库默认的隔离级别)
4.读未提交:(Read Uncommitted) 读取未提交,其他事务只要修改了数据,即使未提交,本事务也能看到修改后的数据值。

前端

面向后端开发人员必会的,并非专业web前端

1. CSS 选择器有哪些

1.id选择器( # myid)
2.类选择器(.myclassname)
3.标签选择器(div, h1, p)
4.相邻选择器(h1 + p)
5.子选择器(ul > li)
6.后代选择器(li a)
7.通配符选择器( *)
8.属性选择器(a[rel = “external”])
9.伪类选择器(a: hover, li: nth - child)

2. undefined与null有何异同

null是一个表示"无"的对象,转为数值时为0;undefined是一个表示"无"的原始值,转为数值时为NaN。
undefined:
(1)变量被声明了,但没有赋值时,就等于undefined。
(2) 调用函数时,应该提供的参数没有提供,该参数等于undefined。
(3)对象没有赋值的属性,该属性的值为undefined。
(4)函数没有返回值时,默认返回undefined。
null:
(1) 作为函数的参数,表示该函数的参数不是对象。
(2) 作为对象原型链的终点。

3. === 和 == 区别

相同点:都是判定两个值是否相等
不同点:=== 会判断类型,而 == 不会判断类型

4. 什么是AJAX

Ajax是一种异步请求数据的web开发技术,对于改善用户的体验和页面性能很有帮助。简单地说,在不需要重新刷新页面的情况下,Ajax 通过异步请求加载后台数据,并在网页上呈现出来。
jQuery发起ajax请求写法 :
$.ajax({name:val, name:val,…}) 可以手动指定各种属性参数
$.post(url, data, func, dataType) 使用POST方式执行Ajax请求
$.get(url, data, func, dataType) 使用GET方式执行Ajax请求
$.getJSON(url, data, func) 使用GET方式执行Ajax请求,从服务器加载JSON格式数据
$.load(url, data, func) 该方法将服务器加载的数据直接插入到指定DOM中
使用axios发起ajax请求 :
get请求: axios.get() axios.delete()
post请求: axios.post() axios.put() 传递的是js对象后台需要使用@RequestBody接收

5. 对MVVM的理解

Model 代表数据模型,数据和业务逻辑都在Model层中定义;泛指后端进行的各种业务逻辑处理和数据操控,对于前端来说就是后端提供的 api 接口。
View 代表UI视图,负责数据的展示;视图层,也就是用户界面。前端主要由 HTML 和 CSS 来构建 。
ViewModel 负责监听 Model 中数据的改变并且控制视图的更新,处理用户交互操作;
Model 和 View 并无直接关联,而是通过 ViewModel 来进行联系的,Model 和 ViewModel 之间有着双向数据绑定的联系。因此当 Model 中的数据改变时会触发 View 层的刷新,View 中由于用户交互操作而改变的数据也会在 Model 中同步

6. vue常见指令

v-text 等同于{{ }}双大括号 主要用来更新 textContent,可以等同于 JS 的 text 属性。纯文本原样输出
v-html 为了输出真正的 HTML,可以用 v-html 指令。它等同于 JS 的 innerHtml 属性。可以解析html代码
v-if 可以实现条件渲染,Vue 会根据表达式的值的真假条件来渲染元素。
v-show 也是用于根据条件展示元素。和 v-if 不同的是,如果 v-if 的值是 false,则这个元素被销毁,不在 dom 中。但是 v-show 的元素会始终被渲染并保存在 dom 中,它只是简单的切换 css 的 dispaly 属性
v-for 循环遍历
v-bind 用来动态的绑定一个或者多个特性。没有参数时,可以绑定到一个包含键值对的对象。常用于动态绑定 class 和 style。以及 href 等。简写为一个冒号 :
v-model 这个指令用于在表单上创建双向数据绑定。
v-on 主要用来监听 dom 事件, 以便执行一些代码块 表达式可以是一个方法名 简写为: @

JAVAWEB

1. cookie 和 session区别

1.cookie和session都是基于键值对的字符串;
2.俩个都是都由后端服务器生成的;
3.cookie字符串保存在客户端浏览器中,session值保存在服务器中,session比cookie更安全

2. get请求和post请求区别

3. JDBC连接数据库步骤

加载驱动
创建数据库连接
创建sql语句对象
执行sql语句
处理结果集
关闭连接

4. Tomcat目录

bin ——Tomcat执行脚本目录
conf ——Tomcat配置文件
lib ——Tomcat运行需要的库文件(JARS)
logs ——Tomcat执行时的LOG文件
temp ——Tomcat临时文件存放目录
webapps ——Tomcat的主要Web发布目录(存放我们自己的JSP,SERVLET,类)
work ——Tomcat的工作目录,Tomcat将翻译JSP文件到的Java文件和class文件放在这里。

5. Json格式

对象格式
{“id”:100,“name”:“tomcat”}

数组格式
[1,2,3,“张三”,“李四”]

嵌套格式
[“java编程”,“美团外卖”,[“吃”,“玩”,{
“id”:100,
“names”: [
{“name”: “梅超风”},
{“name”: “梅超风老公”},
[“张无忌”,“赵敏”]
]
}]

6. JAVA对象转JSON的几种方式

第一种方式:Google的Gson
Gson gson = new Gson();
gson.toJson(目标对象)
第二种方式:阿里巴巴的fastjson
JSON.toJSONString(目标对象)

倒入对应的依赖,调用方法即可

框架

1. Spring IOC和DI

控制反转即IoC (Inversion of Control),它把传统上由程序代码直接操控的对象的调用权交给容器,通过容器来实现对象组件的装配和管理。所谓的“控制反转”概念就是对组件对象控制权的转移,从程序代码本身转移到了外部容器。
Spring IOC 负责创建对象,管理对象(通过依赖注入(DI),装配对象,配置对象,并且管理这些对象的整个生命周期。

控制反转IoC是一个很大的概念,可以用不同的方式来实现。其主要实现方式有两种:依赖注入和依赖查找
依赖注入:相对于IoC而言,依赖注入(DI)更加准确地描述了IoC的设计理念。所谓依赖注入(Dependency Injection),即组件之间的依赖关系由容器在应用系统运行期来决定,也就是由容器动态地将某种依赖关系的目标对象实例注入到应用系统中的各个关联的组件之中。组件不做定位查询,只提供普通的Java方法让容器去决定依赖关系。

2. Spring 框架中都用到了哪些设计模式

工厂模式:BeanFactory就是简单工厂模式的体现,用来创建对象的实例;
单例模式:Bean默认为单例模式。
代理模式:Spring的AOP功能用到了JDK的动态代理和CGLIB字节码生成技术;
模板方法:用来解决代码重复的问题。比如. RestTemplate, JmsTemplate, JpaTemplate。
观察者模式:定义对象键一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知被制动更新,如Spring中listener的实现–ApplicationListener。

3. @Autowired和@Resource之间的区别

@Autowired默认是按照类型装配注入的,默认情况下它要求依赖对象必须存在(可以设置它required属性为false)。
@Resource默认是按照名称来装配注入的,只有当找不到与名称匹配的bean才会按照类型来装配注入。

4. @RequestMapping 注解有什么用

@RequestMapping 注解用于将特定 HTTP 请求方法映射到将处理相应请求的控制器中的特定类/方法。此注释可应用于两个级别:
类级别:映射请求的 URL
方法级别:映射 URL 以及 HTTP 请求方法

5. SpringMVC五大组件运行流程

五大组件
DispatcherServlet 前端控制器 请求的入口
HandlerMapping 映射处理器 请求的派发 负责让请求 和 控制器建立一一对应的关联
Controller 真正的处理器
ViewResolver 视图处理器 最终定位页面的
ModelAndView 封装模型信息和视图信息的

运行流程
DispatcherServlet(前端处理器)收到请求后,依据HandlerMapping的配置,调用相应的Controller来处理
Controller将处理结果封装成ModelAndView对象,返回给DispatcherServlet.
DispatcherServlet依据ViewResolver的解析,调用相应的视图对象,(如jsp)来生成相应的页面

6. @Controller和@RestController区别

@RestController注解等价于@ResponseBody + @Controller。
@RestController和@Controller的共同点是都用来表示Spring某个类是否可以接收HTTP请求
二者区别: @RestController无法返回指定页面,而@Controller可以

7. @ResponseBody和@RequestBody区别

@ResponseBody: 将服务器的数据通过特定的形式返回给浏览器,它可以将数据序列化为JSON、XML返回,不过我们一般用的都是JSON类型
@RequestBody: 用于接收前端发起post请求传递过来的js对象,封装到后端实体类中

8. 接收请求的几种方式

使用自定义变量接收
使用实体类对象接收,如果前端传递的是js对象需要使用@RequestBody
RestFul风格

9. SpringAOP

OOP(Object-Oriented Programming)面向对象编程,允许开发者定义纵向的关系,但并适用于定义横向的关系,导致了大量代码的重复,而不利于各个模块的重用。
AOP(Aspect-Oriented Programming),一般称为面向切面编程,作为面向对象的一种补充,用于将那些与业务无关,但却对多个对象产生影响的公共行为和逻辑,抽取并封装为一个可重用的模块,这个模块被命名为“切面”(Aspect),减少系统中的重复代码,降低了模块间的耦合度,同时提高了系统的可维护性。可用于权限认证、日志、事务处理等。

AOP 领域中的特性术语:
Aspect:切面!包括连接点,切点,通知的一个载体。(如果用AspectJ它就是一个类,如果用springXML的时候它就是一个标签)并且交给spring管理。
Join point:连接点,例如:servlet中的longin()就是连接点;所以连接点在spring中它永远是一个方法。也可以说’目标对象中的方法就是一个连接点‘
pointcut:切点,就是连接点的集合
Advice:通知,就字面意思,但是有2个部分组成,通知内容和通知到哪里去。
通知类型:
Before :前置通知,在连接点方法前调用
After :后置通知,在连接点方法后调用
AfterReturning:返回通知,在连接点方法执行并正常返回后调用,要求连接点方法在执行过程中没有发生异常
AfterThrowing:异常通知,当连接点方法异常时调用
Around:环绕通知,它将覆盖原有方法,但是允许你通过反射调用原有方法,后面会讲

10. JDK动态代理和CGLIB动态代理的区别

Spring AOP中的动态代理主要有两种方式,JDK动态代理和CGLIB动态代理
JDK动态代理只提供接口的代理,不支持类的代理。核心InvocationHandler接口和Proxy类,InvocationHandler 通过invoke()方法反射来调用目标类中的代码,动态地将横切逻辑和业务编织在一起;接着,Proxy利用 InvocationHandler动态创建一个符合某一接口的的实例, 生成目标类的代理对象。
CGLIB: 如果代理类没有实现 InvocationHandler 接口,那么Spring AOP会选择使用CGLIB来动态代理目标类。CGLIB(Code Generation Library),是一个代码生成的类库,可以在运行时动态的生成指定类的一个子类对象,并覆盖其中特定方法并添加增强代码,从而实现AOP。CGLIB是通过继承的方式做的动态代理,因此如果某个类被标记为final,那么它是无法使用CGLIB做动态代理的。

11. Springsecurity

Spring Security 重要核心功能
用户认证(Authentication)和用户授权(Authorization)两个部分
(1)用户认证指的是:验证某个用户是否为系统中的合法主体,也就是说用户能否访问该系统。用户认证一般要求用户提供用户名和密码。系统通过校验用户名和密码来完成认证过程。通俗点说就是系统认为用户是否能登录
(2)用户授权指的是验证某个用户是否有权限执行某个操作。在一个系统中,不同用户所具有的权限是不同的。比如对一个文件来说,有的用户只能进行读取,而有的用户可以进行修改。一般来说,系统会为不同的用户分配不同的角色,而每个角色则对应一系列的权限。通俗点讲就是系统判断用户是否有权限去做某些事情。

12. Mybatis绑定异常解决思路

检查配置文件中sql.xml文件存放的路径是否正确
在sql.xml中 namespace标签的值和接口的全路径是否一致
在sql.xml中 sql语句id和接口中的方法名是否一致

13. #{}和${}区别

#{} : 采用预编译方式,可以防止SQL注入
${}: 采用直接赋值方式,无法阻止SQL注入攻击

14. Mybtais缓存

如果有大量相同的请求查询数据库,则数据库需要执行多次重复的sql,那么并发压力高,查询效率低. 如果引入缓存机制,则可以极大的提升用户的查询的效率
Mybatis中自身提供了缓存机制,可以极大的提高查询效率.
Mybatis系统中默认定义了两级缓存: 一级缓存 和 二级缓存
Mybatis默认条件下只开启一级缓存, 一级缓存是sqlSession级别的, 在同一个sqlSession中查询数据可以共享数据.
二级缓存默认开启. 二级缓存是SqlSessionFactory级别. 同一个工厂创建多个sqlSession共享数据.
Mybatis 也提供了第三方Cache接口,整合第三方缓存(了解)

15. SpringBoot特点

(1)快速开发spring应用的框架
(2)内嵌tomcat和jetty容器,不需要单独安装容器,jar包直接发布一个web应用
(3)简化maven配置,parent这种方式,一站式引入需要的各种依赖
(4)基于注解的零配置思想
(5)和各种流行框架,spring web mvc,mybatis,spring cloud无缝整合

16. SpringBoot核心注解

@SpringBootApplication
这是 Spring Boot 最最最核心的注解,用在 Spring Boot 主类上,标识这是一个 Spring Boot 应用,用来开启 Spring Boot 的各项能力。
其实这个注解就是 @SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan 这三个注解的组合,也可以用这三个注解来代替 @SpringBootApplication 注解

@EnableAutoConfiguration
允许 Spring Boot 自动配置注解,开启这个注解之后,Spring Boot 就能根据当前类路径下的包或者类来配置 Spring Bean。
如:当前类路径下有 Mybatis 这个 JAR 包,MybatisAutoConfiguration 注解就能根据相关参数来配置 Mybatis 的各个 Spring Bean。

@SpringBootConfiguration
用来代替 applicationContext.xml 配置文件,所有这个配置文件里面能做到的事情都可以通过这个注解所在类来进行注册。

17. Spring Boot 的配置文件有哪几种格式?它们有什么区别?

.properties 和 .yml,它们的区别主要是书写格式不同。

18. Spring Boot 的核心配置文件有哪几个?它们的区别是什么?

注意是配置文件的命名
application 配置文件这个容易理解,主要用于 Spring Boot 项目的自动化配置。
bootstrap 是应用程序的父上下文,也就是说 bootstrap 加载优先于 applicaton。
Spring Boot 的核心配置文件是 application 和 bootstrap 配置文件。
加载顺序: bootstrap.yml > application.yml

19. Spring核心组件模块


spring core:提供了框架的基本组成部分,包括控制反转(Inversion of Control,IOC)和依赖注入(Dependency Injection,DI)功能。
spring beans:提供了BeanFactory,是工厂模式的一个经典实现,Spring将管理对象称为Bean。
spring context:构建于 core 封装包基础上的 context 封装包,提供了一种框架式的对象访问方法。
spring jdbc:提供了一个JDBC的抽象层,消除了烦琐的JDBC编码和数据库厂商特有的错误代码解析, 用于简化JDBC。
spring aop:提供了面向切面的编程实现,让你可以自定义拦截器、切点等。
spring Web:提供了针对 Web 开发的集成特性,例如文件上传,利用 servlet listeners 进行 ioc 容器初始化和针对 Web 的 ApplicationContext。
spring test:主要为测试提供支持的,支持使用JUnit或TestNG对Spring组件进行单元测试和集成测试。

20. Spring Bean作用域

singleton:单例, 在Ioc容器中仅存在一个实例,Bean以单例的方式存在, 默认为单例
prototype: 多例, 每次从容器中调用Bean时,都返回一个新的Bean,也就是创建一个新的对象
request: 每次HTTP请求都会创建一个Bean,此作用域适用于WebApplicationContext
session: 同一个Http Session共享一个Bean,不同的Http Session使用不同的Bean,此作用域适用于WebApplicationContext
globalSession: 同一个全局Session共享一个Bean,此作用域适用于WebApplicationContext

21. SpringBean的生命周期

简化:
实例化 Instantiation
属性赋值 Populate
初始化 Initialization
销毁 Destruction

具体
对象创建
1、从xml配置的Bean,@Bean注解,或者Java代码BeanDefinitionBuilder中读取Bean的定义,实例化Bean对象;
2、设置Bean的属性;
3、注入Aware的依赖(BeanNameAware,BeanFactoryAware,ApplicationContextAware);
4、执行通用的方法前置处理,方法: BeanPostProcessor.postProcessorBeforeInitialization()
5、执行 InitalizingBean.afterPropertiesSet() 方法
6、执行Bean自定义的初始化方法init,或者 @PostConstruct 标注的方法;
7、执行方法BeanPostProcessor.postProcessorAfterInitialization()
8、创建对象完毕;
对象销毁
9、执行 DisposableBean.destory() 方法;
10、执行自定义的destory方法或者 @PreDestory 标注的方法;
11、销毁对象完毕

微服务/高并发

1. Nginx负载均衡策略

常见的有: 轮询 权重 IP_HASH

2. Redsi常用数据类型

Redis支持五种数据类型:
string(字符串)
hash(哈希)
list(列表)
set(集合)
zset(sorted set:有序集合)

3. Redis持久化机制

RDB和AOF
默认试RDB方式
RDB:快照的方式,这种方式可以将某一时刻的所有数据都写入硬盘中,当然这也是redis的默认开启持久化方式,保存的文件是以.rdb形式结尾的文件因此这种方式也称之为RDB方式。
AOF:只追加日志文件,这种方式可以将所有客户端执行的写命令记录到日志文件中,AOF持久化会将被执行的写命令写到AOF的文件末尾,以此来记录数据发生的变化,因此只要redis从头到尾执行一次AOF文件所包含的所有写命令,就可以恢复AOF文件的记录的数据集.
两种持久化方案既可以同时使用(aof),又可以单独使用,根据实际需求来决定,同时开启更数据更安全

4. Redis高可用

Redis 支持主从同步,提供 Cluster 集群部署模式,通过 Sentine l哨兵来监控 Redis 主服务器的状态。当主挂掉时,在从节点中根据一定策略选出新主,并调整其他从 slaveof 到新主。
Redis Cluster 使用分片机制,在内部分为 16384 个 slot 插槽,分布在所有 master 节点上,每个 master 节点负责一部分 slot。数据操作时按 key 做 CRC16 来计算在哪个 slot,由哪个 master 进行处理。数据的冗余是通过 slave 节点来保障。

5. Redis哨兵

哨兵必须用三个实例去保证自己的健壮性的,哨兵+主从并不能保证数据不丢失,但是可以保证集群的高可用。当主服务宕机后,并不会影响哨兵,哨兵会发起通讯选择一个新的服务当主服务

6. Redis主从

Redis同时读写,接收大量请求也会导致宕机,此时我们可以设置主从,让主服务master机器去写数据,数据同步给别的slave从服务器去读数据,分发大量请求

7. Redis缓存穿透,缓存击穿,缓存雪崩

缓存穿透。产生这个问题的原因可能是外部的恶意攻击,例如,对用户信息进行了缓存,但恶意攻击者使用不存在的用户id频繁请求接口,导致查询缓存不命中,然后穿透 DB 查询依然不命中。这时会有大量请求穿透缓存访问到 DB。
缓存穿透解决方案:
缓存空对象:是指在持久层没有命中的情况下,对key进行set (key,null)
过滤器拦截: 当收到一个对key请求时先用过滤器验证是key否存在

缓存击穿,就是某个热点数据失效时,大量针对这个数据的请求会穿透到数据源。
缓存击穿解决方案:
分布式互斥锁: 只允许一个线程重建缓存,其他线程等待重建缓存的线程执行完,重新从缓存获取数据即可
永不过期: 设置key永久保存

缓存雪崩,产生的原因是缓存挂掉,这时所有的请求都会穿透到 DB。
缓存雪崩解决方案
可以把缓存层设计成高可用的,即使个别节点、个别机器、甚至是机房宕掉,依然可以提供服务。利用sentinel或cluster实现。
采用多级缓存,本地进程作为一级缓存,redis作为二级缓存,不同级别的缓存设置的超时时间不同,即使某级缓存过期了,也有其他级别缓存兜底
缓存的过期时间用随机值,尽量让不同的key的过期时间不同(例如:定时任务新建大批量key,设置的过期时间相同)

8. SpringCloud Alibaba 组件

Sentinel: 把流量作为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。
Nacos: 一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。
RocketMQ: Apache RocketMQ™ 基于 Java 的高性能、高吞吐量的分布式消息和流计算平台。
GateWay: 网关,是在spring生态系统上构建的API网关服务,它是基于springboot2,spring5,和project Reactor等技术
openfegin: 远程调用

9. SpringCloud组件

服务发现——Eureka
客服端负载均衡——Ribbon
断路器——Hystrix
服务网关——Zuul
分布式配置——Spring Cloud Config

10. Linux常用命令

略 记几个常用的即可
https://www.runoob.com/w3cnote/linux-common-command-2.html

11. 微服务的执行调用流程

参考若依微服务版 执行流程

简化版

常见笔试,机试题

1. 冒泡排序

int arr[] = {8,3,1,4,5,9}
for(int i = 0; i < arr.length -1; i++){for(int j = 0 ;j < arr.length - i - 1; j++){if(arr[j] > arr[j+1]){int t = arr[j];arr[j] = arr[j+1];arr[j+1] = t;}}
}

2. 二分查找发

 //使用循环的方式实现public static void main(String[] args) {//定义一个数组 必须是有序的int [] arr = {1,2,3,4,5,6,7,8,9};int value = 7;  //定义目标植 例如查询 7int first = 0;  //第一个元素下标int last = arr.length-1;    //最后一个元素下标int center = 0; //折半后的中间下标 先给个默认值//如果传入的值比第一个元素小 或者比最后一个值大 则没必要进行比较if(value <arr[first] || value>arr[last]){return;}while (first<=last){center = (first+last)/2;if (arr[center] > value){//如果中间值比value大则value在左侧区域//折半后最大下标为 center-1last = center-1;}else if(arr[center] < value){//如果中间值比value小则value在右侧区域//折半后最大下标为 center+1first = center+1;}else {//否则 正好等于中间值 目标值的下标就是 centeSystem.out.println("下标为"+center);return;}}}

3. 计算某字符出现的次数

import java.util.HashMap;
import java.util.Map;public class Demo {public static void main(String[] args) {String str = "abcabdabc";//计算给定字符串中 每个 字符出现的次数findCharCount(str);//计算给定字符串中 目标 字符串中的次数findCount(str, "ab");}//计算给定字符串中每个字符出现的次数public static void findCharCount(String str) {Map<Character,Integer> map = new HashMap<>();for(int i=0;i<str.length();i++) {char ch = str.charAt(i);//判断map容器中是否包含keyif(map.containsKey(ch)) {//如果集合中已经存在Integer count = map.get(ch);count += 1;//重新存入map.put(ch, count);}else {map.put(ch,1);}}for (Character key : map.keySet()) {Integer value = map.get(key);System.out.println(key+" 出现了 "+value+" 次");}}//计算字符串在给定字符串出现的次数public static void findCount(String src,String des) {int index = 0;int count = 0;while((index = src.indexOf(des, index)) != -1) {count++;index = index + des.length();}System.out.println(des+"出现了 "+count+" 次");}
}

4. sql题

#每个年级分别有男女多少人
select g.grade_name,sum(s.sex='男') as 男,sum(s.sex='女') as 女
from student s join grade g on s.grade_id=g.id
group by g.id;
#每个老师分别带了每个年级男女多少名
select t.teacher_name,g.grade_name,sum(s.sex='男') as 男,sum(s.sex='女') as 女
from student s join grade g on s.grade_id=g.id join teacher t on s.teacher_id=t.id
group by t.id,g.id;

不断更新中,欢迎 关注 收藏 转发 分享
不断更新中,欢迎 关注 收藏 转发 分享
不断更新中,欢迎 关注 收藏 转发 分享

JAVA面试题大全,收藏这一篇就够了相关推荐

  1. java面试题,看我这篇就够了,前端后台应有尽有,包你通过面试

    面试题精华版:https://blog.csdn.net/cencong863251/article/details/88963573 以下为详情版: HTML&CSS部分 1.HTML中定义 ...

  2. Java 面试题大全(一篇足以,建议收藏)

    Java 面试题大全 1.JDK 和 JRE 有什么区别? 2.== 和 equals 的区别是什么? 3.final 在 java 中有什么作用? 4.java 中的 Math.round(-1.5 ...

  3. 收藏的JAVA面试题大全

    基础知识: 1.C++或Java中的异常处理机制的简单原理和应用. 当JAVA程序违反了JAVA的语义规则时,JAVA虚拟机就会将发生的错误表示为一个异常.违反语义规则包括2种情况.一种是JAVA类库 ...

  4. [zz]收藏的JAVA面试题大全

    http://www.blogjava.net/bibi/archive/2006/07/18/58701.html 以前的收藏,估计很少有这么全的面试题集了 ^_^ 基础知识: 1.C++或Java ...

  5. 收藏的JAVA面试题大全(http://www.blogjava.net/bibi/archive/2006/07/18/58701.html)

    以前的收藏,估计很少有这么全的面试题集了 ^_^ 基础知识: 1.C++或Java中的异常处理机制的简单原理和应用. 当JAVA程序违反了JAVA的语义规则时,JAVA虚拟机就会将发生的错误表示为一个 ...

  6. 2020最新Java面试题大全,赶紧收藏吧!

    发现网上很多Java面试题都没有答案,所以花了很长时间搜集整理出来了这套Java面试题大全,希望对大家有帮助哈~ 本套Java面试题大全,全的不能再全,哈哈~ 一.Java 基础 1. JDK 和 J ...

  7. [转载] Java面试题大全(2020版)

    参考链接: Java中的循环 发现网上很多Java面试题都没有答案,所以花了很长时间搜集整理出来了这套Java面试题大全,希望对大家有帮助哈~ 本套Java面试题大全,全的不能再全,哈哈~ 博主已将以 ...

  8. Java面试题大全(2020版)

    发现网上很多Java面试题都没有答案,所以花了很长时间搜集整理出来了这套Java面试题大全,希望对大家有帮助哈~ 本套Java面试题大全,全的不能再全,哈哈~ 博主已将以下这些面试题整理成了一个Jav ...

  9. java面试题大全必备神器

    Java面试题大全 一.JavaSE 部分 基础部分 Java中基本数据类型有哪些? byte:8位,最大存储数据量是255,存放的数据范围是-128~127之间. short:16位, int:32 ...

最新文章

  1. SecureCRT自动保存窗口数据到文件,自动保存日志,每行添加时间戳
  2. SAP ABAP 内表使用
  3. formal method satisfiable check
  4. 【CyberSecurityLearning 17】三层交换技术及实验演示、内部网络规划、HSRP
  5. eclipse不支持泛型_C++ 泛型编程(一)
  6. ios xcode真机调试获取屏幕截屏
  7. [CTO札记]电纸书,将成为教学、阅读潮流
  8. java 删除list_Java 删除List元素的正确方式
  9. java宿舍管理系统代码_JAVA学生宿舍管理系统
  10. 鸿蒙超级终端使用教程,超级终端怎么用(超级终端使用配置教程)
  11. Mac itunes安装旧版本步骤
  12. 页面加载性能之如何测试打开速度
  13. A STRIP OF LAND POJ - 1156 (单调队列)
  14. 南阳oj 144 小柯的苦恼
  15. HTML5 之 Img 标签
  16. Spring Boot 学习之路 使用JPA对Girl 操作
  17. Java批量高效压缩支持加解密支持所有压缩格式(Zip/7z/rar)
  18. arm 2022.10.22
  19. 南方电网计算机招聘笔试,南方电网招聘笔试题(附答案).PDF
  20. 股票实盘交易接口怎样实现自动交易过程?

热门文章

  1. CASAIM自动化精密尺寸测量设备全尺寸检测铸件自动化检测铸件
  2. swift锁屏播放,音乐进度更新,专辑,歌手名显示
  3. C++学习(二八一)Gradle下载目录里的随机码是什么
  4. setup/teardown用法汇总
  5. 用python画几个东西怎么画_一步一步教你如何用Python画一个滑稽
  6. Mybatis中mapper.xml中like模糊查询字符串,日期写法
  7. 微信小程序iconfont不显示解决
  8. python熊猫图案_Python-熊猫
  9. 如何安装用友NC6.5
  10. 群晖存储空间不足-处理方案一