自己做的面试总结

面向对象

一切皆为对象,面向对象注重事情有哪些参与者

封装:允许外部所有的成员函数和数据项对内部细节的调用,外部调用无需修改或关心内部实现

继承:继承基类的方法,并做出自己的改变或扩展,子类共性的方法或者属性直接使用父类的,不需要自己再定义,只需扩展自己的个性化

多态:必须有继承,重写,父类引用指向子类对象,无法调用子类特有的方法

比如:父类类型 变量名 = new 子类对象

​ 变量名.方法名()

JDK、JRE、JVM的区别

JDK:开发工具

JRE:java运行时的环境

JVN:java虚拟机

JDK包含JRE包含JVM

==和equals区别

==对比的是栈中的值,基本数据类型是变量型,引用类型是堆中内存对象的地址

equals:object中默认采用==,通常会重写

final

最终类

修饰类:表示类不可以被继承

修饰方法:表示方法不可被子类覆盖(重写),但可以重载

修饰变量:表示变量一旦被赋值就不可更改它的值

1、修饰成员变量

如果修饰的是类的变量,只能在静态代码块中初始值或者声明改变量时指定初始值

如果修饰的是成员变量,可以在非静态初始化块,声明改变量或者构造器中初始值

2、修饰局部变量

一定要在使用时赋值,定义时不赋值不会报错

3、修饰基本类型和引用类型

基本类型:一旦初始化不能被改变

引用类型:初始化都不能指向另一个对象,但是引用值可以变

string stringbuffer stringbuilder区别

string时final修饰的,不可变,每次操作都会产生新的string对象

stringbuffer和stringbuilder都是在原对象中操作

stringbuffer是线程安全的stringbuilder线程不安全

stringbuffer方法是synchronized修饰的

性能stringbuilder>stringbuffer>string

重载和重写的区别

重载:发生在同一个类里面,方法名相同,参数类型不同,个数不同,顺序不同,方法返回值和访问修饰符可以不同

重写:发生在父类和子类中,方法名和参数列表必须相同,返回值范围小于父类,抛出异常范围小于父类,访问修饰符大于父类,如何访问修饰符父类为private则子类不能重写改方法

接口和抽象类的区别

抽象类可以存在普通成员函数,而接口只能存在public和abstract方法

抽象类成员变量可以是各种类型的,而接口的成员变量只能是public static final类型的

抽象类是单继承,接口多实现

list和set区别

list:有序的,按对象进入顺序保存对象,可重复,允许存在多个null值对象,可以用迭代器取出所有元素,再逐一遍历,还可以使用get(inr index)获取指定下标的元素

set:无序的,不可重复,最多允许一个null元素对象,去元素时只能用迭代接口取出所有元素,再逐一遍历各个元素

hashcode和equals

  • equals : Object 的 实例方法,比较两个对象的content是否相同
  • hashCode : Object 的 native方法 , 获取对象的哈希值,用于确定该对象在哈希表中的索引位置,它实际上是一个int型整数

arraylist和linkedlist的区别

arrayList:基于动态数组,查询快

linkedList:基于链表,增删快

hashMap和hashTable的区别

(1)HashMap方法没有synchronized修饰,线程非安全,HashTable线程安全;

(2)HashMap允许key和value为null,而HashTable不允许

底层实现:数组+链表实现 jdk8开始链表高度到8、数组长度超过64,链表转变为红黑树,元素以内部类Node节点存在

spring

如何实现一个ioc容器

1、配置文件扫描包路径

2、递归包扫描获取.class文件

3、反射、确定需要交给IOC管理的类

4、对需要注入的类进行依赖注入

spring是什么

轻量级的开源的J2EE框架。它是一个容器框架,用来装javabean(java对象),中间层框架(万能胶) 可以起一个连接作用,比如说把Struts和hibernate粘合在一起运用,可以让我们的企业开发更快、更简 洁

Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架

–从大小与开销两方面而言Spring都是轻量级的。

–通过控制反转(IoC)的技术达到松耦合的目的

–提供了面向切面编程的丰富支持,允许通过分离应用的业务逻辑与系统级服务进行内聚性的

开发

–包含并管理应用对象(Bean)的配置和生命周期,这个意义上是一个容器。

–将简单的组件配置、组合成为复杂的应用,这个意义上是一个框架。

AOP理解

将程序中的交叉业务逻辑(比如安全,日志,事务等),封装成一个切面,然后注入到目标对象

(具体业务逻辑)中去。AOP可以对某个对象或某些对象的功能进行增强,比如对象中的方法进行增

