前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Java面试:2021.05.12

Java面试:2021.05.12

原创
作者头像
夕梦
修改于 2021-05-17 07:31:43
修改于 2021-05-17 07:31:43
50900
代码可运行
举报
文章被收录于专栏:每日面试每日面试
运行总次数:0
代码可运行

1、redis中RDB和AOF的使用情况分别是什么?

如果是保存不重要的数据可以使用RDB方式(比如缓存数据),如果是保存很重要的数据就要使用AOF,但是两种方式也可以同时使用。

RDB触发机制:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
第一种:
save(同步)
1 客户端输入save命令----》redis服务端----》同步创建RDB二进制文件
2 会造成redis的阻塞(数据量非常大的时候)
3 文件策略:如果老的RDB存在,会替换老的
4 复杂度 o(n)

第二种:
bgsave(异步,Backgroud saving started)
1 客户端输入save命令----》redis服务端----》异步创建RDB二进制文件(fork函数生成一个子进程(fork会阻塞reids),执行createRDB,执行成功,返回给reids消息)
2 此时访问redis,会正常响应客户端
3 文件策略:跟save相同,如果老的RDB存在,会替换老的
4 复杂度 o(n)

第三种:(常用方式)******)
自动(通过配置文件)
配置   seconds   changes
save   900        1
save   300        10
save   60         10000
如果60s中改变了1w条数据,自动生成rdb
如果300s中改变了10条数据,自动生成rdb
如果900s中改变了1条数据,自动生成rdb

以上三条符合任意一条,就自动生成rdb,内部使用bgsave。

RDB触发机制一般使用第三种方式,但是这种方式也会有缺点。如果修改的条数没有在设置范围内那么就不会触发,就会引发很多数据没有持久化的情况。所以我们一般采用下面方式:AOF。

AOF

问题:耗时,耗性能。不可控,可能会丢失数据。

实现策略:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
日志不是直接写到硬盘上,而是先放在缓冲区,缓冲区根据一些策略,写到硬盘上
#第一种:
always:redis--》写命令刷新的缓冲区---》每条命令fsync到硬盘---AOF文件
#第二种:
everysec(默认值):redis——》写命令刷新的缓冲区---》每秒把缓冲区fsync到硬盘--AOF文件
#第三种:
no:redis——》写命令刷新的缓冲区---》操作系统决定,缓冲区fsync到硬盘--AOF文件

RDB和AOF的选择

rdb最佳策略

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
rdb关掉,主从操作时;
集中管理:按天,按小时备份数据;

主从配置,从节点打开。

aof最佳策略

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
开:缓存和存储,大部分情况都打开,
aof重写集中管理
everysec:通过每秒刷新的策略

最佳策略

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
小分片:每个redis的最大内存为4g;
缓存或存储:根据特性,使用不通策略;
时时监控硬盘,内存,负载网络等;
有足够内存。

2、斐波那契数列的实现。

实现一:基于递归形式实现

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public static int getFib(int n){
if(n < 0){
return -1;
        }else if(n == 0){
return 0;
        }else if(n == 1 || n ==2){
return 1;
        }else{
return getFib(n - 1) + getFib(n - 2);
        }
    }

递归是最简单的实现方式,但递归有很多的问题,在n的值非常大时,会占用很多的内存空间,既然该数列定义F(n)=F(n-1)+F(n-2)(n≥2,n∈N*),那么我们可以从头到尾进行计算,先计算前面的值,然后逐步算出第n个值。

方式二:基于变量形式实现

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public static int getFib2(int n){
if(n < 0){
return -1;
        }else if(n == 0){
return 0;
        }else if (n == 1 || n == 2){
return 1;
        }else{
int c = 0, a = 1, b = 1;
for(int i = 3; i <= n; i++){
                c = a + b;
                a = b;
                b = c;
            }
return c;
        }
    }

从上面的实现中我们定义了3个变量a、b、c其中c=a+b,然后逐步进行计算从而得到下标为n的值。 既然我们可以定义变量进行存储,那么同样我们还可以定义一个数组,该数组的每一个元素即一个斐波那契数列的值,这样我们不仅能得到第n个值,还能获取整个斐波那契数列。

方式三:基于数组的实现

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public static int getFib3(int n){
if(n < 0){
return -1;
        }else if(n == 0){
return 0;
        }else if (n == 1 || n == 2){
return 1;
        }else{
int[] fibAry = new int[n + 1];
            fibAry[0] = 0;
            fibAry[1] = fibAry[2] = 1;
for(int i = 3; i <= n; i++){
                fibAry[i] = fibAry[i - 1] + fibAry[i - 2];
            }
return fibAry[n];
        }
    }

