java面试题整理(找工作过程中的积累)

java面试题链接:https://blog.csdn.net/weixin_43495390/article/details/86533482

一、redis是怎么把数据存储到内存中的
参考链接:https://www.cnblogs.com/chuijingjing/p/10075552.html
数据是如何存储的?
Redis 中是把数据保存到内存中的,但是它也会定期的把数据写会到硬盘中。
Redis是一款内存高速缓存数据库;

数据模型为:key - value,非关系型数据库使用的存储数据的格式;

可持久化:将内存数据在写入之后按照一定格式存储在磁盘文件中,宕机、断电后可以重启redis时读取磁盘中文件恢复缓存数据;
分布式:当前任务被多个节点切分处理,叫做分布式处理一个任务。单个服务器内存,磁盘空间有限,无法处理海量的缓存数据,必须支持分布式的结构;

nosql:not only structured query language 不仅仅结构化查询语言

结构化数据:有规律的一类数据;例如:人的信息,动物信息,考试信息

非结构化数据:海量的不具备任何共同特性的数据集合;例如:网页,日志;图片

关系型数据库:体现不同类结构化数据之间的关系的数据,例如ORACLE mysql

非关系型数据库:存储的是非结构化的海量数据;无法体现数据的关系;例如 mongoDB redis

Redis保存数据有两种方式,
1.快照模式(Snapshot) RDB方式,是将redis某一时刻的数据持久化到磁盘中,是一种快照式的持久化方法。
redis在进行数据持久化的过程中,会先将数据写入到一个临时文件中,待持久化过程都结束了,才会用这个临时文件替换上次持久化好的文件。正是这种特性,让我们可以随时来进行备份,因为快照文件总是完整可用的。

定时快照,即按一定时间将内存中的数据保存到磁盘上。
定量快照,即数据变化一定次数后将数据保存到磁盘上。
你也可以结合这两种方式,比如变化 1000 次,距离上次保存时间 60 秒以上才保存数据。

2.写模式(Append Only File)。这种模式下Redis会把所有修改数据的命令(如Update,Set)等保存到一个只能追加的ASAP文件中,当Redis重启时,它会把这个文件里的命令重新执行一遍。配置redis.conf中的appendonly yes就可以打开AOF功能。如果有写操作(如SET等),redis就会被追加到AOF文件的末尾。
数据保存到哪里?
数据是保存到一个数据文件中的,具体文件名要看 Redis 的配置文件,即 redis.conf,默认就在 redis 的安装目录下。

config get dbfilename // 返回 dump.rdb
可以使用 config set dbfilename new (修改你要保存数据的文件)

数据如何到导出?
Redis 写数据时先写到一个 temp 文件中,然后再把 temp 文件重命名为预定义的文件,所以即使 Redis 在运行,也可以直接用 cp 命令拷贝这个文件。

cp /usr/loca/redis/demo.rdb /home/greenerycn/db/demo.rdb

Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)

Redis - 高并发,内存高速cache ,处理读写io的高并发容忍 参考链接:http://www.360doc.com/content/18/0318/11/43997888_738099429.shtml

redis的的特点,参考链接:https://www.cnblogs.com/lgj8/p/12734854.html

redis提供了两种持久化的方式,分别是RDB(Redis DataBase)和AOF(Append Only File)。 参考链接:https://zhuanlan.zhihu.com/p/85778397
RDB,简而言之,就是在不同的时间点,将redis存储的数据生成快照并存储到磁盘等介质上;
AOF,则是换了一个角度来实现持久化,那就是将redis执行过的所有写指令记录下来,在下次redis重新启动时,只要把这些写指令从前到后再重复执行一遍,就可以实现数据恢复了。
其实RDB和AOF两种方式也可以同时使用,在这种情况下,如果redis重启的话,则会优先采用AOF方式来进行数据恢复,这是因为AOF方式的数据恢复完整度更高。

二、set是如何实现不重复的?

在一个应用程序执行期间,如果一个对象的equals方法做比较所用到的信息没有被修改的话,则对该对象调用hashCode方法多次,它必须始终如一地返回同一个整数。如果两个对象根据equals(Object o)方法是相等的,则调用这两个对象中任一对象的hashCode方法必须产生相同的整数结果。