强,可以在执行某个方法之前额外的做一些事情,在某个方法执行之后额外的做一些事情

IOC理解

容器概念、控制反转、依赖注入

ioc容器:
实际上就是个map(key,value),里面存的是各种对象(在xml里配置的bean节点、

@repository、@service、@controller、@component),在项目启动的时候会读取配置文件里面的 bean节点,根据全限定类名使用反射创建对象放到map里、扫描到打上上述注解的类还是通过反射创 建对象放到map里。

这个时候map里就有各种对象了,接下来我们在代码里需要用到里面的对象时,再通过DI注入

(autowired、resource等注解,xml里bean节点内的ref属性,项目启动的时候会读取xml节点ref属性 根据id注入,也会扫描这些注解,根据类型或id注入;id就是对象名)。

控制反转:

没有引入IOC容器之前,对象A依赖于对象B,那么对象A在初始化或者运行到某一点的时候,自己必须 主动去创建对象B或者使用已经创建的对象B。无论是创建还是使用对象B,控制权都在自己手上。

引入IOC容器之后,对象A与对象B之间失去了直接联系,当对象A运行到需要对象B的时候,IOC容器会 主动创建一个对象B注入到对象A需要的地方。

通过前后的对比,不难看出来:对象A获得依赖对象B的过程,由主动行为变为了被动行为,控制权颠倒 过来了,这就是“控制反转”这个名称的由来。

全部对象的控制权全部上缴给“第三方”IOC容器,所以,IOC容器成了整个系统的关键核心,它起到了一 种类似“粘合剂”的作用,把系统中的所有对象粘合在一起发挥作用,如果没有这个“粘合剂”,对象与对 象之间会彼此失去联系,这就是有人把IOC容器比喻成“粘合剂”的由来。

依赖注入:

“获得依赖对象的过程被反转了”。控制被反转之后,获得依赖对象的过程由自身管理变为了由IOC容器 主动注入。依赖注入是实现IOC的方法,就是由IOC容器在运行期间,动态地将某种依赖关系注入到对 象之中。

BeanFactory和ApplicationContext有什么区别?

ApplicationContext是BeanFactory的子接口 ApplicationContext提供了更完整的功能:

①继承MessageSource,因此支持国际化。

②统一的资源文件访问方式。

③提供在监听器中注册bean的事件。

④同时加载多个配置文件。

⑤载入多个(有继承关系)上下文 ,使得每一个上下文都专注于一个特定的层次,比如应用的web层。

Spring Bean的生命周期?

1、解析类得到BeanDefinition 2、如果有多个构造方法,则要推断构造方法

3、确定好构造方法后,进行实例化得到一个对象

4、对对象中的加了@Autowired注解的属性进行属性填充

5、回调Aware方法,比如BeanNameAware,BeanFactoryAware

6、调用BeanPostProcessor的初始化前的方法

7、调用初始化方法

8、调用BeanPostProcessor的初始化后的方法,在这里会进行AOP

9、如果当前创建的bean是单例的则会把bean放入单例池

10、使用bean

11、Spring容器关闭时调用DisposableBean中destory()方法

Spring支持的几种bean的作用域。

singleton:默认,每个容器中只有一个bean的实例,单例的模式由BeanFactory自身来维护。该 对象的生命周期是与Spring IOC容器一致的(但在第一次被注入时才会创建)。

prototype:为每一个bean请求提供一个实例。在每次注入时都会创建一个新的对象

request:bean被定义为在每个HTTP请求中创建一个单例对象,也就是说在单个请求中都会复用 这一个单例对象。

session:与request范围类似,确保每个session中有一个bean的实例,在session过期后,bean

会随之失效。

application:bean被定义为在ServletContext的生命周期中复用一个单例对象。 websocket:bean被定义为在websocket的生命周期中复用一个单例对象。

global-session:全局作用域,global-session和Portlet应用相关。当你的应用部署在Portlet容器

中工作时,它包含很多portlet。如果你想要声明让所有的portlet共用全局的存储变量的话,那么 这全局变量需要存储在global-session中。全局作用域与Servlet中的session作用域效果相同。

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

1.工厂模式,这个很明显,在各种BeanFactory以及ApplicationContext创建中都用到了;

2.模版模式,这个也很明显,在各种BeanFactory以及ApplicationContext实现中也都用到了;

3.代理模式,在Aop实现中用到了JDK的动态代理;

4.单例模式,这个比如在创建bean的时候。

