个人面试题总结

spring

1.spring有哪些部分组成

Spring Context:提供框架式的Bean访问方式,以及企业级功能(JNDI、定时任务等);
Spring Core:核心类库,所有功能都依赖于该类库,提供IOC和DI服务;
Spring AOP:AOP服务;
Spring Web:提供了基本的面向Web的综合特性,提供对常见框架如Struts2的支持,Spring能够管理这些框架,将Spring的资源注入给框架,也能在这些框架的前后插入拦截器;
Spring MVC:提供面向Web应用的Model-View-Controller,即MVC实现。
Spring DAO:对JDBC的抽象封装,简化了数据访问异常的处理,并能统一管理JDBC事务;
Spring ORM:对现有的ORM框架的支持;

2.spring的启动流程

加载配置文件:Spring框架首先会读取并加载应用程序的配置文件。配置文件可以是XML文件(如applicationContext.xml)或者注解类(如@Configuration)。

创建Spring容器:Spring会根据配置文件中定义的Bean定义,创建一个容器(Application Context)。容器是Spring框架的核心,负责管理和组织各个Bean。

实例化Bean:容器根据配置文件中的Bean定义,在需要时实例化相应的Bean对象。实例化过程可以通过构造函数、工厂方法或者依赖注入来完成。

注入依赖:容器会自动为实例化的Bean对象注入其依赖的其他Bean对象。

执行自定义初始化方法:如果Bean类实现了InitializingBean接口或者在配置文件中指定了初始化方法,容器会在完成依赖注入后调用Bean的初始化方法。

Bean后置处理:容器会对Bean进行一些额外的处理,例如应用BeanPostProcessor接口实现类中定义的逻辑。

Bean准备就绪:当所有的Bean都初始化完成并且准备就绪时,Spring容器准备好为应用程序提供服务了。

执行应用程序:根据应用程序的需要,可以调用合适的方法或者触发事件来执行相应的应用程序逻辑。

3.spring中bean的生命周期

实例化,赋值,初始化,销毁

4.spring的bean默认单例的,怎么将其变为多例

将singleton属性设置为prototype

5.bean的注入方式

setter,构造器,注解

6.bean的装配方式

no    byname(@resource)    bytype(@autowrite)   构造函数  自动

7.spring的事务机制

编程式事务(TransactionTemplate)

声明式事务(@Transaction(异常类型),方法不是public时会失效)

8.spring的事务隔离级别

ISOLATION_DEFAULT:默认的隔离级别,同数据库

ISOLATION_READ_UNCOMMITTED:未提交读,允许事务在执行过程中,读取其他事务未提交的数据。(会出现幻读、脏读、不可重复读)

ISOLATION_READ_COMMITTED:提交读,允许事务在执行过程中,读取其他事务已经提交的数据。(会造成幻读、不可重复读)

ISOLATION_REPEATABLE_READ:可重复读,在同一个事务内,任意时刻的查询结果都是一致的。会造成幻读)

ISOLATION_SERIALIZABLE:所有事务逐个依次执行。

脏读 :表示一个事务能够读取另一个事务中还未提交的数据。比如,某个事务尝试插入记录 A,此时该事务还未提交,然后另一个事务尝试读取到了记录 A。

不可重复读 :是指在一个事务内,多次读同一数据,值发生修改。

幻读 :指同一个事务内多次查询返回的结果集不一样。比如同一个事务 A 第一次查询时候有 n 条记录,但是第二次同等条件下查询却有 n+1 条记录,这就好像产生了幻觉。

9.自定义注解的实现

使用@Target指定注解作用范围

使用@Retention指定注解的生命周期

springboot

1.springboot的启动流程

通过main方法 启动springboot,首先进入run方法

run方法新建SpringApplication对象,创建并启动计时监控类

初始化应用应用参数

根据运行监听器和参数准备spring环境

创建,准备,刷新应用上下文

停止计时监控器类

发布应用上下文 启动完成事件

最后返回应用上下文

2.springboot的静态首页可以放在那里

/resources/static目录下

也可以子自定义静态资源位置,在application.yml文件中配置static-locations指定目录