3、数据库插入大批量数据的优化方案。

3.1、数据有序插入;

由于数据库插入时,需要维护索引数据无序的记录会增大维护索引的成本。我们可以参照InnoDB使用的B+tree索引,如果每次插入记录都在索引的最后面,索引的定位效率很高,并且对索引调整较小;如果插入的记录在索引中间,需要B+tree进行分裂合并等处理,会消耗比较多计算资源,并且插入记录的索引定位效率会下降,数据量较大时会有频繁的磁盘操作。

3.2、在事务中进行插入处理;

使用事务可以提高数据的插入效率,这是因为进行一个INSERT操作时,MySQL内部会建立一个事务,在事务内才进行真正插入处理操作。通过使用事务可以减少创建事务的消耗,所有插入都在执行后才进行提交操作

结论:

合并数据+事务的方法在较小数据量时,性能提高是很明显的,数据量较大时(1千万以上),性能会急剧下降,这是由于此时数据量超过了innodb_buffer的容量,每次定位索引涉及较多的磁盘读写操作,性能下降较快。而使用合并数据+事务+有序数据的方式在数据量达到千万级以上表现依旧是良好,在数据量较大时,有序数据索引定位较为方便,不需要频繁对磁盘进行读写操作,所以可以维持较高的性能

注意事项:

  1. SQL语句是有长度限制,在进行数据合并在同一SQL中务必不能超过SQL长度限制,通过max_allowed_packet配置可以修改,默认是1M,测试时修改为8M。
  2. 事务需要控制大小,事务太大可能会影响执行的效率。MySQL有innodb_log_buffer_size配置项,超过这个值会把innodb的数据刷到磁盘中,这时,效率会有所下降。所以比较好的做法是,在数据达到这个这个值前进行事务提交。

3.3、存储过程;

3.4、加缓存,使用redis等对数据进行预加载;

3.5、临时表;

3.6、队列;

3.7、分库分表(更大的数据量)等。

今日份其他面试问题:

  1. 哈希原理;
  2. 哈希结构和b+tree谁的速度更快;
  3. 如何分库分表;
  4. 分布式事务解决方案;
  5. kafka如何解决不能传送大于10k的消息;
  6. nacos和eruika如何选型;
  7. 你的项目上线了吗?日火多少,统计用户是多少?
  8. 说说多表子查询;
  9. 刷盘策略是什么;
  10. dc分布式中心;
  11. 关于项目的问题;
  12. 项目从开发到结束是怎么个流程;
  13. 项目团队有多人人;
  14. 项目怎么部署发布的;
  15. Redis的应用场景,请列举一个场景,并说明怎么实现的;
  16. SQL优化;
  17. 项目为什么选择了spring cloud ,不用Dubbo;
  18. 介绍一下使用了Spring cloud哪些组件;
  19. MongoDB的应用场景,为什么选择MongoDB,不选择mysql;
  20. 介绍一下你了解的MQ;
  21. Spring Boot常用注解及作用;
  22. Vue怎么使用的,常用标签;
  23. 如果让你设计消息队列,你怎么设计;
  24. 开发代码的规范,你谈一谈;
  25. Mybatis和mybatis-plus的区别,怎么选型;
  26. 说说bean的生命周期;
  27. 缓存雪崩如何解决? 缓存穿透如何解决?
  28. 如何使用Redis完成订单列表场景?
  29. MySQL里有2000w数据,Redis中只存20w的数据,如何保证Redis中的都是热点数据?
  30. Redis相比memcached有哪些优势?
  31. 假如Redis里面有1亿个key,其中有10w个key是以某个固定的已知的前缀开头的,如何将它们全部找出来?
  32. 我说的登录验证.加密方式是什么?
  33. 有没有参与部署?
  34. 为什么用mq不是kafuka?
  35. 说一下你对高并发线程的理解?
  36. 说一下mysql调优?
  37. 项目中第三方支付接口是什么?
  38. 讲一下项目中用到的搜索引擎?
  39. redis的增量更新;
  40. 懒汉式在多线程中如何保证唯一又不影响效率的;
  41. springboot的启动类,为什么添加上后就可以启动了;
  42. MQ生产者生产消息如何保证消息被消费了;
  43. 冒泡排序后开始索引值与输出结果对应;
  44. 词典,set存储,如何获取词典中的词汇;
  45. 你以后的职业规划是什么。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验