5.Tomcat中有很多场景都使用到了外观模式,因为Tomcat中有很多不同的组件,每个组件需要相互通信,但又不能将自己内部数据过多地暴露给其他组件。用外观模式隔离数据是个很好的方法。

6.策略模式在Java中的应用,这个太明显了,因为Comparator这个接口简直就是为策略模式而生的。Comparable和Comparator的区别一文中,详细讲了Comparator的使用。比方说Collections里面有一个sort方法,因为集合里面的元素有可能是复合对象,复合对象并不像基本数据类型,可以根据大小排序,复合对象怎么排序呢?基于这个问题考虑,Java要求如果定义的复合对象要有排序的功能,就自行实现Comparable接口或Comparator接口.

7.原型模式:使用原型模式创建对象比直接new一个对象在性能上好得多,因为Object类的clone()方法是一个native方法,它直接操作内存中的二进制流,特别是复制大对象时,性能的差别非常明显。

8.迭代器模式:Iterable接口和Iterator接口 这两个都是迭代相关的接口,可以这么认为,实现了Iterable接口,则表示某个对象是可被迭代的;Iterator接口相当于是一个迭代器,实现了Iterator接口,等于具体定义了这个可被迭代的对象时如何进行迭代的

Spring事务的隔离级别

spring事务隔离级别就是数据库的隔离级别:外加一个默认级别 read uncommitted(未提交读)

read committed(提交读、不可重复读)

repeatable read(可重复读)

serializable(可串行化)

Spring Boot、Spring MVC 和 Spring 有什么区别

spring是一个IOC容器,用来管理Bean,使用依赖注入实现控制反转,可以很方便的整合各种框架,提 供AOP机制弥补OOP的代码重复问题、更方便将不同类不同方法中的共同处理抽取成切面、自动注入给 方法执行,比如日志、异常等

springmvc是spring对web框架的一个解决方案,提供了一个总的前端控制器Servlet,用来接收请求, 然后定义了一套路由策略(url到handle的映射)及适配执行handle,将handle结果使用视图解析技术 生成视图展现给前端

springboot是spring提供的一个快速开发工具包,让程序员能更方便、更快速的开发spring+springmvc 应用,简化了配置(约定了默认配置),整合了一系列的解决方案(starter机制)、redis、 mongodb、es,可以开箱即用

SpringMVC 工作流程

1)用户发送请求至前端控制器 DispatcherServlet。 2)DispatcherServlet 收到请求调用 HandlerMapping 处理器映射器。

3)处理器映射器找到具体的处理器(可以根据 xml 配置、注解进行查找),生成处理器及处理器拦截器

(如果有则生成)一并返回给 DispatcherServlet。

4)DispatcherServlet 调用 HandlerAdapter 处理器适配器。 5)HandlerAdapter 经过适配调用具体的处理器(Controller,也叫后端控制器) 6)Controller 执行完成返回 ModelAndView。

7)HandlerAdapter 将 controller 执行结果 ModelAndView 返回给 DispatcherServlet。8) DispatcherServlet 将 ModelAndView 传给 ViewReslover 视图解析器。

9)ViewReslover 解析后返回具体 View。

10)DispatcherServlet 根据 View 进行渲染视图(即将模型数据填充至视图中)。

11)DispatcherServlet 响应用户。

mybatis的优缺点

优点:

1、基于 SQL 语句编程,相当灵活,不会对应用程序或者数据库的现有设计造成任何影响,SQL 写在 XML 里,解除 sql 与程序代码的耦合,便于统一管理;提供 XML 标签, 支持编写动态 SQL 语句, 并 可重用。

2、与 JDBC 相比,减少了 50%以上的代码量,消除了 JDBC 大量冗余的代码,不需要手动开关连接;

3、很好的与各种数据库兼容( 因为 MyBatis 使用 JDBC 来连接数据库,所以只要JDBC 支持的数据库

MyBatis 都支持)。

4、能够与 Spring 很好的集成;

5、提供映射标签, 支持对象与数据库的 ORM 字段关系映射; 提供对象关系映射标签, 支持对象关 系组件维护。

缺点:

1、SQL 语句的编写工作量较大, 尤其当字段多、关联表多时, 对开发人员编写SQL 语句的功底有一 定要求。

2、SQL 语句依赖于数据库, 导致数据库移植性差, 不能随意更换数据库

#{}和${}的区别是什么?

#{}是预编译处理、是占位符, ${}是字符串替换、是拼接符。

Mybatis 在处理#{}时,会将 sql 中的#{}替换为?号,调用 PreparedStatement 来赋值;

Mybatis 在处理 时 , 就 是 把 {}时, 就是把 {}替换成变量的值,调用 Statement 来赋值;

