uniapp的生命周期
小程序
onLoad(Object query) 页面加载时触发。一个页面只会调用一次,可以在 onLoad
的参数中获取打开当前页面路径中的参数。
onShow() 页面显示/切入前台时触发。
onReady() 页面初次渲染完成时触发。一个页面只会调用一次,代表页面已经准备妥当,可以和视图层进行交互。
所以加载顺序是先加载onLoad,再是onShow,最后onReady
vue的生命周期
beforecreate 创建前
created:创建后
mounted:实例已经被挂载完成了
谈谈对spring的理解
Spring是一个轻量级的免费框架,它有两大核心功能,分别是ioc和aop,ioc控制反转是将创建对象的权限交给spring容器来进行管理,可以很好的起到解耦和的作用,aop是一种编程思想,底层使用的是动态代理,可以在程序原有的功能上进行增强,常用的地方有日志记录,权限验证等 ...
bean的生命周期:
创建,初始化,调用,销毁; bean的创建方式有四种,构造器,静态工厂,实例工厂,setter注入的方式。 spring在调用bean的时候因为作用域的不同,不同的bean初始化和创建的时间也不相同。 在作用域为singleton的时候,bean是随着容器一起被创建好并且实例化的, 在作用域为pritotype的时候,bean是随着它被调用的时候才创建和实例化完成。 然后程序就可以使用bean了,当程序完成销毁的时候,bean也被销毁。
一.对SpringAop的理解*
答:1.AOP是一种面向切面的编程思想,将那些重复的代码抽取出来,使用动态代理技术,可以在不影响原代码的情况下去对原方法进行增强。
2.我们将影响多个类的公共行为抽取出来封装到一个可重用的模块中,我们称其为切面。这样可以减少系统中的重复代码,降低模块之间的耦合。然后用注解@pointcut去定义切入点。最后就是通知,aop中有前置通知和后置通知和环绕通知。
2.使用场景:一般在权限认证以及日志记录中常使用。
二.实现线程的方法
1.继承thread类()
2.实现runnable接口。启动线程:start方法
3.实现Callable接口
三.介绍以下redis
1.redis是一钟基于键值对的非关系型数据库,它的数据是存在内存中的,单线程,避免了线程之间的切换以及竞争的消耗,所以它的速度很快。
2.redis有五种数据类型,分别是string、list、set、hset、hash。
3.如何设置key的过期时间
热点数据不设置过期时间,避免了缓存击穿问题。
在设置过期时间的时候,可以采用随机数,这样可以避免同一时间大量key过期,导致缓存雪崩。
四.缓存击穿、雪崩、穿透
- 缓存击穿:key对应的数据存在,但在redis中过期,此时若有大量并发请求过来,这些请求发现缓存过期一般都会从后端DB加载数据并回设到缓存,这个时候大并发的请求可能会瞬间把后端DB压垮。
- 缓存穿透:key对应的数据在数据源并不存在,每次针对此key的请求从缓存获取不到,请求都会到数据源,从而可能压垮数据源。比如用一个不存在的用户id获取用户信息,不论缓存还是数据库都没有,若黑客利用此漏洞进行攻击可能压垮数据库。(加布隆过滤器)
- 缓存雪崩:当缓存服务器重启或者大量缓存集中在某一个时间段失效,这样在失效的时候,也会给后端系统(比如DB)带来很大压力。
五.谈一谈springIOC的理解*
IOC是也就是控制反转,是一种面向对象的编程思想。我们在不采用IO时,我们需要去一个一个的new对象,并且去要去维护对象与对象之间的关系,这就造成了耦合度高的问题,在大型项目中,对象和对象的关系相当复杂,这就不利于代码的维护。IOC就帮我们解决了这个问题。我们将对象的创建去交给ioc容器。而不是传统的DI:交给应用程序去创建,在注入容器,也就是依赖注入。
常见的IOC容器:BeanFactory
六.mysql的主从复制实现读写分离
读写分离就是基于主从复制,也就是说可以建一个主表挂多个从表,在写操作的时候就只操作主表,然后主表再同步给从表。主表的写操作会记录再binlog日志中,从表会将其拷贝到自己的本地,然后执行binlog 中的操作。这样就可以保证一致性,但是再高并发的场景可以出现延迟的状态,这时可以采用并行复制或者将主表分库。
七.redis常用指令:
String类型:
1.set key value给指定的key赋值
2.get key 获取该key的值
3.append key value 追加值
4.del key 删除该key的值
5.rename key xxx 给key改名
6.type key 查看key的类型
八.springboot整合redis中redis的指令
九.说一下hashmap中put方法的流程*
1.根据key通过哈希算法来计算出下标。
2.如果下标的元素为空,则将key和value封装成entry对象放入该位置。
3.如果下表不为空,在jdk1.7中,则需要判断扩不扩容,就直接用头插法添加到当前位置的链表中。而在jdk1.8中,则要判断是红黑树还是链表,如是红黑树,则封装key和value成一个红黑树节点添加到红黑树中,在这个过程中会判断是否有这个key,有则更新value。如是链表,则采用尾插法插入到链表中,若当前链表节点大于8,则将转换成红黑树。
4.在jdk1.7中hashMap是底层数组加链表实现的,在jdk1.8中则是链表加红黑树。
十.串行和并行*
串行:一个任务执行完,才执行下一个任务。
并行:两个任务同时执行
十一.Mysql慢查询怎么优化*
1.检查表中数据是否过多,是否应该分库分表。
3.检查所查字段是否都是必须的,是否查询了过多字段,查询了多余数据。
十二.redis和mysql如何保证数据一致性*
1.延迟双删:先删除redis数据,再更新mysql数据,延迟几百毫秒再去删除redis,这也在多线程的情况下,就算读到了老数据,也会被删除掉。
十三.mysql的事务*
1.MySQL一共有四个事务,分别为原子性,隔离性,一致性和持久性。原子性是指一个不可分割的操作序列,要么都成功,要么都失败。隔离性是指多个事务并发执行的时,互不影响。一致性是指事务前后的状态一致。持久性是指事务一旦执行成功,对数据库的修改是永久性的,即使系统崩溃也不会丢失。
十四.MySQL中有那些锁
最常见的就是共享锁和排它锁。共享锁用于读取数据时,可以运行多个事务同时读取一份数据,但是不能进行修改。排它锁用于修改数据时,保证只有一个事务可以修改数据,其它事务需要等待
十五.==和equals()有什么区别?*
==运算符:
在比较基本数据类型时,会比较两个数值是否相等。
在比较引用数据类型时,会比较两个对象的内存地址是否相同,判断是否喂同一个对象。
equals:
在equals没有被重写之前,会默认使用==来比较两个对象地址是否相同。
在equals被重写之后,会按照对象的内容来进行比较,若两个对象内容相同则认为对象相等,否则认为对象不等。
十六.为什么重写hashcode方法就要重写equals方法?*
如果只重写equals方法,可能会两个对象equals为true,但是hashcode却不同,这个只重写了equals的对象在使用散列集合进行存储时就会出现问题,因为散列集合是通过hashcode来确定key的位置,如果存储两个相同的对象却存储在两个不同的位置,就会出现两个完全相同的对象存储在两个不同的位置!
十七.spring依赖注入的原理*
spring的依赖注入采用的是反射原理,它通过配置文件或注解中的元信息,然后动态的创建对象实例,并将其依赖注入在对象中。
十八.spring依赖注入的实现方式*
1.setter方式
2.注解注入@Autowrite
3.构造函数注入
十九.介绍一下springboot*
Spring Boot 是一个快速构建应用程序的框架,能够自动配置大部分应用程序的依赖关系和配置。它主要侧重于简化和快速化 Spring 应用程序的开发,使得开发人员可以快速启动和运行一个基本的 Spring 应用
二十.spring事务*
spring事务共分为编程式事务和声明式事务。
1.编程性事务是通过编写代码来规定事务从哪里开始,哪里结束。拥有很高的灵活性。但是他会使程序代码和事务耦合度高,难以维护,所以不常用。
2.声明式事务可以通过xml配置或者注解的方式来实现。在使用声明式事务时底层采用了aop!
@EnableTransationManagemen开始事务
@transactional 添加事务。
二十一.脏读、幻读、不可重复读*
1.脏读:一个未提交的事务读取到另外一个事务未提交的数据。
2.幻读:一个未提交的事务读取到另一个事务添加的数据。
3.不可重复读:一个未提交的事务读取到另一个事务修改的数据。
二十二.如何避免脏读幻读和不可重复读*
设置事务隔离级别。
1.读未提交:可以读取到未提交的更改,可能会导致脏读、幻读、不可重复读。
2.读已提交:可以读取到已提交的更改,避免了脏读。
3.可重复读:防止脏读和不可重复读,不能避免幻读。
4.串行化:可同时避免脏读幻读和不可重复读。
二十三.spring的常用注解
1.@SpringBootApplication:它是SpringBoot的核心注解,用于开启自动配置。
2.@SpringBootConfiguration
3.@configuration
4.@enableAutoconfiguration
5.@ComponentScan:位置在springBoot的启动类上,spring包扫描
二十四.springboot的启动流程
1.加载配置文件,加载application.yml文件,将其中的配置加载到spring中。
2.扫描注解,spring会扫描启动类所在的包或者子包下的所有类,查找带有特定注解的类。
3.创建applicationcontext,springboot会根据扫描到的类创建applicationContext,其中包括bean的定义和依赖关系。
4.注册bean,spring boot会将带有特定注解的类注册为bean,加入进application中。
5.启动内置的web服务器,比如tomcat。
6.运行应用程序,并将请求转发给对应的控制器。
二十五.git怎么创建分支*
1. 首先,切换到需要新建分支的代码所在的分支,比如master分支: `git checkout master`
2. 然后,使用以下命令新建一个分支,比如dev分支: `git branch dev`
3. 最后,切换到新建的分支: `git checkout dev`
二十六.Arraylist和linklist哪个更占内存*
ArrayList通常比LinkedList占用更多的内存,因为它需要在内存中为每个元素分配一个固定大小的空间,而LinkedList只需要为每个元素分配一个节点。此外,ArrayList还需要在数组中保留额外的空间以容纳未来的元素添加
二十七.乐观锁和悲观锁怎么实现*
1.乐观锁可以在该表中添加一个版本号或者是时间戳字段,当我们进行更新操作时,若发现版本号或者时间搓被其他线程所更改,则更新失败。
2.悲观所的实现,则是可以使用数据库的锁机制,比如说添加行数或者是表锁,那么我们在操作数据时,会先获取锁,确保其他县城无法修改,无法操作该数据,在操作完成后在释放锁。
二十八.线程的状态以及他们之间的转换*
1.初始状态:刚刚 new Thread()
2.可运行状态:初始状态,通过start()方法可转化成可运行状态
3.运行中状态:可运行状态被线程(OS)调度选中将变成运行中
4.等待队列状态,使用wait()方法。
5.锁池状态。
6.阻塞状态。
7.结束。
二十九.设计模式
1.单例模式:饿汉式和懒汉式
2.工厂模式
3.代理模式:动态代理以及静态代理。
三十.@Autowrite和@Resource的区别*
1.前者是根据类型去装配的,类型装配不到便根据名字,该注解是spring中定义的注解。
2.后者是根据名字装配的,可指定bean的名字,名字装配不上时则会根据类型装配,该注解是jdk定义的。
三十一.springboot是如何启动tomcat的
1.springboot在启动时会创建一个spring容器。
2.在创建过程中会去判断classpath中有没有tomcat依赖,如有则生成一个启动tomcat的bean。
3.容器创建完之后,会获取启动tomcat的bean,并创建tomcat对象,绑定端口,启动tomcat。
三十二.mysql慢sql怎么查询和优化*
1.开启mysql自带的慢查询日志,设置阈值,记录执行超过阈值的sql语句。
2.分析慢查询日志,找出执行时间较久的sql,确定哪些语句需要优化。
3.使用explain命令分析SQL的执行计划,查看是否出现索引失效或者全表扫描的情况。
4.根据分析结果,优化SQL语句,可以采取:添加索引,优化查询条件,优化表结构。
三十三.可能导致索引失效的情况*
1.对索引列使用了函数转换。
2.对索引列进行了加减乘除等运算符。
3.使用了!=或者in或者like等操作符。
4.对索引列进行了排序或者分组。
使用explain命令后 出现Using filesort,就是索引失效的标志。
三十四.spring如何解决循环依赖*
1.通过构造函数注入,在bean实例化的时候就完成依赖注入,避免了循环依赖。
2.通过setter注入,可以在bean实例化后再注入,避免了循环依赖的问题。
3.通过代理对象来解决,Spring框架会先创建一个代理对象,然后将代理对象注入到Bean A中,等到Bean B创建完成后,再将真正的Bean B注入到代理对象中,从而完成依赖的注入。
三十五.spring定时器的原理和实现
spring定时器基于Timer和timertask实现,可以使用@Scheduled来实现定时任务。可以指定执行时间,执行间隔。
三十六.springboot和springcloud的区别*
1.springboot是主要关注单个应用程序的开发,springcloud则关注分布式系统的开发。
2.springboot是一个快速开发框架,它可以帮助开发人员快速构建基于spring的应用程序。springcloud是基于springboot的微服务框架,用于构建分布式系统中的各种服务。
三十七.谈一谈jvm内存模型
1.jvm内存模型是java虚拟机在运行时对内存的管理和分配方式。
2.jvm内存模型主要分为堆内存和栈内存,其次还有本地方法栈和方法区。
3.堆内存主要存储对象。它是所有线程共享的。堆内存里的对象需要通过引用来访问。
4.栈内存主要存储方法,每个线程都有各自的栈内存。栈中主要存储方法的局部变量,当一个方法被调用,就会创建新的栈帧,执行完后栈帧弹出,释放内存。
5.方法区用来存放类的信息以及静态变量,本地方法栈用来支持本地方法的调用。
三十八.谈一谈对jvm的理解
1.jvm是java虚拟机的缩写,是java的运行环境,它负责将java程序编译后的字节码文件解释成机器码并执行。jvm主要的功能包括内存管理,垃圾回收,线程管理和安全性管理。
2.jvm的垃圾回收机制可以自动回收不在被使用的对象的内存空间,保证程序的内存使用效率。
三十九.HashMap是线程安全的吗?如果不是该如何解决*
hashmap是线程不安全的,为了解决这个问题,可以使用concurrentHashmap,它是线程安全的HashMap实现,另外可以使用synchronrized关键字或者Lock来保证线程安全。
四十.请说一说多线程
1.多线程是指在程序中同时运行多个线程,每个线程都可以独立执行不同的任务,多线程可以提高程序的效率和反应速度。
2.它可能会带来线程安全和死锁等问题。
3.可以使用synchronized关键字和实现Lock接口来保证线程安全。
四十一.说一下深拷贝和浅拷贝的区别
答:浅拷贝只会复制引用,而不是对象本身,这时若其中一个对象修改了,则另一个对象也会被影响。而深拷贝是会将原始对象进行递归复制,原始对象和拷贝对象都有各自独立的空间,互不影响。
四十二.比如在搭建mybatis时,读取不到mybatis-config配置文件时,这时候有什么办法吗
答:可以使用@MapperScan来扫描指定包下的mapper接口,将其注册为Mapper对象,mybatis框架可以正确使用。
四十三.Java泛型这块了解吗,什么是类型擦除
1.泛型:Java在jdk1.5引入了泛型,在没有泛型之前,每次从集合中读取的对象都必须进行类型转换,如果在插入对象时,类型出错,那么在运行时转换处理的阶段就出错;在提出泛型之后就可以明确的指定集合接受哪些对象类型,编译器就能知晓并且自动为插入的代码进行泛化,在编译阶段告知是否插入类型错误的对象,程序会变得更加安全清晰。 2.泛型擦除:Java泛型是伪泛型,因为Java代码在编译阶段,所有的泛型信息会被擦除,Java的泛型基本上都是在编辑器这个层次上实现的,在生成的字节码文件中是不包含泛型信息的,使用泛型的时候加上的类型,在编译阶段会被擦除掉,这个过程称为泛型擦除。
四十四.什么是线程死锁,如何避免线程死锁呢
四十五.springboot最核心的注解是什么,这个框架通过这个注解读取到一个配置,如何读取的,你去了解过吗
四十六.final,finally,finalize的区别:
final用于声明属性,可以声明对象、方法和类,分别表示对象不可变,方法不可覆盖,类不可被继承。finally是异常处理语句的一部分,表示总是执行,finalize是object的一个类,在垃圾回收器执行的时候调用被回收对象的该方法,可以覆盖该方法来关闭文件。
四十七.hashmap的扩容机制*
1.7版本:先生成新数组,然后遍历老数组中的链表上每个元素,取每个元素的key,并基于新数组长度,计算出每个元素的数组下标,将元素添加到新数组上去。
1.8版本:先生成新数组,然后遍历老数组中的链表或红黑树上每个元素,如果是链表,则直接将链表上的元素重新计算下标,直接添加到新数组上去。
如果是红黑树,则先遍历红黑树,若该位置的下标超过8个,则生成新的红黑树,反之生成链表
四十八.sleep()和wait()的区别
sleep是线程类的方法,他的作用是使线程暂停指定的时间,时间到自动恢复,不会释放锁,而wait是object类的方法,他的作用是本线程放弃对象锁,进入锁池,只有对象执行notify方法时才会重新去获得锁。