如果两个对象根据equals(Object o)方法是不相等的,则调用这两个对象中任一个对象的hashCode方法,不要求产生不同的整数结果。但如果能不同,则可能提高散列表的性能。

三、dubbo和spring cloud的区别

参考链接:https://blog.csdn.net/Jonny_jun_gao/article/details/91049778
1.社区活跃度
2.架构完整度
很多人会说Spring Cloud和Dubbo的对比有点不公平,Dubbo只是实现了服务治理,而Spring Cloud下面有17个子项目(可能还会新增)分别覆盖了微服务架构下的方方面面,服务治理只是其中的一个方面,一定程度来说,Dubbo只是Spring Cloud Netflix中的一个子集。
Dubbo实现了服务治理的基础,Dubbo具有调度、发现、监控、治理等功能,支持相当丰富的服务治理能力。但是要完成一个完备的微服务架构,还需要在各环节去扩展和完善以保证集群的健康,以减轻开发、测试以及运维各个环节上增加出来的压力,这样才能让各环节人员真正的专注于业务逻辑。而Spring Cloud依然发扬了Spring Source整合一切的作风,以标准化的姿态将一些微服务架构的成熟产品与框架揉为一体,并继承了Spring Boot简单配置、快速开发、轻松部署的特点,让原本复杂的架构工作变得相对容易上手一些(如果您读过我之前关于Spring Cloud的一些核心组件使用的文章,应该能体会这些让人兴奋而激动的特性,传送门)。所以,如果选择Dubbo请务必在各个环节做好整套解决方案的准备,不然很可能随着服务数量的增长,整个团队都将疲于应付各种架构上不足引起的困难。而如果选择Spring Cloud,相对来说每个环节都已经有了对应的组件支持,可能有些也不一定能满足你所有的需求,但是其活跃的社区与高速的迭代进度也会是你可以依靠的强大后盾。
4.文档质量
虽然Spring Cloud的文档量大,但是如果使用Dubbo去整合其他第三方组件,实际也是要去阅读大量第三方组件文档的,所以在文档量上,我觉得区别不大。对于文档质量,由于Spring Cloud的迭代很快,难免会出现不一致的情况,所以在质量上我认为Dubbo更好一些。而对于文档语言上,Dubbo自然对国内开发团队来说更有优势。

四、zookeeper的的文件系统是怎么存储数据的?

参考链接:https://blog.csdn.net/qichangjian/article/details/88184705

zooKeeper本质上是一个分布式的小文件存储系统,
Zookeeper提供一个多层级的节点命名空间(节点称为znode)。与文件系统不同的是,这些节点都可以设置关联的数据,而zk文件系统中只有文件节点可以存放数据而目录节点不行。

Zookeeper 为了保证高吞吐和低延迟,在内存中维护了这个树状的目录结构,这种特性使得 Zookeeper 不能用于存放大量的数据,每个节点的存放数据上限为1M。

zookeeper的文件系统的特点:

zk的文件系统和Linux的文件系统目录结构一样,从”“/开始
zk的访问路径只有绝对路径,没有相对路径。
zk中没有文件和目录的概念,只有znode节点,Znode既有文件的功能,又有目录的功能。

3.zookeeper的监听机制
(1)监听机制介绍:
客户端注册监听它关心的目录节点,当目录节点发生变化(数据改变、节点删除、子目录节 点增加删除)时,zookeeper会通知客户端。

监听机制保证zookeeper保存的任何的数据的任何改变都能快速的相应到监听了该节点的应用程序。监听器的工作机制,其实是在客户端会专门创建一个监听线程,在本机的一个端口上等待zk集群发送过来的事件。

五、二维数组:其实就是一个元素为一维数组的数组;

数据类型[][] 变量名=new 数据类型[m][n];
m表示这个二维数组有多少个数组
n表示每一个一维数组的元素个数

package cn.manman.com;
/*
 * 创建一个二维数组
 * 并且遍历二维数组
 */