#{} 的变量替换是在DBMS 中、变量替换后,#{} 对应的变量自动加上单引号

的 变 量 替 换 是 在 D B M S 外 、 变 量 替 换 后 , {} 的变量替换是在 DBMS 外、变量替换后, DBMS{} 对应的变量不会加上单引号 使用#{}可以有效的防止 SQL 注入, 提高系统安全性。

mysql索引的基本原理

索引用来快速地寻找那些具有特定值的记录。如果没有索引,一般来说执行查询时遍历整张表。 索引的原理:就是把无序的数据变成有序的查询

\1. 把创建了索引的列的内容进行排序

\2. 对排序结果生成倒排表

\3. 在倒排表内容上拼上数据地址链

\4. 在查询的时候,先拿到倒排表内容,再取出数据地址链,从而拿到具体数据

事务的基本特性和隔离级别

事务基本特性ACID分别是:

**原子性 **指的是一个事务中的操作要么全部成功,要么全部失败。

**一致性 **指的是数据库总是从一个一致性的状态转换到另外一个一致性的状态。比如A转账给B100块钱, 假设A只有90块,支付之前我们数据库里的数据都是符合约束的,但是如果事务执行成功了,我们的数据库 数据就破坏约束了,因此事务不能成功,这里我们说事务提供了一致性的保证

**隔离性 **指的是一个事务的修改在最终提交前,对其他事务是不可见的。

持久性指的是一旦事务提交,所做的修改就会永久保存到数据库中。

隔离性有4个隔离级别,分别是:

read uncommit 读未提交,可能会读到其他事务未提交的数据,也叫做脏读。

用户本来应该读取到id=1的用户age应该是10,结果读取到了其他事务还没有提交的事务,结果读 取结果age=20,这就是脏读。

read commit 读已提交,两次读取结果不一致,叫做不可重复读。 不可重复读解决了脏读的问题,他只会读取已经提交的事务。

用户开启事务读取id=1用户,查询到age=10,再次读取发现结果=20,在同一个事务里同一个查 询读取到不同的结果叫做不可重复读。

repeatable read 可重复复读,这是mysql的默认级别,就是每次读取结果都一样,但是有可能产 生幻读。

serializable 串行,一般是不会使用的,他会给每一行读取的数据加锁,会导致大量超时和锁竞争 的问题。

脏读(Drity Read):某个事务已更新一份数据,另一个事务在此时读取了同一份数据,由于某些原因, 前一个RollBack了操作,则后一个事务所读取的数据就会是不正确的。

不可重复读(Non-repeatable read):在一个事务的两次查询之中数据不一致,这可能是两次查询过程中 间插入了一个事务更新的原有的数据。

幻读(Phantom Read):在一个事务的两次查询中数据笔数不一致,例如有一个事务查询了几列(Row)数 据,而另一个事务却在此时插入了新的几列数据,先前的事务在接下来的查询中,就会发现有几列数据 是它先前所没有的。

redis RDB 和 AOF 机制

RDB:Redis DataBase

在指定的时间间隔内将内存中的数据集快照写入磁盘,实际操作过程是fork一个子进程,先将数据集写 入临时文件,写入成功后,再替换之前的文件,用二进制压缩存储。

优点:

1、整个Redis数据库将只包含一个文件 dump.rdb,方便持久化。 2、容灾性好,方便备份。

3、性能最大化,fork 子进程来完成写操作,让主进程继续处理命令,所以是 IO 最大化。使用单独子进 程来进行持久化,主进程不会进行任何 IO 操作,保证了 redis 的高性能

4.相对于数据集大时,比 AOF 的启动效率更高。

缺点:

1、数据安全性低。RDB 是间隔一段时间进行持久化,如果持久化之间 redis 发生故障,会发生数据丢 失。所以这种方式更适合数据要求不严谨的时候)

2、由于RDB是通过fork子进程来协助完成数据持久化工作的,因此,如果当数据集较大时,可能会导 致整个服务器停止服务几百毫秒,甚至是1秒钟。

AOF:Append Only File

以日志的形式记录服务器所处理的每一个写、删除操作,查询操作不会记录,以文本的方式记录,可以 打开文件看到详细的操作记录

优点:

1、数据安全,Redis中提供了3中同步策略,即每秒同步、每修改同步和不同步。事实上,每秒同步也 是异步完成的,其效率也是非常高的,所差的是一旦系统出现宕机现象,那么这一秒钟之内修改的数据 将会丢失。而每修改同步,我们可以将其视为同步持久化,即每次发生的数据变化都会被立即记录到磁 盘中。。