3.springboot静态资源的优先级

默认resource/static->public

也可以自定义指定spring.webservices.wsdl-locations=classpath:/staticNew

4.springboot热部署的方式

idea设置spring-boot-devtools

jrebel插件

springcloud

1.怎么实现服务的注册

在配置文件中配置服务名,注册的服务中心地址

启动类添加注解@EnableEurekaServer

2.怎么使用feigin

提供外部接口,添加注解@FeiginClient补充服务名称和映射地址

3.ribbon的使用

负载均衡:默认轮询,还提供随机,最优可用,响应速度

定义RestTemplate添加注解@Bean@LoadBalanced,通过restTemolate发起请求

4.zuul网关的作用

处理http请求,拦截,监控,身份验证

zuul仅支持同步,可用配套多个微服务框架

5.gateway的作用

处理http请求,拦截,监控,身份验证,对比zuul还能实现负载均衡

gateway支持异步,但指配套与springcloud,吞吐量比zuul高

Dubbo

1.dubbo和springCloud的区别

dubbo是基于rpc(基于底层tcp,不需要通过http包装,效率更高)协议的,不能跨平台,一般使用xml注释

cloud是基于http协议的,可以跨平台,一般使用注解

2.dubbo默认的通信框架

netty(默认):异步事件驱动框架,高并发,次延迟

mina:基于java nio的通信框架

3.dubbo的声明式缓存

分为类级别和方法级别的缓存,将cache设置为true,默认大小1000,超过会根据lur策略保留热门缓存

4.dubbo的容错策略

失败自动切换,失败立刻抛出异常,失败重发,失败忽略,并行调用,容错合并

5.dubbo的动态代理

一般使用jdk动态代理,是基于proxyFactory来实现

还有javassist动态代理

6.dubbo怎么设置版本号

xml:通过version设置

可以用来新旧版本的升级过渡

7.dubbo的负载均衡

通过loadBalance实现

有随机,轮询,权重,最短时间相应,最少链接,一致性哈希

Zookeeper

1.zookeeper的数据结构

zookeeper的数据结构称之为节点,最小节点是zndoe,是一种树桩结构

2.zookeeper的节点类型

持久性节点,临时性节点,顺序性持久节点,顺序性临时节点

3.创建节点

create 节点名 数据: 持久性节点

create -e :临时性节点

create -s :顺序性节点

4.读写锁(分布式锁)

zookeeper的节点是唯一性的,我们可以创建一个临时顺序性节点(避免羊群效应,一次通知太多的节点),节点名称可以带有read或write再加上节点名称,节点数据可以使用客户端id,客户端访问时会先判断是否存在锁,不存在则设置锁,存在则进入等待,等线程执行完后可以删除该临时节点,其他线程就可以根据watcher监听重新获取锁

5.怎么保证主从状态同步

通过zab协议的恢复模式和广播模式来保证主从状态同步

6.通知机制

通知机制用于监听znode的变化,变化时会通知客户端,注册一次性的watcher来监听事件,watcher不能保证事务的顺序性

7.zookeeper的特点

zookeeper是个数据库,文件存储系统,提供了事务监督通知,zookeeper更适用与传统的分布式场景

RocketMq,RabbitMq,Kafka

1.各自的特点和区别

rabbitmq:多语言,多协议,高可用高并发,有消息跟踪,有友好的可视化界面,不支持二次开发

rocketmq:高可用,低延迟,支持事务,延迟消息,有消息追踪,有可视化界面,多语言多协议,所有数据持久化,不支持消息优先级

kafka:低延迟,高吞吐量,高性能分布式储存,缺少可视化界面,不支持延迟消息,消息追踪

mybatis

1.mybatis的延迟加载

延迟加载又叫懒加载,也叫按需加载,也就是说先加载主信息,需要的时候,再去根据推迟策略加载从信息(直接加载,侵入式延时加载,深度延时加载)

开启方式:设置lazyLoadingEnabled=true

MyBatis 延迟加载是通过动态代理实现的,当调用配直为延迟加载的属性方法时, 动态代