public class erweishuzu {
    public static void main(String[] args) {
        int[][] arr = {{1,2,3},{4,5,6},{7,8,9}};
        for(int x=0;x<arr.length;x++){
            for(int y=0;y<arr[x].length;y++){
                System.out.print(arr[x][y]);
            }
            System.out.println();
        }
    }
}

六、dubbo的协议:dubbo协议是dubbo默认的协议,

参考链接:https://www.jianshu.com/p/af285ed827ce
dubbo的协议的特点如下:
连接个数:单连接

连接方式:长连接

传输协议:TCP

传输方式:NIO异步传输

序列化:Hessian二进制序列化

适用范围:传入传出参数数据包较小(建议小于100K),消费者比提供者个数多,单一消费者无法压满提供者,尽量不要用dubbo协议传输大文件或超大字符串。

适用场景:常规远程服务方法调用

Dubbo 协议采用经典定长包头+变长包体的协议设计,包头记录了数据的序列化方式,请求状态,数据长度等信息,包体是请求/响应对象序列化后的二进制数据。

1、dubbo是什么? 参考链接:https://blog.csdn.net/a347911/article/details/88324056

dubbo是一个分布式服务框架,提供了性能和透明化的RPC远程服务调用案,以及SOA服务治理方案。说白了其实dubbo就是一个远程调用的分布式框架。

2.什么情况下适用dubbo协议,什么时候适用rmi协议?

Dubbo支持dubbo、rmi、hessian、http、webservice、thrift、redis等多种协议,但是dubbo协议是官网推荐使用的,dubbo 缺省协议是dubbo协议,采用单一长连接和 NIO 异步通讯,适合于小数据量大并发的服务调用,以及服务消费者机器数远大于服务提供者机器数的情况。反之,Dubbo 缺省协议不适合传送大数据量的服务

七、jvm优化及解决方法和数据库查询优化及索引优化

参考:https://blog.csdn.net/weixin_43495390/article/details/86533482

八、@RestController和@Controller的区别?

@RestController注解相当于@ResponseBody + @Controller合在一起的作用
1.使用@Controller 注解,
在对应的方法上,视图解析器可以解析return 的jsp,html页面并且跳转到相应页面,若返回json等内容到页面,则需要加@ResponseBody注解 2.@RestController注解
相当于@Controller+@ResponseBody两个注解的结合,返回json数据不需要在方法前面加@ResponseBody注解了,但使用@RestController这个注解,就不能返回jsp,html页面,视图解析器无法解析jsp,html页面。

LinkedList类是双向列表,列表中的每个节点都包含了对前一个和后一个元素的引用.

8.hashMap是数组+链表+红黑树(JDK1.8增加了红黑树部分)

Node[] table的初始化长度length(默认值是16),Load factor为负载因子(默认值是0.75),threshold是HashMap所能容纳的最大数据量的Node(键值对)个数。threshold = length * Load factor。也就是说,在数组定义好长度之后,负载因子越大,所能容纳的键值对个数越多。

结合负载因子的定义公式可知,threshold就是在此Load factor和length(数组长度)对应下允许的最大元素数目,超过这个数目就重新resize(扩容),扩容后的HashMap容量是之前容量的两倍。默认的负载因子0.75是对空间和时间效率的一个平衡选择,建议大家不要修改。

java反射获取类的实例:
1.调用getClass 2.运用.class 语法 3.Class.forName()

九、.springboot和vue怎么打包部署?放在哪个目录下

答:lib 目录 和resource目录 一级jar包放在同一目录下,启动jar包会去同级目录下找静态文件。

十 .lombok的插件使用log4j的jar包 log4j的底层原理:

答:在springboot中可以配置日志的级别及日志文件的路径等,如:logging.level: logging:file

十一 .springboot加载yaml的顺序

十二 .springboot的注解的方式

参考链接:https://www.jianshu.com/p/b2ade1737271
springbootConfig注解 @SpringBootApplication包含的三个注解及其含义

