java常见面试题

java常见面试题
  1. jdk、jre、jvm区别?
	jdk:java的开发工具包,提供了java的开发环境和运行环境,jdk包含jre。
	jre:java的运行环境。
	jvm:Java 虚拟机(JVM)是运行 Java 字节码的虚拟机实现java的跨平台特性。JVM 有针对不同系统的特定实现(WindowsLinux,macOS),目的是使用相同的字节码,它们都会给出相同的结果。
  1. 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;
		    }
  1. int和Integer的区别?
	1Integerint的包装类,int是基本数据类型
	2Integer必须实例化才能使用,int不需要实例化
	3Integer是对象的引用,new一个Integer时实际生成一个指针指向对象,int直接存数值
	4Integer默认是是null,int默认值是0
  1. 数据类型有哪些?
	1、基本数据类型:
		整数型:short(2)int(4)long(8)
		浮点型:float(4)double(8)
		字符型:char(2)
		字节型:byte(1)
		布尔型:boolean(1)
 	2、引用数据类型:String、类、接口、数组
 		
  1. 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;
    }
}
执行结果:
*************父类静态成员变量************
*************父类静态代码块************
*************子类静态成员变量************
*************子类静态代码块************
*************父类普通成员变量************
*************父类构造代码块************
*************父类构造方法************
*************子类普通成员变量************
*************子类构造代码块************
*************子类构造方法************

  1. final在java中的作用?
	final:最终的,可以用来修饰类、方法、属性
	1final修饰类:这个类不能被继承
	2final修饰方法:这个方法不能被重写
	3final修饰属性:这个属性就是常量
	注意:
		常量:一旦被final修饰,不可在被赋值,一般大写
		1)此常量补不能使用默认初始化
		2)可以显式的赋值,代码块或构造器
		3)变量用static final修饰:全局常量,列:Math.PI
  1. String、StringBuffer、StringBuilder的区别?
	1String:底层final修饰,值是不可变的,每次都需要生产新的String对象,效率低,浪费空间
	2StringBuffer:值是可变的,任何指向他的字符串都不会产生新的对象,字符串超过容量,自动增加容量,线程安全的,多线程操作字符串
	3StringBuilder:值是可变的,线程不安全,单线程操作字符串
	执行速度:
		StringBuilder>StringBuffer>String
	备注:
		1)少量数据用String
		2)多线程大量数据用StringBuffer
		3)单线程大量数据用StringBuilder
  1. String str="i"与String str=new String(“i”)一样吗?
	不一样
	1String str="i"的方式,虚拟机将其分配到常量池中
	2String str=new String("i")的方式,虚拟机将其分配到堆内存中
  1. 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. 普通类和抽象类的区别?
	1、普通类不能包含抽象方法,抽象类可以包含普通方法
	2、普通类可以选择重写父类方法或者直接调用父类方法,抽象类必须重写父类方法
	3、普通类可以直接实例化,抽象类不能直接实例化(为了被继承)
	
	普通类:
		1)普通类可以实例化,实例化后可以直接调用类中的属性和方法或者父类的属性和方法
		2)普通类的构造方法中必须要调用父类的构造方法
		3)如果普通类继承抽象类,必须重写父类所有抽象方法
		4)普通类存在的意义就是实例化
	抽象类:
		1)含有抽象方法的类叫做抽象类,抽象方法就是被abstract修饰的方法,这个方法没有具体的实现
		2)抽象类的子类是普通类必须重写父类的所有抽象方法
		3)抽象类不能被实例化,抽象类的构造方法作用为初始化子类对象
		4)抽象类中的普通属性和普通方法都需要用子类的对象去调用
		5)抽象类存在的意义就是被继承
  1. 抽象类能用final修饰吗?
	不能,抽象类是为了被继承的,final修饰的类不可以被继承
  1. 接口和抽象类的区别?
	1、实现方式:抽象类的子类使用extends来继承;接口使用implements来实现接口
	2、构造函数:抽象类可以有构造函数;接口不能有
	3、实现数量:一个类只能继承一个抽象类;一个类可以实现多个接口
	4、访问修饰符:抽象类中的方法可以是任意访问修饰符;接口中的方法默认使用public修饰
  1. java中io流分几种?
	1、按照功能分:输入流(input)、输出流(output)
	2、按照类型分:字节流、字符流
	
	字节流和字符流的区别:
		1)字节流按照8位传输以字节为单位输入输出数据
		2)字符流按照16位传输以字符为单位输入输出数据
  1. Files的常用方法有哪些?
	1Files.exists():检测文件路径是否存在
	2Files.createFile():创建文件
	3Files.createDirectory():创建文件夹
	4Files.delete():删除一个文件或目录
	5Files.copy():复制文件
	6Files.move():移动文件
	7Files.size():查看文件个数
	8Files.read():读取文件
	9、files.write():写入文件
  1. 集合框架都有哪些?
	Collection:
		List:
			ArrayList:
			LinkedList:
			Vector:
		Set:
			HashSet:
			LinkedHashSet:
			TreeSet:
	Map:
		HashMap:
			LinskedHashMap
		TreeMap:
		ConcurrentHashMap:
  1. Collection常用方法?
	1boolean add(E e):添加指定元素到此集合
	2boolean addAll(Colleciton<? extends E> c):将指定集合中所有元素添加到此集合(set中求并集)
	3void clear():从此集合中删除所有元素
	4boolean contains(Object o):如果此集合包含指定元素,则返回true
	5boolean containsAll(Collection<?> c):如果刺激和包含指定集合中所有的元素,则返回true
	6boolean equals(Object o):将指定的对象与此集合进行比较以获得相等性
	7int hashCode():返回此集合的哈希码值
	8boolean isEmpty():如果此集合不包含元素,则返回true
	9Iterator<E> iterator():返回此集合中的元素的迭代器
	10boolean remove(Object o):从该集合中删除指定元素的单个实例(如果存在)
	11boolean removeAll(Collection<?> c):删除指定集合中包含的所有此集合元素
	12boolean retainAll(Collection<?> c):仅保留此集合中包含在指定集合中的元素(求交集)
	13Object[] toArray():返回一个包含此集合中所有元素的数组(集合转数组)
	14List Arrays.asList(Object[]):数组转为集合
  1. ArrayList和LinkedList的区别?
	1、数据结构:ArrayList数据结构是动态数组;LinkedList是双向链表
	2、查询效率:ArrayList随机查询效率高,因为LinkedList是线性数组的存储方式,需要指针从前往后依次查找
	3、增删效率:LinkedList增删操作效率高,因为ArrayList的增删操作影响数组内其他的下标
	总结:查询ArrayList,新增删除LinkedList
  1. 求俩个集合的交集和并集?
	 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. 创建线程的三种方式?
	1、继承Thread类,重写run()方法
	2、实现Runnable接口,重写ran()方法
	3、实现Callable接口,重写call()方法
  1. 继承Thread和Runnable实现是的线程安全注意点?
	1、继承Thread:实现方式为新建多个线程类,所以线程实现类公用变量需要添加static,同步方法也需要添加static,充当锁
	2Runnable:实现方式是新建一个线程类,新建多个Thread
  1. 线程的生命周期?
	1、新建:线程已经创建,但并未调用start()方法启动。
	2、就绪:线程启动start()后,等待CPU分配资源。
	3、运行:当就绪的线程获取CPU资源时,便进入运行状态,run()方法定义了线程池的操作和功能。
	4、阻塞:在某种特殊情况下,被人为挂起或执行输入输出操作时,让出CPU并临时中止自己的执行,进入阻塞状态。
	5、死亡:线程完成他的全部工作或线程被提前强制性的中止或异常导致结束。
  1. 线程池有哪些状态?

  2. 线程池中submit()和execute()方法有什么区别?

	execute():只能执行Runnable类型的任务
	submit():可以执行RunnableCallable类型的任务
  1. 在java中怎么保证线程安全?
	1、使用自动锁
		同步代码块:synchronized括起来同步代码
		同步方法:同步方法用synchronized修饰
	3、使用手动锁
		Lock锁:新建ReentrantLock类,执行Lock()方法,通过unLock释放锁
	4、使用安全类
		java.util.concurrent下的类
  1. 什么是死锁?
	当线程A持有独占锁a,并尝试去获取独占锁b的同时,线程持有独占锁b,并尝试获取独占锁a的情况,会发生AB两个线程相互持有对方需要的锁,而发生的阻塞现象,称为死锁
  1. 怎么防止死锁?
	1、尽量使用java.util.concurrent并发类代替自己手写锁
	2、尽量不要几个功能用同一把锁
	3、尽量减少同步的代码块
	4、尽量使用tryLock(Long timeout,TimeUnit unit)的方法(ReentrantLockRentrantReadWriteLoke),设置超时时间,超时可以退出防止死锁
	5、使用Lock()时,必须使用unLock()释放锁
  1. synchronized和lock有什么区别?
	1synchronized可以给类、方法、代码块加锁;而lock只能给代码块加锁
	2synchronized不需要手动加锁和释放锁,发生异常会自动释放锁,不会造成死锁;Lock()需要手动加锁和释放锁,如果unLock()释放锁使用不当,会造成死锁
  1. 什么时候反射?
	1、反射是运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法
	2、对于任意一个对象,都能够调用他的任意一个方法和属性
	3、这种动态获取的信息以及动态调用对象的方法叫做反射机制
  1. 深拷贝和浅拷贝的区别?
	1、深拷贝:当对象被复制时,对象所包含的所有成员变量也将复制
	2、浅拷贝:当对象被复制时,只复制它本身和其中包含的值类型的成员变量
  1. mybatis中#和$符号的区别?
	#{}:预编译处理,相当于变量,数值替换为"?",可以方式sql注入
	${}:字符替换,相当常量,数值替换为?,可以替换表名或者order by的字段名称
  1. 如何避免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. 常见的异常类有哪些?
	1NullPointerException:空指针异常
	2ClassNotFoundException:指定类不存在
	3NumberFormatException:字符串转换为数字异常
	4IndexOutOfBoundException:数组下标越界异常
	5ClassCastException:数据类型转换异常
	6FileNotFoundException:文件未找到异常
	7NoSuchMethodException:方法不存在异常
	8IOExceptionIO异常
	9SocketExceptionSocket异常
  1. forward和redirct的区别?
	forward是转发、redirct是重定向
	1、地址栏url显示:转发不会发生改变,重定向会发生改变
	2、数据共享:转发可以共享request里的数据,重定向不能共享
	3、效率:转发比重定向效率高
  1. get和post请求有哪些区别?
	1、get请求会被浏览器主动缓存,而post不会
	2、get传递参数有大小限制,而post没有
	3、get的参数会明文限制在url上,post不会,post参数传输相对安全
  1. 说一下你熟悉的设计模式?
	代理模式:首先有一个租客,要去找房东,但是找不到房东,所以要找中介,中介再去找房东,中介就是代理角色
  1. 什么是aop?
	1、aop:面向切面编程,降低耦合,是开发更加方便,不通过修改源代码的方式,对功能做增强
	2、动态代理:在程序运行期间,创建目标对象的代理类对象,并对目标中的方法进行增强
	3、aop底层使用动态代理实现,spring5中,已经做了封装,我们只需要通过注解使用即可,不用关心这些底层
	4、aop术语:
		1)连接点:在一个类中,那个方法可以被增强,那个方法就叫连接点
		2)切入点:实际被增强的方法叫切入点
		3)通知(增强):给方法实际增加的部分,分为:
			前置通知(在原方法执行前执行)
			后置通知(在原方法执行后执行)
			环绕通知(前置通知+后置通知)
			异常通知
			最终通知
		4)切面:把通知应用到切入点的过程
  1. 什么是ioc?
	1、ioc叫做控制反转,是面向对象的一种设计方式
	2、把对象的创建和对象之间的调用过程,交给spring管理
	3、目的:为了是耦合度降低
		(耦合度:我有多个service类,都需要调用一个dao类,当我修改这个dao类的位置时,则多个service类中都要修改,麻烦。尽量降低耦合度,我可以弄一个中间类,service类通过中间类调用dao类,这样当要修改dao的位置时,只用修改中间类即可,中间类则为spring管理)
	4、一个类中,我想调用另一个类的方法,不必生成这个类的实例,直接从spring获取,就叫ioc
  1. 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. 事务的特性?
	1、原子性:确保要么一起成功,要么一起失败
	2、一致性:A账户给B账户转钱,不会因为A账户扣了钱,而B账户没有加钱
	3、隔离性:多个事务同时操作一个资源,确保数据准确
	4、持久性:事务一旦提交,无论发生什么问题,都会写入数据库
  1. 事务的几种实现方式?
	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)提供编码的形式管理和维护事务
  1. 事务的传播行为
	propagation属性:设置事务的传播行为,主要解决是A方法调用B方法,事务的传播方式问题
	例如:使用单方的事务,还是AB都使用自己的事务等
	1、required:默认值,A调用BB需要事务,如果A有事务B就加入A事务中,如果A没有事务,B就自己创建事务
	2、required_new:A调用BB需要新事务,如果A有事务就挂起,B自己创建一个新的事务
	3、supports:A调用BB有无事务无所谓,A有事务就加入A事务中,A无事务B就以非事务方式执行
	4、not_supports:A调用BB以无事务方式执行,A如有事务则挂起
	5、never:A调用BB以无事务方式执行,A如有事务则抛出异常
	6、mandatory:A调用BB要加入A的事务中,如果A无事务则抛出异常
	7、nested:A调用BB创建一个新事务,A有事务就作为嵌套事务存在,A没事务就一创建的新事务执行
	
  1. 事务的隔离级别
	isolation属性:指定事务的隔离级别,事务并发存在三大问题:脏读、幻读、不可重复读。可以通过事务的隔离级别来保证并发问题的出现,常用的是read_committed和repeatable_read
	1default:默认隔离级别,取决于当前数据库隔离级别,例如mysql默认隔离级别是repeatable_read(默认数据库的隔离级别)
	2、read_uncommited:A事务可以读取到B事务未提交的数据,不能解决任何并发问题,安全性最低,性能最高(会出现脏读、幻读、不可重复读)
	3、read_commited:A事务只能读取到其他事务提交的数据,不能读到未提交数据,可以解决脏读问题不能解决幻读和不可重复读(会出现幻读和不可重复读)
	4、repeatable_read:A事务多次从数据库读取到某条记录结果一致,可以解决脏读和不可重复读,不能解决幻读(会出现幻读)
	5、serializable:串行化,可以解决任何并发问题,安全性最高,但性能最低(什么都不会出现)
  1. 事务的脏读、幻读、不可重复读?
	1、脏读:一个未提交的事务A读到了一个未提交的事务B的数据
		例:事务A和事务B对同一个账户基础5000操作,A200没提交,B数据库获取为5200A发生错误回滚了,B应该读到5000,减200,应为4800,但B提交之后还是5000,这个操作称为脏读
	2、幻读:一个未提交的事务A,修改了数据库所有数据,另一个事务B提交新增一条数据,A提交完发现还有没有被修改的数据
		例:事务A读取数据库有3条数据,修改这3条数据且未提交,事务B新增1条数据,事务A提交完后发现还有1条数据未被修改,这个操作称未幻读
	3、不可重复读:一个未提交的事务A读取数据是,另一个事务B读取后直接提交,事务A读取的两次数据不一样
		例:事务A和事务B对同一个账户基础5000操作,A200没提交,B数据库获取为5000B200且提交之后为4800,事务A操作又读到的数据为4800,第一次和第二次读的数据不一样,这个操作称为不可重复读
  1. spring动态代理是什么?

  2. springmvc运行流程?
    在这里插入图片描述

  3. 为什么要用springBoot?

	1、配置简单
	2、独立运行
	3、自动装配
	4、无代码生成和xml配置
	5、提供应用监控
	6、易上手
	7、提升开发效率
  1. SpringBoot的常用注解?
	1@SpringBootApplication:是SpringBoot核心注解,实际上是另外三个注解的组合
		1@SpringBootConfiguration:实际是一个@Configuration,将当前类中被@Bean标记的方法纳入spring容器中(加载配置文件)
		2@EnableAutoConfiguration:向Spring容器中导入一个Selector,用来加载ClassPathSpringFactories中所定义的自动配置类,将这些自动加载为配置Bean(开启自动配置)
		3@ComponentScan:识别当前包下的子包的所有注解标识的类,纳入spring容器(组件扫描和自动装配)
	2@Bean:用来定义bean,类似于Xml中的<bean>标签,spring启动时,会对加了@Bean注解的方法进行解析,将方法的名字作为beanName,并通过执行方法得到bean对象
	3@ControllerController层注解
	4@ServiceService层注解
	5@ResponseBodyController层类上,注释该类的方法返回实体类会被转为json数据,不会跳转页面;注释方法上,该方法返回实体类转为json数据,不会跳转页面
	6@Autowired:依赖注入,按照注入类型进行bean匹配
	7@Resource:依赖注入,按照注入名称进行bean匹配
  1. SpringBoot的自动装配?

  2. Linux常用命令?

	1、关键字查询日志
		1)cat 或者 tail 日志文件名 | grep  "关键词"
	 	2)grep -i  "关键词" 日志文件名(与方法一效果相同,写法不同)
	 2
  1. redis有哪些数据类型?
	String(字符串)List(列表)Set(集合)ZSet(有序结合)hash(哈希)
  1. redis缓存穿透、缓存击穿、缓存雪崩?
	1、缓存穿透:指查询一个不存在的数据,缓存中未命中,数据库也没有,数据库查不到也不写入缓存中,每次查询都要去直接访问数据库,造成了缓存穿透
	解决方案:数据库查不到时,存入缓存中一个null值,但它的过期时间比较短,最多5分钟
	2、缓存击穿:指缓存中没有,数据库有,(常见缓存同时过期,且这一时间段为高并发),数据库查询压力瞬间增大
	解决方案:
		1)预先设置热门数据:在redis高峰访问前,把一些热门数据提前存入redis中,加大这些热门数据key的时长实时调整 现场监控哪些数据是热门数据,实时调整key的过期时长
	3、缓存雪崩:缓存雪崩是指缓存同一时间大面积的失效,所以,后面的请求都会落到数据库上,造成数据库短时间内承受大量请求而崩掉
	常见缓存雪崩出现原因:
		1、redis服务器挂掉了。
		2、对缓存数据设置了相同的过期时间,导致某时间段内缓存集中失效。
	解决方案:
		1)构建多级缓存架构:nginx缓存+redis缓存+其他缓存(ehcache等)
		2)设置过期标志更新缓存:记录缓存数据是否过期(设置提前量),如果过期会触发通知另外的线程在后台去更新实际key的缓存
		3)将缓存失效时间分散开:设置缓存过期时间时加上一个随机值,避免缓存在同一时间过期
		
	
  1. mysql中有哪些索引?
	1、唯一索引
	2、主键索引
	3、普通索引
	4、联合索引
  1. 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语句不使用*,尽量指定具体字段
  1. mysql内连接、左连接、右连接有什么区别?
	1、内连接(inner join):把匹配的关联数据显示出来
	2、左连接(left join):左边的表全部显示出来,右边的表有则显示,无则为空
	3、右连接(right join):右边的表全部显示出来,左边的表有则显示,无则为空
  1. 什么是springcloud?

  2. springcloud的核心组件有哪些?

	1、服务注册与发现:Eureka
	2、负载均衡:
		客户端负载均衡——Ribbon
		服务端负载均衡——Feign(其也是依赖于Ribbon,只是将调用方式RestTemplete更改成Service接口)
	3、断路器:Hystrix
	4、服务网关:Zuul
	5、分布式配置:Spring Cloud Config
  1. Spring Cloud和Dubbo的关系?
	1Dubbo是基于RPC调用的,而SpringCloud是基于HTTPREST方式,所以效率上是Dubbo更快
	2Dubbo的组件不是很齐全,很多功能比如服务注册与发现你需要借助与类似Zookeeper等组件才能实现,而SpringCloud则是提供了一站式解决方案
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值