理的操作会被触发,这些额外的操作就是通过 MyBatis 的 SqlSessio口去执行嵌套 SQL 的 。

由于在和某些框架集成时, SqlSession 的生命周期交给了框架来管理,因此当对象超出

SqlSession 生命周期调用时,会由于链接关闭等问题而抛出异常 。

2.mybatis的二级缓存

一级缓存默认开启,基于sqlSession实现的,底层依旧属于hashmap结构

二级缓存需要手动开启,添加配置或是使用注解,是基于mapper文件的namespace的实现的,底层依旧属于hashmap结构

3.mybatis的执行器

简单执行器:这是默认的执行器类型,它每次执行都会创建一个Statement对象,并立即执行SQL语句。这种执行器不支持事务

重用执行器:当需要执行相同的SQL语句时,会直接使用缓存的Statement对象,而不是每次都创建新的对象。这种执行器也不支持事务

批处理执行器:这种执行器用于批量操作,可以一次执行多个SQL语句

4.查询大量数据避免内存溢出怎么处理

流式查询:建立长链接,利用服务端游标,每次读取一条加载一条

游标查询:通过fetchSize控制一次读取多少条

5.大量数据怎么排序

合理简历索引,创建索引时,索引已经帮忙排序了

6.mybatis怎么映射的

resultType:自动映射

resultMap:自定义映射

mysql

1.索引的结构和储存位置

b+树结构

叶子节点存放的是实际的行数据,而非叶子节点存放的是主键和页号

mysql会将索引存到磁盘上,但会将常用的索引存到内存中,有限查询内存再查询磁盘

2.聚簇索引和非聚簇索引的区别

聚簇索引的叶子节点储存的是数据行和主键值

非聚簇索引索引的叶子节点储存的是主键值和数据记录地址,查询需要回表(所有查询条件都命中索引时不会回表)

3.索引的类型

聚簇索引,非聚簇索引

覆盖索引(索引包含所有查询条件)

联合索引

唯一索引(保证数据的唯一性,主键id)

主键索引(表中的第一个索引)

全文索引(对文本内存进行提取)

4.索引失效的方式

联合索引不满足最左前缀法则,左模糊匹配,列运算,使用函数,类型转换,使用is not null,使用or,非驱动表使用orderby

5.explan后各属性意思

id:列数字越大越先执行

select_type:查询类型

table:表名

type:查询的结果类型(除了all外其他的都使用到了索引)

possible_keys:可能使用到的索引

key:真正使用到的索引

key_len:索引长度

rows:预估扫描的行数

6.mysql三范式

保证原子性,数据的每一列都是不可分割的原子数据项

实体属性必须完全依赖主关键字

任何非主属性不依赖其他非主属性

7.ACID是什么

原子性:要么全部完成要么全部失败

一致性:数据的完整性没有遭到破坏

隔离性:允许多个事务对数据进行读写

持久性:对数据的修改时永久的,不会丢失

8.mysql两种引擎的区别

innoDB:支持事务,行锁表锁,不会记录表的数据量,查询count时会扫描全表

myIASM:不支持事务,只支持表锁,会记录表的数据量

行锁:开销大,加锁慢,会出现死锁,锁冲突概率小,并发高

表锁:开销小,加锁块,不会死锁,锁冲突概率大,并发低

9.可以使用多少列创建索引

一个表最多给16个列建索引

10.如何优化distinct

根据业务场景合理使用orderby和内查询解决

11.now()和cruuent_date()的区别

now()返回的时间更详细包含了年月日时分秒微秒,cruuent_date只包含年月日

12.列对比运算符是什么

就是逻辑运算符(=,>,<,in,like之类的)

13.主键和候选键的区别

每个表必须有主键,且不能为空,候选键不一定存在,可以为多列组合,且可以为空

14.mysql有哪些不同的表格

事务安全型:BDB,InnoDB

非事务安全型:HEAP,ISAM,MERGE,MYISAM,MERGE

15.怎么保证分库时同一个用户数据落到同一个库

基于用户id进行分库

16.怎么实现主从数据库