2、通过 append 模式写文件,即使中途服务器宕机也不会破坏已经存在的内容,可以通过 redis- check-aof 工具解决数据一致性问题。

3、AOF 机制的 rewrite 模式。定期对AOF文件进行重写,以达到压缩的目的

缺点:

1、AOF 文件比 RDB 文件大,且恢复速度慢。

2、数据集大的时候,比 rdb 启动效率低。

3、运行效率没有RDB高

AOF文件比RDB更新频率高,优先使用AOF还原数据。 AOF比RDB更安全也更大

RDB性能比AOF好 如果两个都配了优先加载AOF

缓存雪崩、缓存穿透、缓存击穿

缓存雪崩是指缓存同一时间大面积的失效,所以,后面的请求都会落到数据库上,造成数据库短时间内 承受大量请求而崩掉。

解决方案:

缓存数据的过期时间设置随机,防止同一时间大量数据过期现象发生。 给每一个缓存数据增加相应的缓存标记,记录缓存是否失效,如果缓存标记失效,则更新数据缓 存。

缓存预热 互斥锁

缓存穿透是指缓存和数据库中都没有的数据,导致所有的请求都落到数据库上,造成数据库短时间内承 受大量请求而崩掉。

解决方案:

接口层增加校验,如用户鉴权校验,id做基础校验,id<=0的直接拦截; 从缓存取不到的数据,在数据库中也没有取到,这时也可以将key-value对写为key-null,缓存有 效时间可以设置短点,如30秒(设置太长会导致正常情况也没法使用)。这样可以防止攻击用户 反复用同一个id暴力攻击

采用布隆过滤器,将所有可能存在的数据哈希到一个足够大的 bitmap 中,一个一定不存在的数据 会被这个 bitmap 拦截掉,从而避免了对底层存储系统的查询压力

缓存击穿是指缓存中没有但数据库中有的数据(一般是缓存时间到期),这时由于并发用户特别多,同 时读缓存没读到数据,又同时去数据库去取数据,引起数据库压力瞬间增大,造成过大压力。和缓存雪 崩不同的是,缓存击穿指并发查同一条数据,缓存雪崩是不同数据都过期了,很多数据都查不到从而查 数据库。

解决方案

设置热点数据永远不过期。 加互斥锁

springcloud核心组件及其作用

Eureka:服务注册与发现

注册:每个服务都向Eureka登记自己提供服务的元数据,包括服务的ip地址、端口号、版本号、通信协 议等。eureka将各个服务维护在了一个服务清单中(双层Map,第一层key是服务名,第二层key是实 例名,value是服务地址加端口)。同时对服务维持心跳,剔除不可用的服务,eureka集群各节点相互 注册每个实例中都有一样的服务清单。

发现:eureka注册的服务之间调用不需要指定服务地址,而是通过服务名向注册中心咨询,并获取所有 服务实例清单(缓存到本地),然后实现服务的请求访问。

Ribbon:服务间发起请求的时候,基于Ribbon做负载均衡,从⼀个服务的多台机器中选择⼀台 (被调 用方的服务地址有多个),Ribbon也是通过发起http请求,来进行的调用,只不过是通过调用服务名的 地址来实现的。虽然说Ribbon不用去具体请求服务实例的ip地址或域名了,但是每调用一个接口都还要 手动去发起Http请求

Feign:基于Feign的动态代理机制,根据注解和选择的机器,拼接请求URL地址,发起请求 ,简化服务 间的调用,在Ribbon的基础上进行了进一步的封装。单独抽出了一个组件,就是Spring Cloud Feign。 在引入Spring Cloud Feign后,我们只需要创建一个接口并用注解的方式来配置它,即可完成对服务提 供方的接口绑定。

调用远程就像调用本地服务一样Hystrix:发起请求是通过Hystrix的线程池来⾛的,不同的服务⾛不同的线程池,实现了不同服务调⽤ 的隔离,通过统计接口超时次数返回默认值,实现服务熔断和降级

Zuul:如果前端、移动端要调⽤后端系统,统⼀从Zuul⽹关进⼊,由Zuul⽹关转发请求给对应的服务, 通过与Eureka进行整合,将自身注册为Eureka下的应用,从Eureka下获取所有服务的实例,来进行服 务的路由。Zuul还提供了一套过滤器机制,开发者可以自己指定哪些规则的请求需要执行校验逻辑,只 有通过校验逻辑的请求才会被路由到具体服务实例上,否则返回错误提示。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值