第一个:@SpringBootConfiguration(在这个类的源码中又有一个Configuration的注解)
@Configuration这个注解的作用就是声明当前类是一个配置类,然后Spring会自动扫描到添加了@Configuration的类,读取其中的配置信息,而@SpringBootConfiguration是来声明当前类是SpringBoot应用的配置类,项目中只能有一个。所以一般我们无需自己添加。

第二个:@EnableAutoConfiguration

开启自动配置,告诉SpringBoot基于所添加的依赖,去“猜测”你想要如何配置Spring。比如我们引入了spring-boot-starter-web,而这个启动器中帮我们添加了tomcat、SpringMVC的依赖,此时自动配置就知道你是要开发一个web应用,所以就帮你完成了web及SpringMVC的默认配置了!我们使用SpringBoot构建一个项目,只需要引入所需框架的依赖,配置就可以交给SpringBoot处理了。

第三个:@ComponentScan  配置组件扫描的指令

提供了类似与<context:component-scan>标签的作用

通过basePackageClasses或者basePackages属性来指定要扫描的包。

如果没有指定这些属性,那么将从声明这个注解的类所在的包开始,扫描包及子包

而我们的@SpringBootApplication注解声明的类就是main函数所在的启动类,

因此扫描的包是该类所在包及其子包。因此,一般启动类会放在一个比较前的包目录中。

十三、 spring启动的原理

参考链接:https://jingyan.baidu.com/article/b7001fe154c2b54f7382dd2c.html
1、新建module,在主程序类加入断点,启动springboot

2、首先进入SpringAplication类run方法

3、run方法新建SpringApplication对象

4、SpringApplication对象的run方法,首先创建并启动计时监控类

5、接着通过configureHeadlessProperty设置java.awt.headless的值

6、接着调用getRunListeners创建所有spring监听器

7、接着DefaultApplicationArguments初始化应用应用参数

8、接着prepareEnvironment根据运行监听器和参数准备spring环境

9、接着调用createApplicationContext方法创建应用上下文

10、通过prepareContext准备应用上下文

11、refreshContext方法刷新上下文

12、调用stop方法停止计时监控器类

13、调用started发布应用上下文启动完成事件

14、callRunners方法执行所有runner运行器

15、调用running发布应用上下文就绪事件

16、最后返回应用上下文

十四. 跨域的实现

参考链接:https://www.cnblogs.com/toutou/p/9843588.html
https://jingyan.baidu.com/article/c14654136fd0f24afdfc4c04.html
1.跨域的方式:直接在Controller类上加注解@CrossOrigin
2.自己实现WebMvcConfigurerAdapter 需要覆写addCorsMappings方法设置请求方式及请求路径等。
6. shiro框架怎么实现登录的一个认证 以及权限的认证
7. mybatis的自定义 类似于《select》标签的实现
8.redis集群部署
9.springboot默认加载appcationyaml文件,在改文件中配置

spring:
    profiles:
        active: dev

来控制读取application-dev.yml还是application-prod.yml文件的配置。

十五、.cglib的动态代理的ams框架

十六.spring security和shiro的异同

参考连接:https://blog.51cto.com/14150615/2356958?source=dra

相同点:1、认证功能2、授权功能3、加密功能4、会话管理5、缓存支持 6、rememberMe功能

十七、线程池

参考链接:https://www.cnblogs.com/jiawen010/p/11855768.html

newFixedThreadPool()固定大小的线程池 内部LinkedBlockingQueue

ThreadPoolExecutor

序号 名称 类型 含义
1 corePoolSize int 核心线程池大小
2 maximumPoolSize int 最大线程池大小
3 keepAliveTime long 线程最大空闲时间
4 unit TimeUnit 时间单位
5 workQueue BlockingQueue 线程等待队列
6 threadFactory ThreadFactory 线程创建工厂
7 handler RejectedExecutionHandler 拒绝策略

十八、.悲观锁 和乐观锁