在主服务器上,设置一个从数据库的账户,使用replication slave赋予权限

修改主数据的配置文件,开启binlog,设置server-id的值

停止主数据库的更新,备份主数据库数据

修改从数据库的配置文件,增加server-id指定复制的数据库

从服务器启动slave进程和show salve status验证

17.怎么实现分库分表

可以使用mycat,mybatis-sharding插件完成分表

18.怎么保证主从一致性

半同步复制:事务在主库写完binlog后,需要从库返回一个已接收,才能返回给客户端

数据库中间件:所有的读写都走中间件,记录所有路由到写库的key, 如果在主从同步的窗口内有读请求过来了,就需要将key上的读请求路由到主库访问

19.插件有哪些分表规则

按值的范围,按值的hash,按指定的值,自定义字段,按取模结果

线程

1.线程池参数

最大线程数,核心线程数,空闲线程存活时间,时间单位,工作队列,线程工厂,拒绝策略

新任务会优先进队列,队列满了就会创建新线程,当线程和队列都满了就会走拒绝策略

2.三个线程123,如何保证顺序执行

创建三个线程,分别调用方法,提供参数打印顺序(0,1,2)和打印的东西

提供公共参数打印次数,方法内部使用for循环,在循环内上锁,根据打印次数取余3来判断该由那个线程打印

private int time;// 控制打印次数
private int state;// 当前状态值:保证三个线程之间交替打印

public void print(String str, int targetNum) {
        for (int i = 0; i < time; ) {
            lock.lock();//上锁
            //只有满足顺序条件的时候才打印 并且state++和i++
            if (state % 3 == targetNum) {
                state++;
                i++;
                System.out.print(str);
            }
            lock.unlock();//解锁
        }
}

        Thread A = new Thread(() -> {
            th.print("A", 0);
        });

        Thread B = new Thread(() -> {
            th.print("B", 1);
        });

        Thread C = new Thread(() -> {
            th.print("C", 2);
        });

        B.start();
        A.start();
        C.start();
3.可见性和安全性的区别

可见性:线程对数据的操作可以被其他线程发现

安全性:多个现场交替执行时,不需要进行额外的同步操作,依旧能保证数据的正确性

4.原子性和一致性的区别

原子性:一起成功一起失败

一致性:数据操作的完整性

5.cpu数量和线程池数量的关系

cpu密集型的应用:线程池线程数=cpu线程数+1

io密集型应用:线程池线程数=cpu线程数*2+1

6.cas的机制

cas是jdk提供的非阻塞原子操作,是使用cmpxchg命令实现cpu独占的,他会对总线加锁并且只有一个线程能加锁,对比synchronized来说cas的排他时间更短

缺点:cas是乐观锁的一种实现,在竞争激烈的情况下容易造成cpu空转,浪费cpu性能

7.volatile的作用

变量修饰符,让其对线程保持修改可见性

容器

1.hashmap实现原理

会根据key的hash值计算取出对应下标进行储存,当hash值一致时会造成hash冲突,此时会根据equals判断是否重复,会将不重复的数据插入链表中(1.7头插法,1,8尾插法),当链表数据超过8时,会将链表转化为红黑树结构,hashmap默认储存容量是16,当超过初始因子(0.75)后,会进行扩容2倍

负载因子设计大了,则容易发生哈希冲突,设计小了,不能充分利用空间,0.75这个值是通过数学中的泊松分布计算出来的,可以达到一个最好的平衡

2.ConcurrentHashMap实现原理

1.7使用分段锁,将数据分为多段,每段都相当于hashmap,让元素自己管理自己的锁

1.8使用cas+synchronized

3.synchronizedMap实现原理

通过synchronized来保证只有一个线程对map进行操作

4.linkedHashMap怎么实现有序

hashmap+双向链表(记录插入顺序)

5.vectory底层实现原理

其中大部分的方法都被synchronized关键字所修饰

io

1.BIO和NIO的区别

bio是面向流的单向传输

nio是面向缓存的双向传输,通过通道和缓冲区来处理io

2.怎么实现多路复用

