java常见面试题
- jdk、jre、jvm区别?
jdk:java的开发工具包,提供了java的开发环境和运行环境,jdk包含jre。
jre:java的运行环境。
jvm:Java 虚拟机(JVM)是运行 Java 字节码的虚拟机实现java的跨平台特性。JVM 有针对不同系统的特定实现(Windows,Linux,macOS),目的是使用相同的字节码,它们都会给出相同的结果。
- equals和==的区别?
1、==:
基本数据类型:比较的是值是否相等
引用数据类型:比较的是引用地址是否相等
2、equals:
基本数据类型:比较的是值是否相等
public boolean equals(Object obj){
return (this==obj)
}
引用数据类型:重写了equals方法,先==比较,如果引用地址相同
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
- int和Integer的区别?
1、Integer是int的包装类,int是基本数据类型
2、Integer必须实例化才能使用,int不需要实例化
3、Integer是对象的引用,new一个Integer时实际生成一个指针指向对象,int直接存数值
4、Integer默认是是null,int默认值是0
- 数据类型有哪些?
1、基本数据类型:
整数型:short(2)、int(4)、long(8)
浮点型:float(4)、double(8)
字符型:char(2)
字节型:byte(1)
布尔型:boolean(1)
2、引用数据类型:String、类、接口、数组
- java类的初始化加载顺序?
顺序由上到下
1、父类的静态成员变量
2、父类的静态代码块
3、子类的静态成员变量
4、子类的静态代码块
5、父类普通成员变量
6、父类构造代码块
7、父类构造方法
8、子类普通成员变量
9、子类构造代码块
10、子类构造方法
public class TestDynamicLoad {
public static void main(String[] args) {
Father son = new Son();
}
}
class Father {
private static String name = getName();
private String address = getAddressParam();
{
System.out.println("*************父类构造代码块************");
}
static {
System.out.println("*************父类静态代码块************");
}
public Father(){
System.out.println("*************父类构造方法************");
}
public static String getName(){
System.out.println("*************父类静态成员变量************");
return null;
}
public String getAddressParam(){
System.out.println("*************父类普通成员变量************");
return null;
}
}
class Son extends Father{
public static String name = getName();
public String address = getAddress();
{
System.out.println("*************子类构造代码块************");
}
static {
System.out.println("*************子类静态代码块************");
}
public Son(){
System.out.println("*************子类构造方法************");
}
public static String getName(){
System.out.println("*************子类静态成员变量************");
return null;
}
public String getAddress(){
System.out.println("*************子类普通成员变量************");
return null;
}
}
执行结果:
*************父类静态成员变量************
*************父类静态代码块************
*************子类静态成员变量************
*************子类静态代码块************
*************父类普通成员变量************
*************父类构造代码块************
*************父类构造方法************
*************子类普通成员变量************
*************子类构造代码块************
*************子类构造方法************
- final在java中的作用?
final:最终的,可以用来修饰类、方法、属性
1、final修饰类:这个类不能被继承
2、final修饰方法:这个方法不能被重写
3、final修饰属性:这个属性就是常量
注意:
常量:一旦被final修饰,不可在被赋值,一般大写
1)此常量补不能使用默认初始化
2)可以显式的赋值,代码块或构造器
3)变量用static final修饰:全局常量,列:Math.PI
- String、StringBuffer、StringBuilder的区别?
1、String:底层final修饰,值是不可变的,每次都需要生产新的String对象,效率低,浪费空间
2、StringBuffer:值是可变的,任何指向他的字符串都不会产生新的对象,字符串超过容量,自动增加容量,线程安全的,多线程操作字符串
3、StringBuilder:值是可变的,线程不安全,单线程操作字符串
执行速度:
StringBuilder>StringBuffer>String
备注:
1)少量数据用String
2)多线程大量数据用StringBuffer
3)单线程大量数据用StringBuilder
- String str="i"与String str=new String(“i”)一样吗?
不一样
1、String str="i"的方式,虚拟机将其分配到常量池中
2、String str=new String("i")的方式,虚拟机将其分配到堆内存中
- String 类常用的方法有哪些?
1、获取功能
int length():获取字符串的长度(字符个数)
String charAt(int index):获取指定索引处的字符
int indexOf(String str):获取str在字符串中第一次出现的索引
String substring(int start):从start开始截取字符串
String substring(int start,int end):从start开始到end结束截取字符串,包括start,不包括end
2、判断功能
Boolean equals(Object obj):比较字符串内容是否相同
Boolean equalslgnoreCase(String str):比较字符串的内容是否相同(忽略大小写)
Boolean startsWith(String prefix):判断字符串是否以指定的字符开头(区分大小写)
Boolean startsWith(String prefix,int toffset):判断字符串是否以指定字符开头,参数toffset为指定从哪个下标开始
Boolean endsWith(String str):判断字符串是否以指定的字符结尾
Boolean isEmpty():判断指定字符串是否为空,list必须为对象,常量底层size()会报空指针
int compareTo(String str):比较字符串的大小,前者大返回整数,后者大返回负数,相等返回0
3、转换方法
char[] toCharArray():把字符串转换为字符数组
String toLowerCase():把字符串转换为小写字符串
String toUpperCase():把字符串转换为大写字符串
4、其他常用方法
String trim():去除字符串两端空格
String[] split(","):以逗号分割字符串,返回字符数组
String replace(char oldStr,char newStr):将字符串旧内容替换为新内容
String replaceFirst(String old,String newStr):替换首个满足条件的字符串
int lastIndexOf(String str):返回指定字符串出现的最后一次的下标
Boolean contains(String str):判断字符串中是否含有指定字符串
String concat(String str):在原有的字符串的基础加上指定字符串
- 普通类和抽象类的区别?
1、普通类不能包含抽象方法,抽象类可以包含普通方法
2、普通类可以选择重写父类方法或者直接调用父类方法,抽象类必须重写父类方法
3、普通类可以直接实例化,抽象类不能直接实例化(为了被继承)
普通类:
1)普通类可以实例化,实例化后可以直接调用类中的属性和方法或者父类的属性和方法
2)普通类的构造方法中必须要调用父类的构造方法
3)如果普通类继承抽象类,必须重写父类所有抽象方法
4)普通类存在的意义就是实例化
抽象类:
1)含有抽象方法的类叫做抽象类,抽象方法就是被abstract修饰的方法,这个方法没有具体的实现
2)抽象类的子类是普通类必须重写父类的所有抽象方法
3)抽象类不能被实例化,抽象类的构造方法作用为初始化子类对象
4)抽象类中的普通属性和普通方法都需要用子类的对象去调用
5)抽象类存在的意义就是被继承
- 抽象类能用final修饰吗?
不能,抽象类是为了被继承的,final修饰的类不可以被继承
- 接口和抽象类的区别?
1、实现方式:抽象类的子类使用extends来继承;接口使用implements来实现接口
2、构造函数:抽象类可以有构造函数;接口不能有
3、实现数量:一个类只能继承一个抽象类;一个类可以实现多个接口
4、访问修饰符:抽象类中的方法可以是任意访问修饰符;接口中的方法默认使用public修饰
- java中io流分几种?
1、按照功能分:输入流(input)、输出流(output)
2、按照类型分:字节流、字符流
字节流和字符流的区别:
1)字节流按照8位传输以字节为单位输入输出数据
2)字符流按照16位传输以字符为单位输入输出数据
- Files的常用方法有哪些?
1、Files.exists():检测文件路径是否存在
2、Files.createFile():创建文件
3、Files.createDirectory():创建文件夹
4、Files.delete():删除一个文件或目录
5、Files.copy():复制文件
6、Files.move():移动文件
7、Files.size():查看文件个数
8、Files.read():读取文件
9、files.write():写入文件
- 集合框架都有哪些?
Collection:
List:
ArrayList:
LinkedList:
Vector:
Set:
HashSet:
LinkedHashSet:
TreeSet:
Map:
HashMap:
LinskedHashMap
TreeMap:
ConcurrentHashMap:
- Collection常用方法?
1、boolean add(E e):添加指定元素到此集合
2、boolean addAll(Colleciton<? extends E> c):将指定集合中所有元素添加到此集合(set中求并集)
3、void clear():从此集合中删除所有元素
4、boolean contains(Object o):如果此集合包含指定元素,则返回true
5、boolean containsAll(Collection<?> c):如果刺激和包含指定集合中所有的元素,则返回true
6、boolean equals(Object o):将指定的对象与此集合进行比较以获得相等性
7、int hashCode():返回此集合的哈希码值
8、boolean isEmpty():如果此集合不包含元素,则返回true
9、Iterator<E> iterator():返回此集合中的元素的迭代器
10、boolean remove(Object o):从该集合中删除指定元素的单个实例(如果存在)
11、boolean removeAll(Collection<?> c):删除指定集合中包含的所有此集合元素
12、boolean retainAll(Collection<?> c):仅保留此集合中包含在指定集合中的元素(求交集)
13、Object[] toArray():返回一个包含此集合中所有元素的数组(集合转数组)
14、List Arrays.asList(Object[]):数组转为集合
- ArrayList和LinkedList的区别?
1、数据结构:ArrayList数据结构是动态数组;LinkedList是双向链表
2、查询效率:ArrayList随机查询效率高,因为LinkedList是线性数组的存储方式,需要指针从前往后依次查找
3、增删效率:LinkedList增删操作效率高,因为ArrayList的增删操作影响数组内其他的下标
总结:查询ArrayList,新增删除LinkedList
- 求俩个集合的交集和并集?
String[] arr1={"1","2","3","5"};
String[] arr2={"2","4","5","6"};
HashSet set1=new HashSet(Arrays.asList(arr1));
HashSet set2=new HashSet(Arrays.asList(arr2));
//并集
//set1.addAll(set2);
//System.out.println(set1);
//输出结果[1,2,3,4,5,6]
//交集
set1.retainAll(set2);
System.out.println(set1);
//输出结果[2,5]
- 创建线程的三种方式?
1、继承Thread类,重写run()方法
2、实现Runnable接口,重写ran()方法
3、实现Callable接口,重写call()方法
- 继承Thread和Runnable实现是的线程安全注意点?
1、继承Thread:实现方式为新建多个线程类,所以线程实现类公用变量需要添加static,同步方法也需要添加static,充当锁
2、Runnable:实现方式是新建一个线程类,新建多个Thread类
- 线程的生命周期?
1、新建:线程已经创建,但并未调用start()方法启动。
2、就绪:线程启动start()后,等待CPU分配资源。
3、运行:当就绪的线程获取CPU资源时,便进入运行状态,run()方法定义了线程池的操作和功能。
4、阻塞:在某种特殊情况下,被人为挂起或执行输入输出操作时,让出CPU并临时中止自己的执行,进入阻塞状态。
5、死亡:线程完成他的全部工作或线程被提前强制性的中止或异常导致结束。
-
线程池有哪些状态?
-
线程池中submit()和execute()方法有什么区别?
execute():只能执行Runnable类型的任务
submit():可以执行Runnable和Callable类型的任务
- 在java中怎么保证线程安全?
1、使用自动锁
同步代码块:synchronized括起来同步代码
同步方法:同步方法用synchronized修饰
3、使用手动锁
Lock锁:新建ReentrantLock类,执行Lock()方法,通过unLock释放锁
4、使用安全类
java.util.concurrent下的类
- 什么是死锁?
当线程A持有独占锁a,并尝试去获取独占锁b的同时,线程持有独占锁b,并尝试获取独占锁a的情况,会发生AB两个线程相互持有对方需要的锁,而发生的阻塞现象,称为死锁
- 怎么防止死锁?
1、尽量使用java.util.concurrent并发类代替自己手写锁
2、尽量不要几个功能用同一把锁
3、尽量减少同步的代码块
4、尽量使用tryLock(Long timeout,TimeUnit unit)的方法(ReentrantLock、RentrantReadWriteLoke),设置超时时间,超时可以退出防止死锁
5、使用Lock()时,必须使用unLock()释放锁
- synchronized和lock有什么区别?
1、synchronized可以给类、方法、代码块加锁;而lock只能给代码块加锁
2、synchronized不需要手动加锁和释放锁,发生异常会自动释放锁,不会造成死锁;Lock()需要手动加锁和释放锁,如果unLock()释放锁使用不当,会造成死锁
- 什么时候反射?
1、反射是运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法
2、对于任意一个对象,都能够调用他的任意一个方法和属性
3、这种动态获取的信息以及动态调用对象的方法叫做反射机制
- 深拷贝和浅拷贝的区别?
1、深拷贝:当对象被复制时,对象所包含的所有成员变量也将复制
2、浅拷贝:当对象被复制时,只复制它本身和其中包含的值类型的成员变量
- mybatis中#和$符号的区别?
#{}:预编译处理,相当于变量,数值替换为"?",可以方式sql注入
${}:字符替换,相当常量,数值替换为?,可以替换表名或者order by的字段名称
- 如何避免sql注入?
1、什么是sql注入:
1)select * from user where pwd=#{pwd}
2)select * from user where pwd="1 or 1=1"
3)select * from user where pwd=${pwd}
4)select * from user where pwd=1 or 1=1
如果1)的形式的用户传入值为1 or 1=1的值,会被替换成"1 or 1=1"的字符串
如果3)的形式的用户传入值1 or 1=1的值,会直接放入成1 or 1=1的值,拼接出来,直接跳过密码登陆,叫做sql注入
- 常见的异常类有哪些?
1、NullPointerException:空指针异常
2、ClassNotFoundException:指定类不存在
3、NumberFormatException:字符串转换为数字异常
4、IndexOutOfBoundException:数组下标越界异常
5、ClassCastException:数据类型转换异常
6、FileNotFoundException:文件未找到异常
7、NoSuchMethodException:方法不存在异常
8、IOException:IO异常
9、SocketException:Socket异常
- forward和redirct的区别?
forward是转发、redirct是重定向
1、地址栏url显示:转发不会发生改变,重定向会发生改变
2、数据共享:转发可以共享request里的数据,重定向不能共享
3、效率:转发比重定向效率高
- get和post请求有哪些区别?
1、get请求会被浏览器主动缓存,而post不会
2、get传递参数有大小限制,而post没有
3、get的参数会明文限制在url上,post不会,post参数传输相对安全
- 说一下你熟悉的设计模式?
代理模式:首先有一个租客,要去找房东,但是找不到房东,所以要找中介,中介再去找房东,中介就是代理角色
- 什么是aop?
1、aop:面向切面编程,降低耦合,是开发更加方便,不通过修改源代码的方式,对功能做增强
2、动态代理:在程序运行期间,创建目标对象的代理类对象,并对目标中的方法进行增强
3、aop底层使用动态代理实现,spring5中,已经做了封装,我们只需要通过注解使用即可,不用关心这些底层
4、aop术语:
1)连接点:在一个类中,那个方法可以被增强,那个方法就叫连接点
2)切入点:实际被增强的方法叫切入点
3)通知(增强):给方法实际增加的部分,分为:
前置通知(在原方法执行前执行)
后置通知(在原方法执行后执行)
环绕通知(前置通知+后置通知)
异常通知
最终通知
4)切面:把通知应用到切入点的过程
- 什么是ioc?
1、ioc叫做控制反转,是面向对象的一种设计方式
2、把对象的创建和对象之间的调用过程,交给spring管理
3、目的:为了是耦合度降低
(耦合度:我有多个service类,都需要调用一个dao类,当我修改这个dao类的位置时,则多个service类中都要修改,麻烦。尽量降低耦合度,我可以弄一个中间类,service类通过中间类调用dao类,这样当要修改dao的位置时,只用修改中间类即可,中间类则为spring管理)
4、一个类中,我想调用另一个类的方法,不必生成这个类的实例,直接从spring获取,就叫ioc
- ioc的实现方式?
1、第一种方式:属性注入
@Autowired//根据类型找到对应对象,完成注入
private UserService userService;
2、第二种方式:set方法注入
private UserService uesrService;
@AutoWired
public void setUserService(UserService userService){
this.userService = userService;
}
3、第三种方式:构造方法注入
private UserService userService;
@Autowired
public UserController(UserService userService){
this.userService = userService;
}
4、第四种方式:形参上注入
private UserService userService;
public UserController(@Autowired UserService userService){
this.userService = userService;
}
- 事务的特性?
1、原子性:确保要么一起成功,要么一起失败
2、一致性:A账户给B账户转钱,不会因为A账户扣了钱,而B账户没有加钱
3、隔离性:多个事务同时操作一个资源,确保数据准确
4、持久性:事务一旦提交,无论发生什么问题,都会写入数据库
- 事务的几种实现方式?
1、声明式事务
1)基于xml配置文件的方式
<!--配置平台事务管理器-->
<bean id="transactionManager" class="org.springframwork.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--配置Spring提供好的Advice-->
<tx:advice id="" transaction="">
<tx:attributes>
<!--
配置不同的方法的事务属性
name:方法名称 *代表通配符 添加操作addUser、addAccout可以用add*代替
isolation:事务的隔离级别,解决事务并发问题(脏读、幻读、不可重复读)
timeout:超时时间 默认-1 单位秒
read-only:是否只读,查询操作设置为只读
propagation:事务的传播行为,解决事务方法调用事务方法问题(事务嵌套问题)
-->
<tx:method name="transferMoney" isolation="READ_COMMITTED" propagation="REQUIRED" timeout="3" read-only="false"/>
<tx:method name="regisAccount"/>
<tx:method name="add*"/>
<tx:method name="update*"/>
<tx:method name="delete*"/>
<tx:method name="select*"/>
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
<!--事务增强aop-->
<aop:config>
<!--配置切入点表达式-->
<!--
execution(返回类型(第一个*号表示所有的类型 空格 包名(所属类的包名) 第二个*号(表示包名下边的所有类) *(..)*号表示该类所有方法,(..)表示所有参数类型)
-->
<aop:pointcut id="txPointcut" expression="execution(* com.itheima.service.impl.*.*(..))"/>
<!--配置织入关系 通知advice-ref引入spring提供好的-->
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/>
</aop:config>
<!--事务的自动代理(开启注解@Transaction)-->
<tx:annotation-driven/>
2)注解方式(类上添加@Transaction注解)
@Transaction(isolation=Isolation.READ_COMMITED,propagation=Propagation.REQUIRED)
2、编程式事务
1)提供编码的形式管理和维护事务
- 事务的传播行为
propagation属性:设置事务的传播行为,主要解决是A方法调用B方法,事务的传播方式问题
例如:使用单方的事务,还是A和B都使用自己的事务等
1、required:默认值,A调用B,B需要事务,如果A有事务B就加入A事务中,如果A没有事务,B就自己创建事务
2、required_new:A调用B,B需要新事务,如果A有事务就挂起,B自己创建一个新的事务
3、supports:A调用B,B有无事务无所谓,A有事务就加入A事务中,A无事务B就以非事务方式执行
4、not_supports:A调用B,B以无事务方式执行,A如有事务则挂起
5、never:A调用B,B以无事务方式执行,A如有事务则抛出异常
6、mandatory:A调用B,B要加入A的事务中,如果A无事务则抛出异常
7、nested:A调用B,B创建一个新事务,A有事务就作为嵌套事务存在,A没事务就一创建的新事务执行
- 事务的隔离级别
isolation属性:指定事务的隔离级别,事务并发存在三大问题:脏读、幻读、不可重复读。可以通过事务的隔离级别来保证并发问题的出现,常用的是read_committed和repeatable_read
1、default:默认隔离级别,取决于当前数据库隔离级别,例如mysql默认隔离级别是repeatable_read(默认数据库的隔离级别)
2、read_uncommited:A事务可以读取到B事务未提交的数据,不能解决任何并发问题,安全性最低,性能最高(会出现脏读、幻读、不可重复读)
3、read_commited:A事务只能读取到其他事务提交的数据,不能读到未提交数据,可以解决脏读问题不能解决幻读和不可重复读(会出现幻读和不可重复读)
4、repeatable_read:A事务多次从数据库读取到某条记录结果一致,可以解决脏读和不可重复读,不能解决幻读(会出现幻读)
5、serializable:串行化,可以解决任何并发问题,安全性最高,但性能最低(什么都不会出现)
- 事务的脏读、幻读、不可重复读?
1、脏读:一个未提交的事务A读到了一个未提交的事务B的数据
例:事务A和事务B对同一个账户基础5000操作,A加200没提交,B数据库获取为5200,A发生错误回滚了,B应该读到5000,减200,应为4800,但B提交之后还是5000,这个操作称为脏读
2、幻读:一个未提交的事务A,修改了数据库所有数据,另一个事务B提交新增一条数据,A提交完发现还有没有被修改的数据
例:事务A读取数据库有3条数据,修改这3条数据且未提交,事务B新增1条数据,事务A提交完后发现还有1条数据未被修改,这个操作称未幻读
3、不可重复读:一个未提交的事务A读取数据是,另一个事务B读取后直接提交,事务A读取的两次数据不一样
例:事务A和事务B对同一个账户基础5000操作,A加200没提交,B数据库获取为5000,B减200且提交之后为4800,事务A操作又读到的数据为4800,第一次和第二次读的数据不一样,这个操作称为不可重复读
-
spring动态代理是什么?
-
springmvc运行流程?
-
为什么要用springBoot?
1、配置简单
2、独立运行
3、自动装配
4、无代码生成和xml配置
5、提供应用监控
6、易上手
7、提升开发效率
- SpringBoot的常用注解?
1、@SpringBootApplication:是SpringBoot核心注解,实际上是另外三个注解的组合
1)@SpringBootConfiguration:实际是一个@Configuration,将当前类中被@Bean标记的方法纳入spring容器中(加载配置文件)
2)@EnableAutoConfiguration:向Spring容器中导入一个Selector,用来加载ClassPath下SpringFactories中所定义的自动配置类,将这些自动加载为配置Bean(开启自动配置)
3)@ComponentScan:识别当前包下的子包的所有注解标识的类,纳入spring容器(组件扫描和自动装配)
2、@Bean:用来定义bean,类似于Xml中的<bean>标签,spring启动时,会对加了@Bean注解的方法进行解析,将方法的名字作为beanName,并通过执行方法得到bean对象
3、@Controller:Controller层注解
4、@Service:Service层注解
5、@ResponseBody:Controller层类上,注释该类的方法返回实体类会被转为json数据,不会跳转页面;注释方法上,该方法返回实体类转为json数据,不会跳转页面
6、@Autowired:依赖注入,按照注入类型进行bean匹配
7、@Resource:依赖注入,按照注入名称进行bean匹配
-
SpringBoot的自动装配?
-
Linux常用命令?
1、关键字查询日志
1)cat 或者 tail 日志文件名 | grep "关键词"
2)grep -i "关键词" 日志文件名(与方法一效果相同,写法不同)
2、
- redis有哪些数据类型?
String(字符串)、List(列表)、Set(集合)、ZSet(有序结合)、hash(哈希)
- redis缓存穿透、缓存击穿、缓存雪崩?
1、缓存穿透:指查询一个不存在的数据,缓存中未命中,数据库也没有,数据库查不到也不写入缓存中,每次查询都要去直接访问数据库,造成了缓存穿透
解决方案:数据库查不到时,存入缓存中一个null值,但它的过期时间比较短,最多5分钟
2、缓存击穿:指缓存中没有,数据库有,(常见缓存同时过期,且这一时间段为高并发),数据库查询压力瞬间增大
解决方案:
1)预先设置热门数据:在redis高峰访问前,把一些热门数据提前存入redis中,加大这些热门数据key的时长实时调整 现场监控哪些数据是热门数据,实时调整key的过期时长
3、缓存雪崩:缓存雪崩是指缓存同一时间大面积的失效,所以,后面的请求都会落到数据库上,造成数据库短时间内承受大量请求而崩掉
常见缓存雪崩出现原因:
1、redis服务器挂掉了。
2、对缓存数据设置了相同的过期时间,导致某时间段内缓存集中失效。
解决方案:
1)构建多级缓存架构:nginx缓存+redis缓存+其他缓存(ehcache等)
2)设置过期标志更新缓存:记录缓存数据是否过期(设置提前量),如果过期会触发通知另外的线程在后台去更新实际key的缓存
3)将缓存失效时间分散开:设置缓存过期时间时加上一个随机值,避免缓存在同一时间过期
- mysql中有哪些索引?
1、唯一索引
2、主键索引
3、普通索引
4、联合索引
- mysql中sql优化?
1、建立中间表
2、添加where条件常用字段为索引字段
3、常见索引:唯一索引、主键索引、联合索引、普通索引
4、explain查看执行计划,All的不走索引
5、不走索引的几种解决方案:
1)不使用函数
2)使用的in、not in替换为exsits、not exsits
3)使用的union替换为unionAll
4)用字符串"1"等于不使用1等于
5)联合索引where条件顺序必须是联合索引从左到右的顺序
6)不使用or
7)sql语句不使用*,尽量指定具体字段
- mysql内连接、左连接、右连接有什么区别?
1、内连接(inner join):把匹配的关联数据显示出来
2、左连接(left join):左边的表全部显示出来,右边的表有则显示,无则为空
3、右连接(right join):右边的表全部显示出来,左边的表有则显示,无则为空
-
什么是springcloud?
-
springcloud的核心组件有哪些?
1、服务注册与发现:Eureka
2、负载均衡:
客户端负载均衡——Ribbon
服务端负载均衡——Feign(其也是依赖于Ribbon,只是将调用方式RestTemplete更改成Service接口)
3、断路器:Hystrix
4、服务网关:Zuul
5、分布式配置:Spring Cloud Config
- Spring Cloud和Dubbo的关系?
1、Dubbo是基于RPC调用的,而SpringCloud是基于HTTP的REST方式,所以效率上是Dubbo更快
2、Dubbo的组件不是很齐全,很多功能比如服务注册与发现你需要借助与类似Zookeeper等组件才能实现,而SpringCloud则是提供了一站式解决方案