参考链接:https://blog.csdn.net/qq_34337272/article/details/81072874
悲观锁:每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁(共享资源每次只给一个线程使用,其它线程阻塞,用完后再把资源转让给其它线程)。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。Java中synchronized和ReentrantLock等独占锁就是悲观锁思想的实现。
乐观锁:总是假设最好的情况,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号机制和CAS算法实现。乐观锁适用于多读的应用类型,这样可以提高吞吐量,像数据库提供的类似于write_condition机制,其实都是提供的乐观锁。在Java中java.util.concurrent.atomic包下面的原子变量类就是使用了乐观锁的一种实现方式CAS实现的。
两种锁的使用场景:从上面对两种锁的介绍,我们知道两种锁各有优缺点,不可认为一种好于另一种,像乐观锁适用于写比较少的情况下(多读场景),即冲突真的很少发生的时候,这样可以省去了锁的开销,加大了系统的整个吞吐量。但如果是多写的情况,一般会经常产生冲突,这就会导致上层应用会不断的进行retry,这样反倒是降低了性能,所以一般多写的场景下用悲观锁就比较合适。

十九 .公平锁和非公平锁

二十.spring事务

注解@Transactional value为7个传播机制 rollbackFor=’’
1.1. 编程式事务管理 使用TransactionTemplate或者直接使用PlatformTransactionManager Spring推荐使用TransactionTemplate。
2.声明式事务管理 声明式事务管理建立在AOP之上,其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,执行完目标方法之后根据执行的情况提交或者回滚。

事务的7个传播机制:PROPAGATION_REQUIRED(默认的传播机制,如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务) PROPAGATION_REQUES_NEW(该事务传播机制是每次都会新开启一个事务,把外层事务挂起)
4个隔离级别:脏读(Dirty read)、幻读等

二十一、.zookeeper和dubbo的使用

二十二. 使用mybatis的分页和sql本身自带的分页的区别?

参考链接:https://blog.csdn.net/mst1010/article/details/78591063
1.limit关键字
2.hibernate分页
3.截取List查询结果分页(简单粗暴)
4.mybatis框架pageHelper插件分页 pom文件引入依赖com.github.pagehelper 在yaml文件中增加分页配置,
5.5.springData分页

PageHelper和limit的区别?
PageHelper的优点是,分页和Mapper.xml完全解耦。实现方式是以插件的形式,对Mybatis执行的流程进行了强化,添加了总数count和limit查询。属于物理分页

二十三. 存储过程

	声明存储过程: CREATE PROCEDURE demo_in_parameter(IN p_in int)   
	存储过程开始和结束符号:  BEGIN .... END    
	变量赋值: SET @p_in=1  
	变量定义:DECLARE l_int int unsigned default 4000000; 

二十四.索引的类型

普通索引:仅加速查询

唯一索引:加速查询 + 列值唯一(可以有null)

主键索引:加速查询 + 列值唯一(不可以有null)+ 表中只有一个

组合索引:多列值组成一个索引,专门用于组合搜索,其效率大于索引合并

全文索引:对文本的内容进行分词,进行搜索

1.--创建普通索引CREATE INDEX index_name ON table_name(col_name);--创建唯一索引CREATE UNIQUE INDEX index_name ON table_name(col_name);--创建普通组合索引CREATE INDEX index_name ON table_name(col_name_1,col_name_2);--创建唯一组合索引CREATE UNIQUE INDEX index_name ON table_name(col_name_1,col_name_2);
2. 通过修改表结构创建索引 	ALTER TABLE table_name ADD INDEX index_name(col_name);

面试总结

1.@bean和@commentScan的异同点
2.spring事务的2种方式 声明式编程和编程式编程
3.spring事务的7种传播机制
4.spring怎么集成mybatis做开发
5.spring框架中的注入bean的方式 默认是注入的bean模式是单例模式,还有没有别的方式?
6.jvm的类加载机制
7.数据库怎么建立索引,建索引的条件是什么,什么情况下需要建立索引,索引的优化,什么情况下会产生索引失效
8.springMVC的工作流程
9.linux常用的命令
10.前端ajax交互的方式
11.java基础的抽象和接口的异同点
12.jerkins怎么使用?
13.怎么做自测?
14.分布式的开发及部署,dubbo和zookeerper怎么工作的
15.dubbo的实现原理
16.线程的生命周期

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值