通过选择器监听通道事件,来轮询读写

网络

1.http和https

http链接简单,默认采用80端口,数据是明文传输

https采用ssl进行加密传输,默认端口443

2.mqtt

mqtt是一种轻量级协议,采用长链接保持通信,消息头和消息都很小,确保了高传输保证,吞吐量远远大于http

3.tcp怎么保证传输安全

校验和,序列号,确认应答,超时重传,连接管理,流量控制

4.osi七层模型
  • 物理层:利用传输介质为数据链路层提供物理连接,实现比特流的透明传输。
  • 数据链路层:负责建立和管理节点间的链路。
  • 网络层:通过路由选择算法,为报文或分组通过通信子网选择最适当的路径。
  • 传输层:向用户提供可靠的端到端的差错和流量控制,保证报文的正确传输。
  • 会话层:向两个实体的表示层提供建立和使用连接的方法。
  • 表示层:处理用户信息的表示问题,如编码、数据格式转换和加密解密等。
  • 应用层:直接向用户提供服务,完成用户希望在网络上完成的各种工作。
5.session和cookie

session:服务器创建sessionid后会发送到客户端,客户端放到浏览器储存,之后请求都会带着sessionid进去确认

  • 存储位置不同:session 存储在服务器端;cookie 存储在浏览器端。
  • 安全性不同:cookie 安全性一般,在浏览器存储,可以被伪造和修改。
  • 容量和个数限制:cookie 有容量限制,每个站点下的 cookie 也有个数限制。
  • 存储的多样性:session 可以存储在 Redis 中、数据库中、应用程序中;而 cookie 只能存储在浏览器中。
6.分布式session怎么实现
  • 将一台机器上的session,广播复制到集群其他机器上
  • 强制将后续请求放在同一个机器上
  • 将session存到分布式缓存集群中,用户访问时先从缓存中拿session
7.浏览器输入url后的执行流程

网页重定向,本地缓存,域名解析,建立tcp连接,浏览器发送http请求,服务端响应http请求,断开http连接,返回数据渲染页面

8.怎么保证网络请求的安全

token校验

ip黑名单,白名单

时间戳加密:客户端请求携带加密时间戳,服务端解密判断时间戳间隔

jvm

1.jvm组成

类加载器:装载class文件到方法区

运行时数据区:jvm内存

执行引擎:解释命令交给操作系统执行

本地库接口:与其他编程语言交互接口

2.类加载的流程

加载:将类转化为二级制字节流

验证:检查类的文件格式,元数据,字节码,符号引用

准备:为变量开辟空间,初始化

解析:将符号引用转化为直接引用

初始化:执行字节码文件,开始初始化方法

3.类加载器和双亲委派模型

启动类加载器,应用程序类加载器,拓展类加载器,其他类加载器

当需要进行类加载时,当前加载器会将请求交给父级去执行,父级继续向父级加载,直到父级无法加载时,才会在当前加载器进行加载

保证了java程序的稳定执行,避免重复加载

4.堆,栈,队列的区别

堆:二叉树结构,线程共享,空间大,用来存放对象

栈:线程私有,空间小,用来执行方法,先进后出

队列:先进先出

5.怎么判断对象是否能回收

引用计数器:对象被引用时计数器+1,被释放时-1,为0时可以被回收,不能解决循环依赖

可达性分析:从GC Roots 开始向下搜索,搜索所走过的路径称为引用链。当一个对象到 GC Roots 没有任何引用链相连时,则证明此对象是可以被回收的

6.垃圾回收算法
  • 标记-清除算法:标记无用对象,然后进行清除回收。缺点:效率不高,无法清除垃圾碎片。
  • 标记-整理算法:标记无用对象,让所有存活的对象都向一端移动,然后直接清除掉端边界以外的内存。
  • 复制算法:按照容量划分二个大小相等的内存区域,当一块用完的时候将活着的对象复制到另一块上,然后再把已使用的内存空间一次清理掉。缺点:内存使用率不高,只有原来的一半。
  • 分代算法:根据对象存活周期的不同将内存划分为几块,一般是新生代和老年代,新生代基本采用复制算法,老年代采用标记整理算法。
7.垃圾回收器
  • Serial:最早的单线程串行垃圾回收器。
  • Serial Old:Serial 垃圾回收器的老年版本
  • ParNew:是 Serial 的多线程版本。
  • CMS:一种以获得最短停顿时间为目标的收集器,非常适用 B/S 系统。
  • G1:一种兼顾吞吐量和停顿时间的 GC 实现,是 JDK 9 以后的默认 GC 选项。
8.年轻代,老年代

分代回收器有两个分区:老生代和新生代,新生代默认的空间占比总空间的 1/3,老生代的默认占比是 2/3。

新生代使用的是复制算法,新生代里有 3 个分区:Eden、To Survivor、From Survivor,它们的默认占比是 8:1:1,它的执行流程如下:

  • 把 Eden + From Survivor 存活的对象放入 To Survivor 区;
  • 清空 Eden 和 From Survivor 分区;
  • From Survivor 和 To Survivor 分区交换,From Survivor 变 To Survivor,To Survivor 变 From Survivor。

每次在 From Survivor 到 To Survivor 移动时都存活的对象,年龄就 +1,当年龄到达 15(默认配置是 15)时,升级为老生代。大对象也会直接进入老生代,一般使用标记整理的执行算法

9.jvm调优参数

1、尽可能让对象在新生代里分配和回收,避免对象频繁进入老年代导致老年代频繁垃圾回收;
2、给系统充足的内存空间,避免新生代频繁的垃圾回收;
3、指定合适的垃圾收集器;

10.cpu100%怎么排查

通过top名称查看pid和线程号

通过命令输出进程的线程文件

分布式

1.分布式事务
2.怎么实现分布式锁

使用数据的乐观锁,悲观锁实现

使用redis分布式锁

使用zookeeper的临时性顺序节点

3.分布式接口的幂等性

乐观锁

数据库主键

4.分布式锁的限流

使用redis的令牌桶算法,将token list存到redis中,设置令牌最大数量,判断redis中获取令牌的token数据,超出最大值直接拒绝访问,否则重试设置令牌数量及过期时间

使用reids的计数器算法,记录ip的请求次数,设置过期时间,超过阈值直接拒绝访问

数据结构

1.二叉树

每个节点最多只有左右两个节点

2.红黑树

是一种平衡二叉查找树,减小了二叉树的深度,提高了查找效率,极端情况下可能会蜕变为链表

根节点是黑的,所有的叶子都是黑的空节点,每个红节点必须有两个黑色的子节点

3.b树和b+树
4.散列表

5.二叉查找树

任意节点的左子树不为空,且左子树上任意节点小于根节点

任意节点的右子树不为空,且右子树上任意节点小于根节点

算法

1.冒泡排序

当数组中前一个元素大于后一个元素,交换,使得较小的元素移动到前面,较大的移动到后面,重复对比和交换的过程

    //冒泡排序
    public static void bubbleSort(int[] array){
        for(int i = 0; i < array.length-1; i++ ){
            for(int j = 0 ; j < array.length-1-i; j++){
                if(array[j] > array[j+1]){
                    swap(array,j,j+1);
                }
            }
        }
    }
2.选择排序

每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置

    //选择排序--直接选择排序
    public static void selectSort(int[] array){
        // 外层循环表示需要走的内层循环趟数
        // 每走一次内层循环,就有一个元素(当前最小值)放在正确位置
        for(int i = 0; i< array.length-1; i++){
            int min = i;
            for(int j = i + 1;j < array.length;j++){
                if(array[min] > array[j]){
                    min = j;
                }
            }
            // 此时min就保存了最小值索引,交换i和min的元素即可
            swap(array,i,min);
        }
    }
3.插入排序
4.二分查找
5.快速排序
6.希尔排序
7.最短路径算法
8.md5

设计模式

1.实现单例模式
2.实现策略者模式
3.实现原型模式
4.实现外观模式

git

1.git相关命令

nginx

vue

1.vue路由的作用
2.vue传值

  • 18
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值